Создание SSH-туннеля. Часть 3 из 4
19.01.2020
Теги: CLI • Linux • SSH • Ubuntu • Виртуализация • Команда • Конфигурация • Настройка • Сервер
Мы создавали ssh-туннели между виртуальными машинами, где сетевые соединения стабильны. Но в реальной жизни каналы связи оставляют желать много лучшего. Было бы разумно как-то отслеживать наличие соединения и автоматически его восстанавливать.
В OpenSSH присутствует стандартная схема для мониторинга состояния подключения, причем как на стороне сервера, так и на стороне клиента. Суть ее заключается в том, что OpenSSH будет проверять наличие рабочего подключения и в случае отсутствия такового будет просто завершать ssh-сеанс, избавляя нас от зависших сессий.
Проверка активности соединения
Для этого отредактируем файл конфигурации /etc/ssh/sshd_config
на виртуальной машине ssh-server
:
$ sudo nano /etc/ssh/sshd_config
# отключаем дефолтный механизм проверки активности соединения TCPKeepAlive no # проверять активность подключения клиента каждые 30 секунд ClientAliveInterval 30 # сервер закроет соединение после трех неудачных попыток ClientAliveCountMax 3
$ sudo systemctl restart ssh.service
Если что-то произойдет с клиентом, например, компьютер просто отключится от сети, то через 90 секунд ssh-server
закроет туннельное соединение.
В файле /etc/ssh/sshd_config
есть параметр TCPKeepAlive
, который по умолчанию имеет значение yes
. Он позволяет поддерживать TCP-соединение в активном состоянии, даже когда нет передачи пакетов. Эта решается на уровне протокола TCP/IP с помощью отправки специальных проверочных пакетов.
Кроме того, OpenSSH имеет альтернативные средства контроля активности сеансов — ClientAliveInterval
и ClientAliveCountMax
. При использовании этих параметров, в отличие от TCPKeepAlive
, запросы отправляются через защищённый ssh-канал и не могут быть подменены.
При создании туннельного подключения со стороны клиента есть возможность указать аналогичные параметры ServerAliveInterval
и ServerAliveCountMax
. Команда создания туннеля на виртуальной машине web-server
:
$ ssh -p 2222 -o "TCPKeepAlive no" -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" \ > -R 3306:127.0.0.1:3306 evgeniy@192.168.110.8
ExitOnForwardFailure yes
.
Параметры на стороне клиента можно задавать как в командной строке, так и записать их в файл конфигурации:
$ nano ~/.ssh/config
# Проброс соединения 192.168.110.8 ==R==> 192.168.110.12 Host remote-forward-ssh-server HostName 192.168.110.8 Port 2222 User evgeniy IdentityFile ~/.ssh/tcp-forward-ssh-server TCPKeepAlive no ServerAliveInterval 30 ServerAliveCountMax 3 ExitOnForwardFailure yes RemoteForward 3306 127.0.0.1:3306 # Проброс соединения 192.168.110.8 <==L== 192.168.110.12 Host local-forward-ssh-server HostName 192.168.110.8 Port 2222 User evgeniy IdentityFile ~/.ssh/tcp-forward-ssh-server TCPKeepAlive no ServerAliveInterval 30 ServerAliveCountMax 3 ExitOnForwardFailure yes LocalForward 3307 127.0.0.1:3306
В этом случае команда создания туннеля будет проще:
$ ssh remote-forward-ssh-server
Поскольку при создании туннеля не планируется выполнять команды на виртуальной машине ssh-server
, можно добавить опцию
$ ssh -N remote-forward-ssh-server
Но в этом случае терминал у нас зависнет, т.к. будет ожидать окончания выполнения этой команды. И для дальнейшей работы нам потребуется еще один терминал. Но мы можем запустить эту команду в фоновом режиме:
$ ssh -N remote-forward-ssh-server & [1] 3949
Чтобы завершить фоновый процесс, надо переместить его на передний план, а потом завершить с помощью Ctrl+C
:
$ fg 1 ssh -N remote-forward-ssh-server ^C
Автоматическое восстанавление туннеля
Утилита autossh
предназначена для мониторинга соединений ssh и их автоматического восстановления в случае разрыва. Она уже входит в репозитории Ubuntu, поэтому устанавливаем ее на виртуальную машину web-server
:
$ sudo apt install autossh
$ autossh usage: autossh [-V] [-M monitor_port[:echo_port]] [-f] [SSH_OPTIONS] -M specifies monitor port. Overrides the environment variable AUTOSSH_PORT. 0 turns monitoring loop off. Alternatively, a port for an echo service on the remote machine may be specified. (Normally port 7.) -f run in background (autossh handles this, and does not pass it to ssh.) -V print autossh version and exit. Environment variables are: AUTOSSH_GATETIME - how long must an ssh session be established before we decide it really was established (in seconds). Default is 30 seconds; use of -f flag sets this to 0. AUTOSSH_LOGFILE - file to log to (default is to use the syslog facility) AUTOSSH_LOGLEVEL - level of log verbosity AUTOSSH_MAXLIFETIME - set the maximum time to live (seconds) AUTOSSH_MAXSTART - max times to restart (default is no limit) AUTOSSH_MESSAGE - message to append to echo string (max 64 bytes) AUTOSSH_PATH - path to ssh if not default AUTOSSH_PIDFILE - write pid to this file AUTOSSH_POLL - how often to check the connection (seconds) AUTOSSH_FIRST_POLL - time before first connection check (seconds) AUTOSSH_PORT - port to use for monitor connection AUTOSSH_DEBUG - turn logging to maximum verbosity and log to stderr
Команда создания туннеля на виртуальной машине web-server
:
$ autossh -M 0 -N -p 2222 -o "TCPKeepAlive no" -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" \ > -o "ExitOnForwardFailure yes" -R 3306:127.0.0.1:3306 evgeniy@192.168.110.8
$ autossh -M 0 -N remote-forward-ssh-server
autossh
обязательна опция -M
, которая задает порт для мониторинга соединения. Но ssh-клиент может и сам это делать (это опции ServerAliveInterval
и ServerAliveCountMax
). Так что опцию -M
будем всегда отключать.
Чтобы запустить autossh
в фоновом режиме, добавляем опцию -f
:
$ autossh -M 0 -f -N -p 2222 -o "TCPKeepAlive no" -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" \ > -o "ExitOnForwardFailure yes" -R 3306:127.0.0.1:3306 evgeniy@192.168.110.8
$ autossh -M 0 -f -N remote-forward-ssh-server
-M
и -f
относятся к autossh
, а все остальные передаются ssh
.
Проверим, что туннель работает, воспользовавшись командой ps
:
$ ps -f -C autossh UID PID PPID C STIME TTY TIME CMD evgeniy 4000 3210 0 12:26 ? 00:00:00 /usr/lib/autossh/autossh -M 0 -N remote-forward-ssh-server
Чтобы завершить процесс, используем команду pkill
:
$ pkill autossh
Проверяем, как работает autossh
Во второй части мы решали две задачи:
- Пробросить ssh-туннель от
TKMCOMP
доweb-server
через промежуточныйssh-server
, чтобы иметь возможность подключаться с физической машиныTKMCOMP
к серверу БД на виртуальной машинеweb-server
- Пробросить ssh-туннель от
web-server
доTKMCOMP
через промежуточныйssh-server
, чтобы иметь возможность подключаться с виртуальной машиныweb-server
к серверу БД на физической машинеTKMCOMP
Мы сейчас посмотрим, как работает autossh
, пробрасывая туннель от web-server
до ssh-server
(правая половина первого рисунка). Для проверки того, что туннель работает, установим на виртуальную машину ssh-server
клиент БД MySQL:
$ sudo apt install mysql-client
Теперь с виртуальной машины web-server
выполним команду создания туннеля:
$ autossh -M 0 -N remote-forward-ssh-server
А с виртуальной машины ssh-server
соединяемся с сервером БД MySQL:
$ mysql -uroot -pqwerty --protocol=TCP
Соединение прошло успешно. Теперь выключим сетевой интерфейс на виртуальной машине ssh-server
:
$ sudo ip link set dev enp0s3 down
Удостоверимся, что подключиться к серверу БД MySQL теперь нельзя:
$ mysql -uroot -pqwerty --protocol=TCP mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (111)
И посмотрим, как отреагирует утилита autossh
на машине web-server
:
$ autossh -M 0 -N remote-forward-ssh-server Timeout, server 192.168.110.8 not responding. # прошло 90 секунд, сервер не отвечает ssh: connect to host 192.168.110.8 port 2222: No route to host # попытка соединения с сервером ssh: connect to host 192.168.110.8 port 2222: No route to host # попытка соединения с сервером ssh: connect to host 192.168.110.8 port 2222: No route to host # попытка соединения с сервером
При включении сетевого интерфейса на виртуальной машине ssh-server
:
$ sudo ip link set dev enp0s3 up
Туннель будет восстановлен. Это можно проверить, если выполнить команду на ssh-server
:
$ mysql -uroot -pqwerty --protocol=TCP mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 12 Server version: 5.7.28-0ubuntu0.18.04.4 (Ubuntu) ..........
Если возникли какие-то проблемы с autossh
, можно запустить утилиту в режиме отладки:
$ AUTOSSH_DEBUG=1 autossh -M 0 -N remote-forward-ssh-server autossh[2744]: port set to 0, monitoring disabled # мы отключили мониторинг autossh[2744]: checking for grace period, tries = 0 autossh[2744]: starting ssh (count 1) # запуск ssh (попытка 1) autossh[2744]: ssh child pid is 2747 autossh[2744]: check on child 2747 autossh[2744]: set alarm for 600 secs autossh[2747]: execing /usr/bin/ssh Timeout, server 192.168.110.8 not responding. autossh[2744]: check on child 2747 autossh[2744]: ssh exited with error status 255; restarting ssh autossh[2744]: expired child, returning 1 autossh[2744]: checking for grace period, tries = 1 autossh[2744]: starting ssh (count 2) # запуск ssh (попытка 2) autossh[2744]: ssh child pid is 2754 autossh[2744]: check on child 2754 autossh[2744]: set alarm for 559 secs autossh[2754]: execing /usr/bin/ssh ssh: connect to host 192.168.110.8 port 2222: No route to host autossh[2744]: check on child 2754 autossh[2744]: ssh exited with error status 255; restarting ssh autossh[2744]: expired child, returning 1 autossh[2744]: checking for grace period, tries = 2 autossh[2744]: starting ssh (count 3) # запуск ssh (попытка 3) autossh[2744]: ssh child pid is 2755 autossh[2744]: check on child 2755 autossh[2744]: set alarm for 524 secs autossh[2755]: execing /usr/bin/ssh ssh: connect to host 192.168.110.8 port 2222: No route to host autossh[2744]: check on child 2755 autossh[2744]: ssh exited with error status 255; restarting ssh autossh[2744]: expired child, returning 1 autossh[2744]: checking for grace period, tries = 3 autossh[2744]: starting ssh (count 4) # запуск ssh (попытка 4) autossh[2744]: ssh child pid is 2756 autossh[2744]: check on child 2756 autossh[2744]: set alarm for 521 secs autossh[2756]: execing /usr/bin/ssh
Поиск: CLI • Linux • Ubuntu • SSH • Виртуальная машина • Команда • Конфигурация • Настройка • Сервер • Туннель