Зворотний 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 описує кожну з використаних вище опцій, і варто повністю прочитати розділи про перенаправлення, перш ніж розширювати будь-яку з них.