Настройка удалённого подключения к PostgreSQL
Пошаговая настройка PostgreSQL для подключения с другого сервера: listen_addresses, порт 5432, firewall и проверка доступности.
По умолчанию PostgreSQL в Ubuntu обычно принимает подключения только локально. Чтобы приложение на другом сервере могло подключиться к базе данных, нужно разрешить прослушивание сетевого интерфейса, открыть доступ в firewall и проверить маршрут.
В этой инструкции рассматривается только сетевой уровень удалённого подключения:
- параметр
listen_addresses; - порт PostgreSQL;
- UFW;
- проверка доступности;
- диагностика сетевых ошибок.
Настройка правил pg_hba.conf и методов аутентификации будет рассмотрена в отдельной статье.
Проверено на: Ubuntu Server 24.04 LTS
Уровень сложности: средний
Время выполнения: около 15–20 минут
Требуемый доступ: пользователь с правамиsudo
Что будет настроено
После выполнения инструкции:
- будет определён адрес сервера PostgreSQL;
- PostgreSQL начнёт слушать нужный сетевой интерфейс;
- будет открыт порт
5432/tcpтолько для доверенного клиента; - будет проверен маршрут между серверами;
- будет выполнена проверка через
pg_isreadyиpsql; - будут разобраны ошибки
connection refusedиtimeout.
Исходная схема
В примерах используется:
PostgreSQL-сервер: 192.0.2.10
Сервер приложения: 198.51.100.20
Порт PostgreSQL: 5432
База данных: app_db
Роль: app_user
Используйте реальные адреса своей инфраструктуры.
Важное предупреждение
Не открывайте PostgreSQL для всего интернета.
Опасный вариант:
0.0.0.0/0
или правило firewall:
sudo ufw allow 5432/tcp
без ограничения источника.
Безопаснее разрешать доступ:
- одному IP;
- подсети приложения;
- VPN-подсети;
- приватной сети;
- отдельному bastion host.
Проверка текущего состояния
Проверьте кластеры:
pg_lsclusters
Проверьте готовность:
sudo -u postgres pg_isready
Проверьте текущий порт:
sudo -u postgres psql -Atc 'SHOW port;'
Проверка listen_addresses
sudo -u postgres psql -Atc 'SHOW listen_addresses;'
На локальной установке часто используется:
localhost
Это означает, что сервер не принимает подключения с других узлов.
Определение конфигурационного файла
sudo -u postgres psql -Atc 'SHOW config_file;'
Пример:
/etc/postgresql/VERSION/main/postgresql.conf
Определение сетевых интерфейсов
ip -br addr
Пример:
lo UNKNOWN 127.0.0.1/8
ens18 UP 192.0.2.10/24
Выберите адрес интерфейса, через который сервер приложения достигает PostgreSQL.
Проверка маршрута до клиента
С PostgreSQL-сервера:
ip route get 198.51.100.20
Проверьте:
- используемый интерфейс;
- исходный адрес;
- шлюз;
- наличие маршрута.
Проверка маршрута с клиента
На сервере приложения:
ip route get 192.0.2.10
Маршрут должен вести к PostgreSQL-серверу.
Создание резервной копии конфигурации
CONFIG_FILE="$(
sudo -u postgres psql -Atc 'SHOW config_file;'
)"
sudo cp "$CONFIG_FILE" "${CONFIG_FILE}.before-remote-access"
Проверьте:
sudo ls -l "${CONFIG_FILE}"*
Настройка одного IP-адреса
Откройте конфигурацию:
sudo nano "$CONFIG_FILE"
Найдите:
listen_addresses
Задайте:
listen_addresses = '127.0.0.1,192.0.2.10'
Так PostgreSQL будет слушать:
- localhost;
- внутренний адрес сервера.
Прослушивание всех интерфейсов
Можно использовать:
listen_addresses = '*'
Это разрешает PostgreSQL слушать все доступные интерфейсы.
Такой вариант допустим только при строгом firewall и корректном pg_hba.conf.
Для небольших инфраструктур предпочтительнее указывать конкретные адреса.
Прослушивание IPv6
Пример:
listen_addresses = '127.0.0.1,::1,2001:db8::10'
Проверьте, что IPv6 действительно используется и защищён firewall.
Проверка параметра port
В конфигурации:
port = 5432
Если стандартный порт подходит, менять его не требуется.
Изменение порта не является полноценной мерой безопасности.
Проверка значения в конфигурации
sudo grep -nE '^[[:space:]]*listen_addresses|^[[:space:]]*port' "$CONFIG_FILE"
Применение конфигурации
Изменение listen_addresses требует restart.
sudo systemctl restart postgresql
Проверьте:
systemctl status postgresql --no-pager
Проверьте кластер:
pg_lsclusters
Проверка журнала после restart
sudo tail -100 /var/log/postgresql/postgresql-*.log
Для systemd:
sudo journalctl -u postgresql -n 100 --no-pager
Проверка фактического значения
sudo -u postgres psql -Atc 'SHOW listen_addresses;'
Проверка прослушиваемого порта
sudo ss -lntp |
grep ':5432'
Ожидается:
127.0.0.1:5432
192.0.2.10:5432
или:
0.0.0.0:5432
при listen_addresses = '*'.
Проверка IPv6
sudo ss -lntp6 |
grep ':5432'
Проверка UFW
sudo ufw status verbose
Если UFW неактивен, проверьте внешний firewall, security group или сетевые ACL.
Разрешение одного IP
sudo ufw allow from 198.51.100.20 to any port 5432 proto tcp
Проверьте:
sudo ufw status numbered
Разрешение подсети
sudo ufw allow from 198.51.100.0/24 to any port 5432 proto tcp
Используйте подсеть только если все узлы в ней доверенные.
Разрешение на конкретный интерфейс
sudo ufw allow in on ens18 from 198.51.100.20 to any port 5432 proto tcp
Проверьте имя интерфейса:
ip -br link
Ограничение приватной сетью
Если приложение и PostgreSQL находятся в одной приватной сети, используйте внутренние адреса.
Пример:
PostgreSQL: 10.10.0.10
Приложение: 10.10.0.20
Правило:
sudo ufw allow from 10.10.0.20 to 10.10.0.10 port 5432 proto tcp
Проверка внешнего firewall
В облачной или виртуальной инфраструктуре дополнительно проверьте:
- security group;
- provider firewall;
- VLAN ACL;
- router ACL;
- NAT;
- Proxmox firewall;
- межсетевой экран гипервизора.
Локальное правило UFW может быть корректным, но трафик всё равно блокируется на другом уровне.
Проверка порта с клиента
На сервере приложения:
nc -zv 192.0.2.10 5432
Если nc отсутствует:
sudo apt update
sudo apt install -y netcat-openbsd
Успешный результат:
succeeded
Проверка через pg_isready
На клиентском сервере:
pg_isready -h 192.0.2.10 -p 5432
Пример успешного сетевого ответа:
192.0.2.10:5432 - accepting connections
pg_isready проверяет доступность сервера, но не подтверждает, что конкретная роль имеет доступ к базе.
Установка клиента PostgreSQL
На сервере приложения:
sudo apt update
sudo apt install -y postgresql-client
Проверьте:
psql --version
Попытка подключения
psql -h 192.0.2.10 -p 5432 -U app_user -d app_db
На этом этапе возможно сообщение:
no pg_hba.conf entry
Это означает, что сетевой доступ уже работает, но правило аутентификации ещё не настроено.
Настройка pg_hba.conf рассматривается в следующей статье.
Разница между сетевой и аутентификационной ошибкой
Connection refused
could not connect to server: Connection refused
Обычно означает:
- PostgreSQL не слушает внешний адрес;
- служба не запущена;
- неверный IP;
- неверный порт;
- соединение активно отклоняется.
Timeout
connection timed out
Обычно означает:
- firewall блокирует трафик;
- отсутствует маршрут;
- security group не разрешает порт;
- сервер недоступен;
- неверный NAT.
No pg_hba.conf entry
no pg_hba.conf entry for host
Означает:
- TCP-соединение дошло до PostgreSQL;
- сервер работает;
- сетевой доступ разрешён;
- отсутствует подходящее правило аутентификации.
Password authentication failed
Означает:
- соединение дошло до сервера;
- правило
pg_hba.confнайдено; - пароль или роль неверны.
Проверка через tcpdump
На PostgreSQL-сервере:
sudo tcpdump -ni any host 198.51.100.20 and port 5432
Затем повторите подключение с клиента.
Если пакеты не появляются, проблема находится до PostgreSQL-сервера.
Остановить:
Ctrl+C
Проверка SYN-пакетов
sudo tcpdump -nn -i any 'tcp port 5432 and tcp[tcpflags] & tcp-syn != 0'
Проверка журнала PostgreSQL
sudo tail -f /var/log/postgresql/postgresql-*.log
Повторите подключение с клиента.
Если сервер получил запрос, в журнале может появиться запись об ошибке аутентификации.
Проверка bind через lsof
sudo lsof -nP -iTCP:5432 -sTCP:LISTEN
Проверка firewall через nftables
UFW использует backend firewall системы.
Проверьте:
sudo nft list ruleset |
grep -n 5432
Не изменяйте правила nftables вручную, если сервер управляется через UFW, без чёткого понимания порядка правил.
Проверка iptables
На системах с совместимым frontend:
sudo iptables -S |
grep 5432
Проверка localhost после изменения
sudo -u postgres psql -h 127.0.0.1 -d postgres -c 'SELECT 1;'
Локальные приложения не должны потерять доступ после изменения listen_addresses.
Проверка Unix socket
sudo -u postgres psql -d postgres -c 'SELECT 1;'
Unix socket работает независимо от внешнего TCP bind.
Подключение по DNS-имени
Вместо IP можно использовать:
psql -h db.example.internal -U app_user -d app_db
Проверьте DNS:
getent hosts db.example.internal
Проверка DNS с клиента
dig +short db.example.internal
DNS должен возвращать нужный адрес PostgreSQL-сервера.
Использование внутреннего DNS
Для приватной инфраструктуры лучше использовать внутреннее имя:
db01.example.internal
Это упрощает перенос сервиса без изменения конфигурации приложения.
Подключение через VPN
Безопасный вариант:
Приложение → VPN → PostgreSQL
PostgreSQL слушает VPN-адрес:
listen_addresses = '127.0.0.1,10.20.0.10'
Firewall разрешает только VPN-подсеть.
Подключение через SSH-туннель
Для временного административного доступа можно использовать:
ssh -L 15432:127.0.0.1:5432 ADMIN_USER@SERVER_IP
Затем локально:
psql -h 127.0.0.1 -p 15432 -U app_user -d app_db
В этом случае PostgreSQL может продолжать слушать только localhost.
SSH-туннель удобен для администрирования, но не всегда подходит как постоянное соединение приложения.
Проверка established-соединений
После подключения:
sudo ss -ntp |
grep ':5432'
В PostgreSQL:
sudo -u postgres psql -c "SELECT
usename,
datname,
client_addr,
client_port,
application_name
FROM pg_stat_activity
WHERE client_addr IS NOT NULL;"
application_name клиента
Подключение:
PGAPPNAME=app-server psql -h 192.0.2.10 -U app_user -d app_db
Проверка на сервере:
SELECT
usename,
application_name,
client_addr
FROM pg_stat_activity
WHERE application_name = 'app-server';
Несколько сетевых интерфейсов
Если сервер имеет:
public IP
private IP
VPN IP
не используйте * без необходимости.
Пример:
listen_addresses = '127.0.0.1,10.10.0.10,10.20.0.10'
Так PostgreSQL не будет слушать публичный интерфейс.
Проверка публичного экспонирования
С внешнего недоверенного узла:
nc -zv PUBLIC_SERVER_IP 5432
Соединение должно быть заблокировано.
Не используйте port change как основную защиту
Перенос PostgreSQL на:
15432
может уменьшить шум автоматического сканирования, но не заменяет:
- firewall;
pg_hba.conf;- сильные пароли;
- TLS;
- приватную сеть;
- мониторинг.
Проверка после перезагрузки сервера
После плановой перезагрузки:
pg_lsclusters
sudo ss -lntp |
grep ':5432'
С клиента:
pg_isready -h 192.0.2.10 -p 5432
Откат listen_addresses
Восстановите резервную копию:
sudo cp "${CONFIG_FILE}.before-remote-access" "$CONFIG_FILE"
Перезапустите:
sudo systemctl restart postgresql
Проверьте:
sudo -u postgres psql -Atc 'SHOW listen_addresses;'
Удаление правила UFW
Покажите правила:
sudo ufw status numbered
Удалите по номеру:
sudo ufw delete RULE_NUMBER
Повторно проверьте:
sudo ufw status numbered
Типичные проблемы
PostgreSQL продолжает слушать только localhost
Проверьте фактический файл:
sudo -u postgres psql -Atc 'SHOW config_file;'
Проверьте значение:
sudo -u postgres psql -Atc 'SHOW listen_addresses;'
Убедитесь, что выполнен restart, а не только reload.
Порт доступен локально, но недоступен удалённо
Проверьте:
- UFW;
- provider firewall;
- маршрут;
- VLAN ACL;
- security group;
- адрес bind;
- NAT.
nc показывает timeout
Проверьте пакеты через tcpdump.
Если SYN не приходит, проблема вне PostgreSQL.
nc показывает connection refused
Проверьте:
sudo ss -lntp |
grep ':5432'
Проверьте адрес, на котором слушает PostgreSQL.
pg_isready отвечает, но psql не подключается
Сеть работает.
Проверьте:
pg_hba.conf;- роль;
- пароль;
- базу;
- SSL mode.
Подключение работает по IP, но не по имени
Проверьте DNS:
getent hosts db.example.internal
Проверьте /etc/hosts, resolver и DNS TTL.
После restart PostgreSQL не запускается
Проверьте:
sudo journalctl -u postgresql -n 100 --no-pager
Проверьте синтаксис строки listen_addresses.
Восстановите резервную копию.
Безопасный порядок настройки
- Определить доверенный IP клиента.
- Проверить маршрут между серверами.
- Создать резервную копию
postgresql.conf. - Указать конкретный адрес в
listen_addresses. - Выполнить restart.
- Проверить
ss. - Открыть UFW только для клиента.
- Проверить
nc. - Проверить
pg_isready. - Выполнить тест
psql. - Проверить журнал PostgreSQL.
- Перейти к настройке
pg_hba.conf.
Быстрый набор команд
Проверить конфигурацию:
sudo -u postgres psql -Atc 'SHOW config_file;'
Проверить адреса:
sudo -u postgres psql -Atc 'SHOW listen_addresses;'
После изменения:
sudo systemctl restart postgresql
Проверить bind:
sudo ss -lntp |
grep ':5432'
Разрешить клиент:
sudo ufw allow from 198.51.100.20 to any port 5432 proto tcp
Проверить с клиента:
pg_isready -h 192.0.2.10 -p 5432
Итог
После выполнения инструкции:
- определён сетевой адрес PostgreSQL-сервера;
- настроен
listen_addresses; - проверен порт
5432; - создано ограниченное правило firewall;
- проверены маршрут и доступность;
- выполнена диагностика через
nc,pg_isreadyиtcpdump; - разобраны сетевые и аутентификационные ошибки.
Следующим этапом нужно создать точные правила доступа в pg_hba.conf и выбрать безопасный метод аутентификации.