raspberry pi и обратный ssh туннель – или как добраться до своей малинки за файрволом

Для доступа к “малинке” которая находится за файрволом потребуется сервер в интернете с публичным адресом
Адрес сервера в интернете: 123.123.123.321
На этом же адресе 123.123.123.321 откроем порт 2222 который будет “проброшен” на малинку на порт 22
На сервере в интернете создадим пользователя и каталог для ключа аутентификации

ssh root@123.123.123.321
useradd reverse-tunnel
mkdir -m700 /home/reverse-tunnel/.ssh

ВАЖНО! Также необходимо открыть порт 2222 для входящих TCP соединений. Я покажу как это сделано в iptables в CentOS.

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:SSH - [0:0]
:SSH2 - [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j SSH
-A INPUT -m state --state NEW -m tcp -p tcp --dport 2222 -j SSH2 -m comment --comment "rapsberry 1 over reverse tunnel"
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited

# These chains are used by fail2ban
-A SSH -j ACCEPT
-A SSH2 -j ACCEPT
COMMIT

На “малинке” сгенерируем ключ и скопируем на сервер в интернете.

mkdir -m700 /home/pi/.ssh
# сгенерируем ключ и положим в наш каталог
ssh-keygen -t rsa -b 4096 -f /home/pi/.ssh/reverse-tunnel-key
# добавить ключ на целевой сервер
echo "no-pty,no-X11-forwarding,permitopen=\"123.123.123.321:2222\",command=\"/bin/echo do-not-send-commands\" $(cat /home/pi/.ssh/reverse-tunnel-key.pub)" | ssh root@123.123.123.321 'cat >>/home/reverse-tunnel/.ssh/authorized_keys'

начало команды  echo “no-pty,no-X11-forwarding,permitopen=\”123.123.123.321:2222\”,command=\”/bin/echo do-not-send-commands\”   запрещает запускать какие либо команды, получать шел и ограничивает установление туннеля только на порт 22 на адресе 123.123.123.321.
Для усиления защищённости туннеля стоит отключить аутентификацию по паролю. Аутентификаця по паролю отключается в файле /etc/ssh/sshd_config

далее на “малинке” нужно установить autossh

apt-get install autossh

и настроить автозапуск

# создаём файл
cat /etc/systemd/system/autossh-reverse-tunnel.service
# со следующим содержимым
[Unit]
Description=AutoSSH reverse tunnel service
After=network.target

[Service]
Type=simple
User=pi
Environment="AUTOSSH_GATETIME=0"
#Environment="AUTOSSH_DEBUG=1"
ExecStart=/usr/bin/autossh -M 0 -o LogLevel=error -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -i /home/pi/.ssh/reverse-tunnel-key -N -R 123.123.123.321:2223:localhost:22 reverse-tunnel@123.123.123.321 -p 22
Restart=on-failure
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target

сообщить systemd что нужно перечитать конфигурационные файлы (это нужно делать после каждой правки файла сервиса)

systemctl daemon-reload

Разрешить автозапуск при старте

systemctl enable autossh-reverse-tunnel.service

И запустить сейчас (без рестарта)

systemctl start autossh-reverse-tunnel.service

Вот как будет выглядеть установленный туннель со стороны сервера в интернете

[root@mail log]# netstat -nlpt | grep ssh
tcp        0      0 123.123.123.321:2222        0.0.0.0:*                   LISTEN      24356/sshd          
tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN      1310/sshd           
tcp        0      0 :::22                       :::*                        LISTEN      1310/sshd           

После этого можно пользоваться туннелем:

ssh pi@123.123.123.321 -p 2222

В принципе качестве малинки может выступать любое устройство с сетевым интерфейсом к которому можно настроить доступ из интернет.
Обратный туннель на VNC или RDP позволит сделать свой удалённый доступ а-ля teamviewer. Так же просто получить доступ к IP камере или файловому серверу.