Не подключается PostgreSQL по TCP/IP: причины и решение
При попытке подключиться к PostgreSQL на удалённом сервере Ubuntu по протоколу TCP/IP возникает ошибка, хотя через SSH-туннель соединение работает отлично. Это частая проблема, связанная с настройками сетевого экрана, правилами iptables или конфигурацией самой базы данных. В этой статье разберём все возможные причины и пошагово устраним неполадки.
Основные причины ошибки подключения к PostgreSQL по TCP/IP
Если HeidiSQL или Python не могут соединиться с PostgreSQL по прямому TCP-соединению, но SSH-туннель работает - проблема не в сети, а в настройках сервера. Рассмотрим три главных блока.
1. Проверка файла pg_hba.conf
Файл pg_hba.conf управляет правилами аутентификации. Для удалённого доступа по TCP/IP необходимо разрешить подключения с внешних IP-адресов. В вашем примере строка host all all 0.0.0.0/0 md5 уже присутствует - это правильно. Однако убедитесь, что нет более строгих правил выше, которые блокируют доступ. Порядок строк важен: PostgreSQL использует первое совпадение.
Рекомендуется разместить разрешающее правило для всех сетей до локальных ограничений:
host all all 0.0.0.0/0 md5
host all all ::/0 md5После изменения файла перезагрузите PostgreSQL командой sudo systemctl reload postgresql.
2. Настройка ufw (Uncomplicated Firewall)
Вы уже открыли порт 5432 в ufw, но обратите внимание: статус показывает 5432/tcp ALLOW Anywhere. Этого должно быть достаточно. Однако если на сервере есть другие сетевые интерфейсы (например, Docker), трафик может идти через них. Проверьте, что правило применяется к основному интерфейсу. Дополнительно убедитесь, что ufw не блокирует входящие соединения с вашего IP. В вашем списке есть строка Anywhere ALLOW {ip рабочего компьютера} - это корректно.
3. Правила iptables
Команда sudo iptables -A INPUT -p tcp --dport 5432 -j ACCEPT добавляет правило, но оно может быть переопределено другими правилами или сброшено после перезагрузки. Для постоянного применения используйте iptables-persistent или ufw. Рекомендуем полностью отключить iptables для теста: sudo iptables -P INPUT ACCEPT и sudo iptables -F. Если после этого подключение заработает - значит проблема в iptables.
Пошаговое устранение неполадок
Шаг 1. Проверка слушающих адресов PostgreSQL
В файле postgresql.conf параметр listen_addresses = '*' указывает, что сервер слушает на всех интерфейсах. Убедитесь, что эта строка не закомментирована. Проверьте логи PostgreSQL - в них должно быть listening on IPv4 address "0.0.0.0", port 5432. Если там указан конкретный IP, замените на '*'.
Шаг 2. Тестирование подключения с сервера
На самом сервере выполните psql -h 127.0.0.1 -U postgres -d postgres. Если это работает, значит PostgreSQL настроен правильно для локальных TCP-соединений. Затем проверьте с внешнего IP: psql -h <внешний IP сервера> -U postgres -d postgres. Если не работает - проблема в сетевом экране или маршрутизации.
Шаг 3. Проверка telnet с сервера на себя
Выполните на сервере telnet 127.0.0.1 5432. Должен появиться пустой экран или ответ от PostgreSQL. Если соединение отклоняется - PostgreSQL не слушает на этом порту. Проверьте, что сервис активен: sudo systemctl status postgresql. В вашем логе статус active (exited) - это нормально для основного процесса, но убедитесь, что дочерние процессы работают.
Что делать, если ничего не помогло?
Если после всех проверок подключение по TCP/IP всё ещё не работает, возможно, проблема на уровне провайдера или виртуальной машины (VPS). Некоторые хостинг-провайдеры блокируют порт 5432 на внешнем фаерволе. В таком случае используйте SSH-туннель как надёжную альтернативу. Для этого в HeidiSQL настройте SSH-соединение, указав хост, порт 22 и логин. Через туннель PostgreSQL будет доступен локально на порту 5432.
Для Python используйте библиотеку sshtunnel:
from sshtunnel import SSHTunnelForwarder
import psycopg2
with SSHTunnelForwarder(
('your_server_ip', 22),
ssh_username='user',
ssh_password='pass',
remote_bind_address=('127.0.0.1', 5432)
) as tunnel:
conn = psycopg2.connect(
host='127.0.0.1',
port=tunnel.local_bind_port,
user='postgres',
password='pass',
database='mydb'
)Этот подход безопасен и не требует открытия портов в фаерволе.
Заключение
Ошибка подключения к PostgreSQL по TCP/IP при работающем SSH-туннеле чаще всего связана с настройками pg_hba.conf, ufw или iptables. Проверьте все три компонента, перезагрузите PostgreSQL и убедитесь, что сервер слушает на всех интерфейсах. Если проблема остаётся - используйте SSH-туннель как временное или постоянное решение. Надеемся, наша инструкция помогла вам восстановить удалённый доступ к базе данных.