Создание SSH-туннеля. Часть 4 из 4

26.01.2020

Теги: CLILinuxSSHSystemdUbuntuКонфигурацияНастройкаСервер

Во второй части мы решали две задачи:

  1. Пробросить ssh-туннель от TKMCOMP до web-server через промежуточный ssh-server, чтобы иметь возможность подключаться с физической машины TKMCOMP к серверу БД на виртуальной машине web-server
  2. Пробросить ssh-туннель от web-server до TKMCOMP через промежуточный ssh-server, чтобы иметь возможность подключаться с виртуальной машины web-server к серверу БД на физической машине TKMCOMP

До этого момента мы создавали туннели сами, выполняя команды ssh или autossh. Гораздо удобнее, если туннель будет запускаться без нашего участия, во время загрузки операционной системы. Для первой задачи создадим две службы: на виртуальной машине web-server и на физической машине TKMCOMP. Каждая из этих служб будут запускаться во время загрузки Linux и Windows, создавая туннель к виртуальной машине ssh-server, и в дальнейшем поддерживать туннель в рабочем состоянии.

Запуск autossh при загрузке web-server

Для этого создаем новый unit-файл на виртуальной машине web-server:

$ sudo nano /etc/systemd/system/autossh-tunnel.service
[Unit]
Description=Autossh tunnel to ssh-server at startup
After=network-online.target

[Service]
User=evgeniy
Group=evgeniy
Environment="AUTOSSH_GATETIME=0"
ExecStart=/usr/bin/autossh -M 0 -N -F /home/evgeniy/.ssh/config remote-forward-ssh-server

[Install]
WantedBy=multi-user.target

Переменная окружения AUTOSSH_GATETIME по умолчанию имеет значение 30 секунд. Она задает время, которое должно пройти, чтобы autossh считал первое соединение ssh успешным. При любых проблемах первого подключения в течение 30 секунд — autossh просто прекращает свою работу, не пытаясь запустить ssh повторно. Это особенно полезно на этапе настройки и тестирования autossh и ssh.

Если переменная окружения AUTOSSH_GATETIME имеет нулевое значение, такое поведение отключается. Даже если первое соединение ssh было неудачным, autossh не прекращает свою работу, а переходит в фоновый режим и пытается запустить ssh снова. Если использована опция -f для autossh — переменная AUTOSSH_GATETIME устанавливается в ноль.

И сообщаем операционной системе про новый unit-файл:

$ sudo systemctl daemon-reload

Добавляем новую службу в автозагрузку:

$ sudo systemctl enable autossh-tunnel.service

Перезагружаем систему и смотрим статус нашей службы:

$ sudo systemctl status autossh-tunnel.service

Альтернативный вариант восстановления туннеля

Разбираясь с созданием unit-файла, обнаружил, что поддерживать туннель в рабочем состоянии можно гораздо проще, без использования утилиты autossh:

$ sudo nano /etc/systemd/system/autossh-tunnel.service
[Unit]
Description=Autossh tunnel to ssh-server at startup
After=network-online.target

[Service]
User=evgeniy
Group=evgeniy
ExecStart=/usr/bin/ssh -N -F /home/evgeniy/.ssh/config remote-forward-ssh-server
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Перезагружаем систему и смотрим статус нашей службы:

$ sudo systemctl status autossh-tunnel.service

Автозапуск туннеля при загрузке TKMCOMP

На физическом компьютере у нас уже создан файл ~/.ssh/config:

# Проброс соединения 192.168.110.2 ==L==> 192.168.110.8
Host local-forward-ssh-server
  HostName 192.168.110.8
  Port 2222
  User evgeniy
  IdentityFile ~/.ssh/tcp-forward-ssh-server
  LocalForward 3307 127.0.0.1:3306

# Проброс соединения 192.168.110.2 <==R== 192.168.110.8
Host remote-forward-ssh-server
  HostName 192.168.110.8
  Port 2222
  User evgeniy
  IdentityFile ~/.ssh/tcp-forward-ssh-server
  RemoteForward 3306 127.0.0.1:3306

По аналогии с файлом ~/.ssh/config на виртуальной машине web-server добавляем в него опции мониторинга ssh-туннеля. Кроме того, указываем абсолютный путь к файлу ключа (зачем — станет понятно чуть ниже):

# Проброс соединения 192.168.110.2 ==L==> 192.168.110.8
Host local-forward-ssh-server
  HostName 192.168.110.8
  Port 2222
  User evgeniy
  IdentityFile C:/Users/Evgeniy/.ssh/tcp-forward-ssh-server
  TCPKeepAlive no
  ServerAliveInterval 30
  ServerAliveCountMax 3
  ExitOnForwardFailure yes
  LocalForward 3307 127.0.0.1:3306

# Проброс соединения 192.168.110.2 <==R== 192.168.110.8
Host remote-forward-ssh-server
  HostName 192.168.110.8
  Port 2222
  User evgeniy
  IdentityFile C:/Users/Evgeniy/.ssh/tcp-forward-ssh-server
  TCPKeepAlive no
  ServerAliveInterval 30
  ServerAliveCountMax 3
  ExitOnForwardFailure yes
  RemoteForward 3306 127.0.0.1:3306

