17.10. Защита соединений TCP/IP с применением туннелей SSH

Для защиты сетевых соединений клиентов с сервером PostgreSQL можно применить SSH. При правильном подходе это позволяет обеспечить должный уровень защиты сетевого трафика, даже для клиентов, не поддерживающих SSL.

Прежде всего, убедитесь, что на компьютере с сервером PostgreSQL также работает сервер SSH и вы можете подключиться к нему через ssh каким-нибудь пользователем. Затем вы можете установить защищённый тоннель с клиентской машины следующим образом:

ssh -L 63333:localhost:5432 joe@foo.com

Первое число в аргументе -L, 63333 — это номер порта с вашей стороны туннеля; это может быть номер любого свободного порта. (IANA резервирует порты с 49152 по 65535 для частного использования.) Второе число, 5432 — порт с удалённой стороны туннеля, порт вашего сервера. Имя или IP-адрес между этими номерами портов идентифицирует целевой компьютер (где работает сервер баз данных, к которому вы будете подключаться), с точки зрения компьютера, с которого выполняется подключение (в данном примере, foo.com). Чтобы подключиться к этому серверу через созданный тоннель, вы можете подключиться к порту 63333 на локальном компьютере:

psql -h localhost -p 63333 postgres

Для сервера баз данных это будет выглядеть так, как будто вы действительно пользователь joe компьютера foo.com, подключающийся к localhost в этом контексте, и он будет применять ту процедуру проверки подлинности, которая установлена для подключений данного пользователя с этого компьютера. Заметьте, что сервер не будет считать такое соединение защищённым SSL, так как на самом деле трафик между сервером SSH и сервером PostgreSQL не защищён. Это не должно нести какие-то дополнительные риски, так как эти серверы работают на одном компьютере.

Чтобы настроенный таким образом туннель работал, вы должны иметь возможность подключаться к компьютеру через ssh под именем joe@foo.com, так же, как это происходит при установлении терминального подключения с помощью ssh.

Вы также можете настроить перенаправление портов примерно так:

ssh -L 63333:foo.com:5432 joe@foo.com

Но в этом случае для сервера баз данных подключение будет приходить с его интерфейса foo.com, а этот интерфейс по умолчанию не прослушивается (вследствие указания listen_addresses = 'localhost'). Обычно требуется другое поведение.

Если вам нужно "перейти" к серверу баз данных через некоторый шлюз, это можно организовать примерно так:

ssh -L 63333:db.foo.com:5432 joe@shell.foo.com

Заметьте, что в этом случае трафик между shell.foo.com и db.foo.com не будет защищён туннелем SSH. SSH предлагает довольно много вариантов конфигурации, что позволяет организовывать защиту сети разными способами. За подробностями обратитесь к документации SSH.

Подсказка: Существуют и другие приложения, которые могут создавать безопасные туннели, применяя по сути тот же подход, что был описан выше.