Проброс трафика через SSH: локальный, remote, SOCKS и TUN

Photo Ubuntu server

SSH – это не только shell на сервере. Через OpenSSH можно пробросить TCP-порты, поднять SOCKS-прокси и даже layer-3 туннель (TUN). Команды ниже одинаковы по смыслу на Linux, macOS и FreeBSD: клиент – ssh, сервер – sshd. Различия в основном в перезапуске службы и синтаксисе ip/ifconfig.

Что значит «инкапсуляция» здесь

Трафик приложения едет внутри уже зашифрованной SSH-сессии. Снаружи виден обмен с портом SSH (обычно 22), содержимое портов и SOCKS – нет. Это удобно для доступа к внутренним сервисам, обхода «только исходящий 22» и ad-hoc VPN без отдельного демона.

  • шифрование канала OpenSSH;
  • доступ к хостам, видимым только с jump/SSH-сервера;
  • минимум инфраструктуры: достаточно рабочего sshd.

Три типа проброса портов

Локальный (-L)

На вашей машине слушается порт; соединения уходят на SSH-сервер и с него – на целевой host:port (часто во внутренней сети).

ssh -L [локальный_порт]:[удалённый_хост]:[удалённый_порт] user@ssh.example.com

# пример: internal.example.com:80 → localhost:8080
ssh -L 8080:internal.example.com:80 user@ssh.example.com

В браузере: http://127.0.0.1:8080. Цель резолвится и доступна со стороны SSH-сервера, не обязательно с вашего ноутбука.

Удалённый (-R)

На SSH-сервере открывается порт; трафик с сервера приходит на host:port у вас (или за вами).

ssh -R [порт_на_сервере]:[цель_хост]:[цель_порт] user@ssh.example.com

# локальный MySQL → порт 3306 на сервере (только localhost сервера по умолчанию)
ssh -R 3306:localhost:3306 user@ssh.example.com

Чтобы слушать не только 127.0.0.1 на сервере, в sshd_config нужно GatewayPorts (осторожно с экспозицией). Для «выставить локальный сервис наружу» чаще смотрят reverse tunnel + firewall, а не открытый 0.0.0.0 без нужды.

Динамический (-D, SOCKS)

Локальный SOCKS-прокси: приложения сами указывают, куда идти, а SSH ходит к целям от имени сервера.

ssh -D 1080 user@ssh.example.com

В браузере или системе: SOCKS5, host 127.0.0.1, порт 1080. Для CLI часто ALL_PROXY=socks5h://127.0.0.1:1080 или proxychains – зависит от инструмента.

Примеры сценариев

OpenSSH-флаги на Linux, macOS и FreeBSD одни и те же. Меняются только пути логов и менеджер служб.

  • HTTPS-сервис за бастионом: ssh -L 8443:remote.service.com:443 user@ssh.example.com, затем https://127.0.0.1:8443;
  • отдать локальный веб на сервер: ssh -R 8080:localhost:8080 user@ssh.example.com;
  • временный SOCKS «весь браузер через VPS»: ssh -D 1080 user@vps;
  • SMTP relay через bastion: ssh -L 2525:mail.example.com:25 user@ssh.example.com.

Полезные опции: -N (без shell, только туннель), -f (в фон после auth), -C (сжатие, иногда помогает на тексте). Для фона надолго удобнее autossh или unit systemd, а не «забытый» -f.

Jump-host (-J)

Цепочка: ваш ПК → bastion → целевой хост без ручного double-ssh:

ssh -J user@jump-host user@destination-host

Несколько прыжков – через запятую. В ~/.ssh/config то же через ProxyJump.

X11 forwarding

Запуск GUI-приложения с удалённого хоста (нужен X-сервер на клиенте; на macOS – отдельный XQuartz и т.п.):

ssh -X user@ssh.example.com
# или -Y (trusted), если -X режет нужные расширения

На сервере в sshd_config:

X11Forwarding yes

Для постоянной удалённой работы удобнее VNC/RDP/Waypipe, чем тяжёлый X11 через SSH.

Layer-3: TUN через SSH (-w)

Режим «почти VPN»: point-to-point через устройства tun. Нужны root на клиенте, поддержка TUN, на сервере – PermitTunnel yes. Это не полноценная замена WireGuard/OpenVPN (NAT, MTU, устойчивость, маршруты – вручную).

Сервер

# /etc/ssh/sshd_config
PermitTunnel yes

# Linux (systemd):
sudo systemctl restart sshd
# FreeBSD:
sudo service sshd restart

Клиент: сессия с tun

sudo ssh -w 0:0 user@ssh.example.com

-w 0:0 – пара номеров tun на клиенте и сервере (tun0/tun0). Сессия должна оставаться открытой; адреса и маршруты задают отдельно (часто вторым терминалом или скриптом после подъёма интерфейса).

Адреса на tun

Сервер (Linux; на macOS синтаксис ip может отличаться, часто используют ifconfig):

sudo ip addr add 10.0.0.1/24 dev tun0
sudo ip link set tun0 up

Клиент:

sudo ip addr add 10.0.0.2/24 dev tun0
sudo ip link set tun0 up

FreeBSD (пример point-to-point):

# сервер
sudo ifconfig tun0 10.0.0.1 10.0.0.2 netmask 255.255.255.0 up
# клиент
sudo ifconfig tun0 10.0.0.2 10.0.0.1 netmask 255.255.255.0 up

Маршруты

Гнать default через туннель (осторожно: можно потерять маршрут к самому SSH-серверу, если не оставить host-route):

# Linux: лучше сначала host-route до ssh.example.com через старый gateway
sudo ip route add default via 10.0.0.1 dev tun0

# FreeBSD
sudo route add default 10.0.0.1

На сервере для выхода клиентов в интернет нужны IP forwarding и NAT (nftables/iptables). Без этого «пинг 8.8.8.8» с клиента не заработает, даже если tun up.

UDP через SSH

Проброс портов SSH – TCP. UDP иногда «протаскивают» через socat/аналоги, оборачивая в поток внутри SSH. Схема хрупкая; для DNS/VPN-подобных задач надёжнее WireGuard или отдельный VPN.

Практика: устойчивость и безопасность

  • ключи вместо пароля: ssh-keygen -t ed25519 (или RSA 4096, если политика требует);
  • ограничения в sshd_config: AllowUsers, отключение root-пароля, по возможности fail2ban/гео;
  • keep-alive, чтобы NAT не рвал idle-туннель:
# в ~/.ssh/config для Host *
ServerAliveInterval 60
ServerAliveCountMax 3
  • не открывайте -R на 0.0.0.0 без firewall и понимания, кто достучится;
  • логи: Linux часто /var/log/auth.log или journald; FreeBSD – /var/log/auth.log / security.

Типичные сбои

  • порт уже занят локально – смените левую часть -L/-D;
  • -R не слушает снаружи – GatewayPorts и firewall на сервере;
  • TUN: «device busy» / нет tun0 – другой номер -w, права root, PermitTunnel;
  • маршруты: ip route / netstat -rn, host-route до bastion до смены default.

Краткий чеклист

  • нужен один порт/сервис – -L или -R;
  • нужен «весь браузер/куча хостов» – -D;
  • нужен IP-туннель – WireGuard предпочтительнее; SSH -w – запасной вариант;
  • ключи, keep-alive, минимальные открытые порты, понятные маршруты.

Итог: локальный, удалённый и динамический проброс закрывают большую часть задач «достучаться до сервиса через bastion». TUN и трюки с UDP – ниша; для постоянной сети лучше профильный VPN.

Источники и ссылки


Комментарии загружаются…