Обратный SSH для одного устройства: loopback-слушатель или маршрутизируемый VPN?
Один административный порт для устройства, которое умеет только звонить наружу. Три условия решают, достаточно ли обратного туннеля или нужен настоящий маршрутизируемый путь.
Ваше устройство находится за NAT оператора, может открывать исходящие соединения и запускает SSH-сервер, до которого никто не доберётся. Приходящий запрос обычно формулируется как "дайте ему VPN", и это один ответ из нескольких. Прежде чем согласиться, решите, нужен ли вам один административный TCP-порт или маршрутизируемый путь ко всей подсети, потому что это разные проекты с разной экспозицией.
Обратный туннель хорошо отвечает на узкую версию. Устройство дозванивается до вашего концентратора, просит его слушать на loopback-порту и перенаправляет этот порт назад в свой SSH-сервис. Затем администраторы попадают к слушателю через концентратор, а не через публичный интернет.
Три условия, которые решают выбор
Запишите их до любой настройки. Это граница между ограниченным административным входом и расширением сети, и их смешение — тот путь, на котором туннель из пяти строк превращается в бесхозную плоскую сеть.
| Condition | Reverse tunnel fits | Something else is needed |
|---|---|---|
| How many services must be reachable? | One, or a small fixed set on loopback | Anything that needs many ports or dynamic discovery |
| Who connects, and how are they authenticated? | Named administrators with their own hub accounts | Third parties, or anything needing per-flow audit you do not control |
| Does the device's own LAN need to be reachable? | No | Yes, so a routed VPN or a managed platform is the honest answer |
Третья строка — та, о которой спорят. Туннель к SSH-порту устройства не помещает его соседей в вашу сеть, и не стоит через цепочку дополнительных перенаправлений делать вид, что помещает. Если требование действительно LAN, так и скажите и проектируйте именно её.
Сторона концентратора: ограниченная учётная запись реле
Дайте каждому устройству собственную учётную запись реле с аутентификацией по открытому ключу и без интерактивной сессии. Match блок, ограниченный этой учётной записью, держит разрешение маленьким, а закрытый ключ остаётся на устройстве, где ему место.
Match User relay-dev-7
AuthenticationMethods publickey
PubkeyAuthentication yes
AllowTcpForwarding remote
PermitListen 127.0.0.1:21022
GatewayPorts no
MaxSessions 0
PermitTTY no
X11Forwarding no
AllowAgentForwarding no
MaxSessions 0 — интересная строка. Он запрещает сессии оболочки и подсистем, но по-прежнему разрешает перенаправление, нужное устройству, поэтому украденный ключ нельзя превратить в интерактивный вход. PermitListen фиксирует адрес и порт слушателя на стороне концентратора, и GatewayPorts no держит его на loopback вместо того, чтобы открывать в сеть, где стоит концентратор.
Проверьте действующую конфигурацию перед перезагрузкой и держите вторую сессию открытой, пока это делаете. Match блок, который случайно применяется ко всем, или опечатка в имени опции — классический способ запереть себя снаружи машины, которую вы укрепляете. Выгрузите работающую конфигурацию и перечитайте опции, а не доверяйте только что написанному файлу. Учтите, что поддержка опций различается между сборками, поэтому принятая в новом сервере строка может просто игнорироваться старым.
Сторона устройства: перенаправление, которое громко падает
Устройство открывает соединение и запрашивает слушатель. Два адреса в аргументе -R означают разное, и чтение их слева направо — самый быстрый способ запомнить, какой из них какой.
ssh -NT \
-o ExitOnForwardFailure=yes \
-o ServerAliveInterval=30 \
-o ServerAliveCountMax=3 \
-R 127.0.0.1:21022:127.0.0.1:22 \
[email protected]
Левая пара — это то, где должен слушать концентратор. Правая пара — то, к чему устройство подключается, когда приходит запрос, разрешаемое с его собственной стороны. Если их поменять, получится туннель, который чисто поднимается и перенаправляет не туда, а это хуже отказа.
ExitOnForwardFailure=yes заставляет команду выходить, когда запрошенный слушатель не удаётся поднять, поэтому цикл перезапуска говорит вам правду вместо того, чтобы оставить полурабочую сессию. Он ничего не говорит о том, здоров ли локальный SSH-сервис позже, поэтому сочетайте его с менеджером процессов и эпизодической настоящей проверкой соединения.
Никогда не заменяйте адрес прослушивания loopback шаблоном, чтобы обойтись без лишнего перехода. Это единственное изменение — разница между административным путём и публично доступным портом, и обычно оно случается при отладке, а потом остаётся. Если коллега не может добраться до порта через концентратор, исправьте конфигурацию перехода, а не расширяйте привязку. Loopback — весь аргумент безопасности этого проекта.
Доступ администратора через концентратор
Администратор с обычной учётной записью на концентраторе может прыгнуть через него до перенаправленного порта. Учётная запись реле для этого не используется, и именно в этом смысл держать их раздельно.
ssh -J [email protected] -o HostKeyAlias=device-7 \
-p 21022 [email protected]
Проверьте ключ хоста устройства под выбранным псевдонимом, потому что этот ключ идентифицирует устройство в конце цепочки, а туннель — только транспорт. Вход от конца до конца по-прежнему аутентифицирует обе стороны; туннель, заканчивающийся на общем концентраторе, не делает его сам по себе доверенным путём.
Возьмите на себя жизненный цикл
Запускайте команду устройства под менеджером процессов ровно с одним активным экземпляром и политикой перезапуска, которую вы выбрали сознательно. Опции keepalive обнаруживают мёртвого партнёра; они не воскрешают процесс, который завершился.
Затем напишите процедуру вывода из эксплуатации. Каждое устройство получает свой слушатель и свой ключ, поэтому вывод означает отзыв этой учётной записи и удаление этого ключа, а не ротацию общего для всего парка секрета.
Наконец, помните, что даёт вам loopback. Он ограничивает сетевую экспозицию и ничего не делает с другими локальными пользователями на общем концентраторе, поэтому политика доступа самого концентратора всё равно должна быть правильной. Справочник по sshd_config описывает каждую из использованных выше опций, и стоит полностью прочитать разделы о перенаправлении, прежде чем расширять любую из них.