Прим. переводчика: автор статьи рассматривает практические сценарии и примеры организации SSH-туннелей. А для более наглядного объяснения того, как это работает, графически показывает потоки трафика. Туннели SSH — это зашифрованные TCP-соединения между клиентами и серверами SSH. Трафик входит с одной стороны туннеля и прозрачно выходит с другой. Изначально этот термин относился к туннелям на виртуальных сетевых интерфейсах TUN/TAP, однако сейчас так обычно называют проброс портов SSH. Например, вот так будет выглядеть схема обратного туннеля, в котором обращение к порту 80 SSH-клиента выполняется через SSH-сервер с определенного IP-адреса (1.2.3.4): Сценарии использования туннелей*: Предоставление зашифрованных каналов для протоколов, передающих данные «открытым текстом». Открытие бэкдоров в частные сети. Обход межсетевых экранов. Перечень дополняется. Не стесняйтесь предлагать примеры или исправления на GitHub. Перенаправляет порт из одной системы (локальной или удаленной) в другую. Проброс локальных портов позволяет перенаправить трафик с SSH-клиента на целевой хост через SSH-сервер. Другими словами, можно получить доступ к удаленным сервисам по зашифрованному соединению так, как будто они локальные. Примеры использования: доступ к удаленному сервису (Redis, Memcached и т. д.) по внутреннему IP-адресу; локальный доступ к ресурсам, размещенным в частной сети; прозрачное проксирование запроса к удаленному сервису. Проброс удаленного порта позволяет направить трафик с SSH-сервера в пункт назначения либо через SSH-клиент, либо через другой удаленный хост. Открывает пользователям в публичных сетях доступ к ресурсам в частных сетях. Примеры использования: открытие доступа к локальному серверу разработки через публичную сеть; предоставление доступа с ограничением по IP-адресу к удаленному ресурсу в частной сети. При динамической переадресации портов на SSH-клиенте поднимается SOCKS-прокси для перенаправления TCP-трафика через SSH-сервер на удаленный хост. Для пересылки трафика с системных портов (1–1023) необходимо запустить SSH с правами суперпользователя в системе, на которой открывается порт. Ниже приведены несколько полезных флагов при создании туннелей: Вот пример команды для создания SSH-туннеля в фоновом режиме и проброса локального порта через SSH-сервер: Для краткости примеры ниже приводятся без флагов командной строки. Перенаправление соединений с порта локальной системы на порт удаленного хоста: Перенаправляет локальные подключения к 127.0.0.1:8080 на 80-й порт example.org через SSH-сервер. Трафик между локальной системой и SSH-сервером идет по SSH-туннелю. Трафик между SSH-сервером и example.org — нет. С точки зрения example.org трафик идет от SSH-сервера. Команды выше открывают доступ к example.org:80 через SSH-туннель для подключений на порт 8080 на всех интерфейсах локальной системы. Переадресует соединения с 192.168.0.1:5432 в локальной системе на 127.0.0.1:5432 на SSH-сервере. Обратите внимание, что здесь 127.0.0.1 — localhost с точки зрения SSH-сервера. Убедитесь, что на SSH-сервере включена переадресация TCP (по умолчанию так и должно быть). Проверьте запись в файле /etc/ssh/sshd_config: При переадресации портов на интерфейсы, отличные от 127.0.0.1, в локальной системе необходимо включить GatewayPorts (в /etc/ssh/ssh_config или в командной строке): Подходит для случаев, когда требуется защищенное соединение для доступа к удаленному сервису, который работает с незашифрованными данными. Например, Redis и Memcached используют протоколы на основе plaintext-данных.  В случае если защищенный доступ к одному из таких сервисов на удаленном сервере организован по общедоступным сетям, можно настроить туннель от локальной системы до этого сервера. Пробрасывает порт на удаленной системе в другую систему. Перенаправляет трафик с порта 8080 SSH-сервера для всех интерфейсов на порт localhost:80 на локальном компьютере. Если один из интерфейсов смотрит в Интернет, трафик, адресуемый на порт 8080, будет перенаправляться на локальную систему. Переадресует трафик с порта 8080 SSH-сервера на localhost:80 в локальной системе, при этом доступ ко входу в SSH-туннель со стороны сервера разрешен только с IP-адреса 1.2.3.4 (обратите внимание: директиву GatewayPorts необходимо установить в clientspecified). Прим. переводчика: здесь, возможно, ошибка. Флаг -R — это binding_address, выбор IP адреса на машине, на котором SSH-сервер будет слушать порт. Соответственно вместо одного человечка с IP должны быть человечки, а вместо ssh_server:8080 должно быть 1.2.3.4:8080. Переадресует трафик с порта 8080 SSH-сервера для всех интерфейсов на localhost:80 в локальной системе. Далее трафик из локальной системы направляется на example.org:80. С точки зрения example.org источником трафика выступает локальная система. SSH-сервер конфигурируется в файле /etc/ssh/sshd_config.  По умолчанию переадресуемые порты недоступны для доступа из Интернета. Для переадресации публичного интернет-трафика на локальный компьютер добавьте в sshd_config на удаленном сервере такую строку: Также в sshd_config можно указать, каким клиентам разрешен доступ: Перенаправление трафика с нескольких портов на удаленный сервер. Команда выше поднимает SOCKS-прокси на порту 3000 для всех интерфейсов в локальной системе. Теперь трафик, отправленный через прокси-сервер на SSH-сервер, можно адресовать на любой порт или конечный хост. По умолчанию используется протокол SOCKS5, поддерживающий TCP и UDP. Поднимает SOCKS-прокси на 127.0.0.1:3000 в локальной системе. При работающем SOCKS-прокси можно настроить браузер на его использование для доступа к ресурсам так, как будто соединения исходят от SSH-сервера. Например, если у SSH-сервера есть доступ к другим серверам в частной сети, с помощью SOCKS-прокси можно заходить на эти серверы локально (словно вы находитесь в той же сети), и не нужно настраивать VPN. Работу SOCKS-прокси можно проверить командой: SSH-клиент настраивается в файле /etc/ssh/ssh_config.  Включите GatewayPorts в системе, чтобы открыть доступ другим интерфейсам к SOCKS-прокси: Поскольку GatewayPorts конфигурируется на SSH-клиенте, вместо ssh_config для настройки можно использовать параметры командной строки: Прозрачное подключение к удаленному хосту через промежуточные. Устанавливает SSH-соединение с jump-хостом и переадресуют трафик на удаленный хост.  Подключается к удаленному хосту через промежуточный jump-хост. Приведенная выше команда должна сработать сразу, если у jump-хоста уже есть SSH-доступ к удаленному хосту. Если нет, можно использовать agent forwarding для проброса SSH-ключа с локального компьютера на удаленный хост. Можно указать несколько jump-хостов через запятую. Подключение к удаленному серверу через SOCKS5 с использованием netcat. С точки зрения сервера, IP-адрес отправителя принадлежит прокси-хосту. При этом для SSH-соединения используется сквозное шифрование, так что прокси-хост видит только зашифрованный трафик между локальной системой и удаленным хостом. SSH-клиент конфигурируется в файле /etc/ssh/ssh_config. Для подключения agent forwarding можно добавить локальный SSH-ключ к локальному SSH-агенту с помощью ssh-add: Перечисленные выше команды работают на разовой основе: вы сразу получаете конкретный результат, и на этом их работа заканчивается. Поэтому, чтобы обеспечить защиту SSH-туннелей от сбоев в сети или ненадежных соединений, придется выполнить дополнительную настройку. По умолчанию TCP-соединение, используемое для создания SSH-туннеля, может разрываться после некоторого периода бездействия. Чтобы это предотвратить, нужно настроить сервер (/etc/ssh/sshd_config) на отправку heartbeat-сообщений: На отсылку таких сообщений также можно настроить клиент (/etc/ssh/ssh_config): Указанные выше настройки могут предотвратить разрывы из-за неактивности, но они не в состоянии восстановить прерванные соединения. Для автоматического перезапуска SSH-туннеля можно воспользоваться утилитой autossh — она создает SSH-туннель и отслеживает его работоспособность. AutoSSH принимает те же аргументы для настройки переадресации портов, что и SSH: Эта команда создает туннель, способный восстанавливаться после сетевых сбоев. По умолчанию AutoSSH открывает дополнительные порты на SSH-клиенте/сервере для проверки работоспособности (healthcheck). Если трафик не проходит между healthcheck-портами, AutoSSH перезапускает туннель. Флаг -M 0 отключает healthcheck-порты (за проверку работоспособности в этом случае отвечает SSH-клиент). В примере выше сервер должен посылать сигналы каждые 10 секунд. Если не проходят три подряд сигнала, SSH-клиент завершает работу, а AutoSSH поднимает новый туннель. Прозрачный доступ к удаленному ресурсу в частной сети. Предположим, в частной сети есть Git-репозиторий, доступ к которому возможен только через выделенный сервер в этой сети. Сервер не подключен к Интернету. Есть прямой доступ к серверу, но нет VPN-доступа к частной сети. Требуется открыть доступ к Git-репозиторию, как если бы подключение к нему шло напрямую из локальной системы. Если есть SSH-доступ к другому серверу, который доступен как с локального компьютера, так и с выделенного сервера, можно создать SSH-туннель и воспользоваться директивами ProxyCommand. Команда выше пробрасывает порт 2222 на промежуточном хосте на порт 22 выделенного сервера. Теперь можно подключиться к SSH-серверу на выделенном сервере, несмотря на то, что он недоступен из Интернета. Прим. переводчика: возможно, что здесь тоже ошибка: перепутаны местами 22 и 2222 порты в команде. Для большего удобства можно добавить несколько директив в локальный ~/.ssh/config: В результате пользователь получает доступ к локальному Git-репозиторию, как если бы находился в частной сети. Читайте также в нашем блоге:  «Автоматизация SSH-доступа к нодам Kubernetes с помощью Fabric и интеграции от CoreOS»; «Немного хардкора: как поднять Kubernetes на двух старых ноутбуках с Gentoo»; «Как с tcpserver и netcat открыть туннель в Kubernetes pod или контейнер».