SSH-туннели, которыми я пользуюсь каждый день
Половина задач, для которых обычно поднимают отдельный сервис, решается одной строкой в терминале. Ниже три варианта проброса, которые реально нужны в работе, и пара грабель, на которые я наступал.
Локальный проброс: -L
Классика — достучаться до сервиса, который слушает только localhost на удалённой машине.
ssh -N -L 5433:127.0.0.1:5432 user@db.example.com
Теперь psql -h 127.0.0.1 -p 5433 на локальной машине попадает
в базу на сервере. Флаг -N говорит, что шелл не нужен — только
туннель.
Обратный проброс: -R
Нужен, когда сервис за NAT и до него надо дотянуться снаружи. Держу так доступ к домашнему хранилищу:
ssh -N -R 8081:127.0.0.1:80 vps
На vps появляется порт 8081, ведущий на домашний веб-интерфейс.
Важно: по умолчанию GatewayPorts выключен, и порт слушает
только 127.0.0.1 на удалённой стороне. Если нужен внешний
доступ — -R 0.0.0.0:8081:127.0.0.1:80 и соответствующая
настройка sshd.
SOCKS-прокси: -D
Быстрый способ увести трафик браузера через сервер, без всяких VPN:
ssh -N -D 1080 user@vps
Дальше в браузере указываем SOCKS5 127.0.0.1:1080. DNS при
этом по умолчанию резолвится локально — если это нежелательно, нужен
-D вместе с настройкой Proxy DNS when using SOCKS v5
в браузере.
Чтобы туннель не отваливался
Мобильный интернет рвёт соединение при каждом переключении между
вышками, и голый ssh -R умирает молча. Выручает autossh:
autossh -M 0 -N -o "ServerAliveInterval 30" \ -o "ServerAliveCountMax 3" -R 8081:127.0.0.1:80 vps
-M 0 отключает отдельный мониторинговый порт (он давно
не нужен), а живость соединения проверяется штатными
ServerAlive-опциями.
Грабли
-
Туннель держится, пока жив процесс. Закрыли терминал — туннель умер.
Для постоянной работы нужен юнит systemd или
autossh. -
Порт, занятый локально, даёт ошибку
bind: Address already in use— проверяйтеss -ltnp, а не гадайте. -
Если в
sshd_configстоитAllowTcpForwarding no, не поможет ничего, кроме правки конфига на сервере.