Доступ к сети с серым адресом

На вашей даче вы используете 4g-модем для выхода в интернет, кроме этого вы решили организовать там небольшую локальную сеть с видеонаблюдением и какой-нибудь автоматизацией, конечно же вы используете raspberry pi для этих целей. Но вот беда: ваш провайдер прячет вас за NAT, бесполезно открывать и переадресовывать порты на роутере, вы не сможете попасть в сеть. Я применил проброс портов, это очень распространенное решение, приведу пример как я это сделал (имея дома белый статический IP). Уточним инфраструктуру: на каждой стороне есть роутер с выходом в интернет, а внутри сети есть какой-нибудь сервер, в моем случае это машинки rasbperry pi, они и будут держать связь между собой.

  1. Пробрасываем порт из домашнего роутера на домашний сервер, внутри своей локальной сети для того, чтобы можно было извне попасть по ssh на ваш домашний сервер, это возможно потому, что эта сеть имеет белый IP, сюда легко попасть извне. Это вы сможете легко сделать через web-интерфейс вашего роутера
  2. Генерируем ключ для доступа в сеть, настроенную на первом шаге, то есть на вашей даче (в сети с серым IP).
    ssh-keygen -t rsa -b 2048
    ssh-copy-id -p "порт открытый на шаге 1" user@homeIp

    Зачем это нужно? Можно ли использовать пароль? Можно, но не удобно, ведь при создании туннеля пароль вас будут спрашивать и придётся использовать сторонние программы для его передачи, проще уж настроить доступ по ключу.
  3. Теперь можно создать туннель между raspberry
    ssh -R XXXX:localhost:22 -p XXXX user@homeIp
    В правой части команды описано то, куда мы подключаемся и через какой порт, а в левой части правило проброса порта, оно заключается в том, что мы пробросили порт XXXX на домашней машине в порт 22 на машине «дачной», в общем-то все знают формат команды, теперь сервер из серой сети проходит сквозь роутер на сервер белой сети
  4. Но есть проблема, такое соединение долго работать не будет, оно будет постоянно разрываться и нужно его восстанавливать, я для себя рассматривал разные варианты, например supervisor, но в конце концов нашел программу autossh
  5. Устанавливаем её и настраиваем, создадим файл конфигурации /etc/systemd/system/autossh.tunel.service
    с подобным содержимым (будем прокидывать ssh-порт)
    [Unit]
    Description=AutoSSH tunnel service on local port 22
    After=network.target

    [Service]
    User=your_user_name
    Environment="AUTOSSH_GATETIME=0"
    ExecStart=/usr/bin/autossh -M 20000 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -N -R XXX:localhost:22 -i /home/user/.ssh/your_file -p XXX user@homeIp

    [Install]
    WantedBy=multi-user.target
  6. Теперь осталось просто зарегистрировать конфиг
    sudo systemctl daemon-reload
    запустить
    sudo systemctl start autossh.tunel.service
    и включить в автозапуск
    sudo systemctl enable autossh.tunel.service
  7. Таким образом мы пришли к следующей ситуации: мы можем создавать туннели на любых портах, например, вы можете пробросить порт 8090 (видеонаблюдение xeoma) и запускать клиента этой программы локально дома, указав ей адрес вашего домашнего сервера и соответствующий порт, туннель доставит ваш трафик на настоящий сервер. Обратите внимание, пробрасывать порт на домашнем роутере нужно только один раз, тот самый XXXX для ssh, а остальные порты не нужно, они пойдут внутри туннеля.

Поговорим о параметрах autossh, один из них M, означает monitoring, если установить его в 0, то мониторинг соединения будет выключен, можно будет увидеть сообщение в логах port set to 0, monitoring disabled, в теории такие туннели будут тухнуть молча. Статья объясняет этот параметр и пока я пробую мониторить некоторые порты, а некоторые нет, чтобы на практике почувствовать разницу поведения программы. Ещё нужно будет добавить параметр T, который вроде бы не будет создавать фантомный терминал создавая туннель (не должно быть видно в команде who).