Перейти до змісту

Зворотний SSH-тунель через autossh

Зворотний SSH-тунель дозволяє внутрішньому серверу (за NAT/фаєрволом) бути доступним через публічний VPS. Внутрішній сервер сам ініціює вихідне SSH-з'єднання і прив'язує віддалений порт на VPS до свого SSH-порту.

1. Скопіювати SSH-ключ на внутрішній сервер

Внутрішньому серверу потрібен ключ для автентифікації на VPS:

scp ~/.ssh/id_ed25519 internal-server:/root/.ssh/

Переконайтесь, що відповідний публічний ключ додано до ~/.ssh/authorized_keys на VPS.

2. Встановити autossh

sudo apt install autossh

autossh моніторить SSH-з'єднання і автоматично перезапускає його при розриві.

3. Створити systemd-сервіс

sudo nano /etc/systemd/system/sysinit-target-audit.service
[Unit]
Description=sysinit-target-audit.service
After=network-online.target
Wants=network-online.target

[Service]
User=root
Environment="AUTOSSH_GATETIME=0"
ExecStart=/usr/bin/autossh -M 0 -N \
  -o "ServerAliveInterval 30" \
  -o "ServerAliveCountMax 3" \
  -o "ExitOnForwardFailure=yes" \
  -R 0.0.0.0:<REMOTE_PORT>:127.0.0.1:22 <user>@<vps-ip>
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Ключові параметри:

  • AUTOSSH_GATETIME=0 — не чекати на початкове з'єднання, одразу почати моніторинг.
  • -M 0 — вимкнути вбудований моніторинговий порт autossh; покладатися на keepalive самого SSH.
  • ServerAliveInterval 30 / ServerAliveCountMax 3 — SSH надсилає keepalive кожні 30с; розриває з'єднання після 3 пропущених відповідей (90с загалом).
  • ExitOnForwardFailure=yes — якщо віддалений порт вже зайнятий, одразу завершити роботу, щоб systemd міг перезапустити сервіс.
  • network-online.target + Wants= — чекати повної готовності мережі перед запуском.
  • Restart=always / RestartSec=10 — systemd перезапускає сервіс через 10с після будь-якого збою.

4. Увімкнути та запустити

sudo systemctl daemon-reload
sudo systemctl enable sysinit-target-audit.service
sudo systemctl start sysinit-target-audit.service

5. Очистити історію команд (опційно)

Якщо ви вводили чутливі команди під час налаштування:

for cmd in $(history | tail -28 | awk '{print $1}' | sort -r); do history -d "$cmd"; done && history -w