После этого скачиваем установщик Cygwin64 и запускаем установку. Обязательно выбираем для установки OpenSSH и autossh. Запускаем терминал Cygwin64 от имени администратора и выполняем команду:

$ cygrunsrv -I AutoSSH -p /bin/autossh -a "-M 0 -N -F C:/Users/Evgeniy/.ssh/config local-forward-ssh-server" \
> -e AUTOSSH_NTSERVICE=yes -e AUTOSSH_PATH=/bin/ssh

Справка по утилите cygrunsrv, которая добавляет службу

$ cygrunsrv --help
Usage: cygrunsrv [OPTION]...

Main options: Exactly one is required.

  -I, --install <svc_name>  Installes a new service named <svc_name>.
  -R, --remove <svc_name>   Removes a service named <svc_name>.
  -S, --start <svc_name>    Starts a service named <svc_name>.
  -E, --stop <svc_name>     Stops a service named <svc_name>.
  -Q, --query <svc_name>    Queries a service named <svc_name>.
  -L, --list [server]       Lists services that have been installed
                            with cygrunsrv.
  <svc_name> can be a local service or "server/svc_name" or "server\svc_name".

Required install options:
  -p, --path <app_path>     Application path which is run as a service.

Miscellaneous install options:
  -P, --crs-path <path>     Path to cygrunsrv. This is useful for testing or
                            when installing a service on a remote machine.
  -a, --args <args>         Optional string with command line options which
                            is given to the service application on startup.
  -c, --chdir <directory>   Optional directory which will be used as working
                            directory for the application.
  -e, --env <VAR=VALUE>     Optional environment strings which are added
                            to the environment when service is started.
                            You can add up to 255 environment strings using
                            the `--env' option.
                            Note: /bin is always added to $PATH to allow all
                            started applications to find cygwin DLLs.
  -d, --disp <display name> Optional string which contains the display name
                            of the service. Defaults to service name.
  -f, --desc <description>  Optional string which contains the service
                            description.
  -t, --type [auto|manual]  Optional start type of service. Defaults to `auto'.
  -u, --user <user name>    Optional user name to start service as.
                            Defaults to SYSTEM account.
  -w, --passwd <password>   Optional password for user. Only needed
                            if a user is given. If a user has an empty
                            password, enter `-w '. If a user is given but
                            no password, cygrunsrv will ask for a password
                            interactively.
  -s, --termsig <signal>    Optional signal to send to service application
                            when service is stopped.  <signal> can be a number
                            or a signal name such as HUP, INT, QUIT, etc.
                            Default is TERM.
  -z, --shutsig <signal>    Optional signal to send to service application
                            when shutdown has been initiated.  Default is the
                            same signal as defined as termination signal.
  -y, --dep <svc_name2>     Optional name of service that must be started
                            before this new service.  The --dep option may
                            be given up to 16 times, listing another dependent
                            service each time.
  -0, --stdin <file>        Optional input file used for stdin redirection.
                            Default is /dev/null.
  -1, --stdout <file>       Optional output file used for stdout redirection.
                            Default is /var/log/<svc_name>.log.
  -2, --stderr <file>       Optional output file used for stderr redirection.
                            Default is /var/log/<svc_name>.log.
  -x, --pidfile <file>      Optional path for .pid file written by application
                            after fork().
                            Default is that application must not fork().
  -n, --neverexits          Service should never exit by itself.
  -O, --preshutdown         Stop service application during system preshutdown.
  -o, --shutdown            Stop service application during system shutdown.
                            (Only one of --preshutdown and --shutdown is
                             accepted.  Preshutdown is preferred, but only
                             available since Windows Vista/Longhorn.  On earlier
                             OS versions it's silently converted to --shutdown).
  -i, --interactive         Allow service to interact with the desktop
                            (No effect since Windows Vista/Longhorn).
  -j, --nohide              Don't hide console window when service interacts
                            with desktop.

Informative output:
  -V, --verbose             When used with --query or --list, causes extra
  -h, --help                print this help, then exit.
  -v, --version             print cygrunsrv program version number, then exit.

Тут два важных момента:

  • В системе могут существовать две утилиты ssh: одна — из поставки Windows 10, а вторая — из поставки Cygwin64. Утилита autossh будет работать с ssh из поставки Cygwin64 — мы указываем это явно с помощью переменной окружения AUTOSSH_PATH.
  • Утилита ssh из состава Cygwin64 ищет файл конфигурации ~/.ssh/config не в директории C:/Users/Evgeniy/, а в директории C:/cygwin64/home/Evgeniy/. Мы указываем явно, какой файл конфигурации использовать. И с самом файле конфигурации задали полный путь к файлу ключа.

Дальше открываем список служб Windows, находим AutoSSH. Задаем пользователя, от которого будет запускаться служба и устанавливаем тип запуска Автоматический:

Удалить службу AutoSSH можно с помощью команды:

$ cygrunsrv --remove AutoSSH

Поиск: CLI • Linux • SSH • Systemd • Ubuntu • Конфигурация • Настройка • Сервер

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.