SSH-туннелированию и переадресация портов
Чтобы сделать это быстрее, я жалею, что не знал о переадресации портов и туннелировании раньше. В этом посте в блоге я попытаюсь лучше понять это сам и поделюсь с вами некоторым опытом и советами.
Темы: примеры использования, конфигурация, прыжковые узлы SSH, локальная/удаленная/динамическая переадресация портов и ограничения
Примеры использования #
Туннелирование SSH и переадресация портов могут использоваться для переадресации трафика TCP по защищенному SSH-соединению от клиента SSH к серверу SSH или наоборот. Можно использовать TCP-порты или сокеты UNIX, но в этом посте я сосредоточусь только на TCP-портах.
Я не буду вдаваться в подробности, но следующий пост должен показать достаточно примеров и вариантов, которые найдут применение в вашей повседневной работе.
- Безопасность:
- шифровать незащищенные соединения (FTP, другие устаревшие протоколы)
- доступ к веб-админкам через защищенный SSH-туннель (Pub Key Authentication)
- Потенциально меньше открытых портов (только 22, вместо дополнительных 80/443)
- Устранение неполадок:
- Обход межсетевых экранов/фильтров содержимого
- выбор различных маршрутов
- Связь:
- сервер reach за NAT
- Используйте Jumphost для доступа к внутренним серверам через Интернет
- Предоставление доступа к локальным портам через Интернет
Существует еще много других вариантов использования, но этот обзор должен дать вам представление о возможностях.
Переадресация портов
Прежде чем мы начнем: варианты из следующих примеров могут быть объединены и настроены в соответствии с вашими настройками. В качестве примечания: если значение не установлено, localhost будет использоваться по умолчаниюbind_address
Конфигурация / Подготовка #
- Локальные и удаленные пользователи должны иметь необходимые разрешения на локальные и удаленные машины соответственно для открытия портов. Порты от 0 до 1024 требуют привилегий root, если они не настроены иначе, а остальные порты могут быть настроены обычными пользователями.
- Настройте клиенты и сетевые брандмауэры соответствующим образом
- На сервере должна быть включена переадресация портов SSH:
AllowTcpForwarding yes
- Он включен по умолчанию, если я его правильно помню
- Если вы перенаправляете порты на интерфейсы, отличные от 127.0.01, то вам потребуется включить порты на сервере SSH:
GatewayPorts
GatewayPorts yes
Не забудьте перезапустить службу сервера ssh.
SSH-jumphost / SSH-туннель #
Прозрачное подключение к удаленному узлу через один или несколько узлов.
ssh -J user@REMOTE-MACHINE:22 -p 22 user@10.99.99.1
Примечание: Адресация портов может быть удалена, если используется порт 22 по умолчанию!
На REMOTE-MACHINE в качестве jumphost:
[user@REMOTE-MACHINE]$ ss | grep -i ssh
tcp ESTAB 0 0 167.135.173.108:ssh 192.160.140.207:45960
tcp ESTAB 0 0 10.99.99.2:49770 10.99.99.1:ssh
- Объяснение:
167.135.173.108
- публичный IP REMOTE-MACHINE92.160.120.207
- публичный IP LOCAL-MACHINE10.99.99.2
- внутренний IP REMOTE-MACHINE10.99.99.1
- внутренний IP REMOTE-WEBAPP
Использование нескольких узлов перехода
- Jumphosts должны быть разделены запятыми:
ssh -J user@REMOTE-MACHINE:22,user@ANOTHER-REMOTE-MACHINE:22 -p 22 user@10.99.99.1
Переадресация местных портов #
Пример 1
ssh -L 10.10.10.1:8001:localhost:8000 user@REMOTE-MACHINE
- Журналы доступа веб-сервера на REMOTE-MACHINE, который прослушивает только 127.0.0.1:
127.0.0.1 - - [30/Dec/2022 18:05:15] "GET / HTTP/1.1" 200
- запрос исходит от LOCAL-MACHINE
Пример 2
ssh -L 8001:10.99.99.1:8000 user@REMOTE-MACHINE
- Логи доступа веб-сервера к REMOTE-WEBAPP:
10.99.99.2 - - [30/Dec/2022 21:28:42] "GET / HTTP/1.1" 200
- запрос исходит с внутреннего IP LOCAL-MACHINE (10.99.99.2)
Удаленная переадресация портов #
Пример 1+2
ssh -R 8000:localhost:8001 user@REMOTE-MACHINE
ssh -R 8000:10.10.10.2:8001 user@REMOTE-MACHINE
Пример 3
ssh -R 10.99.99.2:8000:10.10.10.2:8001 user@REMOTE-MACHINE
Важно: должен быть включен на сервере SSH для прослушивания на другом интерфейсе, отличном от интерфейса обратной связи.GatewayPorts yes
Динамическая переадресация портов #
Для переадресации более одного порта SSH использует протокол SOCKS. Это прозрачный прокси-протокол, и SSH делает нас самой последней версией SOCKS5.
Порт по умолчанию для сервера SOCKS5 — 1080, как определено в RFC 1928.
Клиент должен быть правильно настроен для использования SOCKS прокси. Либо на уровне приложения, либо на уровне ОС.
Пример
ssh -D 10.10.10.1:5555 user@REMOTE-MACHINE
- Используйте на клиенте 'LOCAL' для проверки правильного соединения/пути:
curl
curl -L -x socks5://10.10.10.1:5555 brrl.net/ip
- Если все работает, вы должны вернуть публичный IP-адрес УДАЛЕННОЙ МАШИНЫ
Туннелирование SSH TUN/TAP
Не буду вдаваться в подробности, но вы можете создать двунаправленный TCP-туннель с помощью флага. Интерфейсы должны быть созданы заранее, а я их еще не тестировал.-w
-w local_tun[:remote_tun]
Как запустить SSH в фоновом режиме #
- Нативный способ запуска туннеля в фоновом режиме будет следующим:
-fN
-f
- запуск в фоновом режиме-N
- отсутствие оболочки
ssh -fN -L 8001:127.0.0.1:8000 user@REMOTE-MACHINE
Кроме этого: используйте экран или какие-то другие инструменты.
Остановите работу SSH в фоновом режиме
user@pleasejustwork:~$ ps -ef | grep ssh
[...]
user 19255 1 0 11:40 ? 00:00:00 ssh -fN -L 8001:127.0.0.1:8000 user@REMOTE-MACHINE
[...]
- Завершите процесс с помощью PID:
kill 19255
Поддерживайте SSH-соединение в активном состоянии
Я не буду вдаваться в подробности, но существуют разные способы поддержания SSH-соединения.
Обработка тайм-аутов с пульсом
Оба параметра могут быть установлены на клиенте или сервере, или на обоих.
ClientAliveInterval
будет отправлять запрос каждые секунды для поддержания соединения:n
ClientAliveInterval 15
ClientAliveCountMax
— количество запросов пульса, отправленных после неполучения ответа от другой стороны соединения до разрыва соединения:ClientAliveCountMax 3
3
является значением по умолчанию, и установка его в значение отключит завершение соединения. В этом примере соединение оборвалось бы примерно через 45 секунд без каких-либо ответов.0
Повторное подключение после прекращения
Есть несколько способов сделать это; autossh, скрипты, cronjob и так далее.
Это выходит за рамки этого поста, и я, возможно, напишу об этом в будущем.
Ограничения #
УДП
SSH зависит от надежной доставки, чтобы иметь возможность правильно все расшифровать. UDP не обеспечивает никакой надежности и поэтому не поддерживается и не рекомендуется использовать через туннель SSH.
Тем не менее, есть способы сделать это, как описано в этом посте. Мне еще нужно его протестировать.
TCP-over-TCP
Это снижает пропускную способность из-за больших накладных расходов и увеличивает задержку. При подключении с потерей пакетов или большими задержками (например, спутниковые) это может привести к сбою TCP.
Этот пост - отличная статья.
Тем не менее, я некоторое время использовал OpenVPN-over-TCP, и он работал безупречно. Меньшая пропускная способность, чем у UDP, но надежный. Так что это сильно зависит от вашей настройки.
Не является заменой VPN
В целом, это не замена VPN. В качестве такового можно использовать SSH-туннелирование, но VPN лучше подходит для лучшей производительности.
Потенциальная угроза безопасности
Если вам эти функции не нужны, рекомендуется их включить. Злоумышленники могут использовать эти функции, чтобы обойти брандмауэры и другие меры безопасности.