создание постоянного SSH-тоннеля
May. 9th, 2018 02:27 pmНастройка SSH-тунеля
Есть сервер master с базой данных. Есть другой сервер slave, на котором надо настроить репликацию базы данных. И есть проблема: на сервере master закрыты все порты, кроме 22 (ssh).
Как одно из решений можно сделать тунель по SSH от сервера slave до сервера master, и внутри этого тунеля пересылать пакеты для репликации базы.
В самом простом случае ssh-тунель создается командой:
ssh -L 33060:localhost:3306 -i /home/user/.ssh/id_rsa -f -N user@slave.domain
где
- f - выполнять в фоне.
- i - путь до ключа, по которому будет происходить авторизация на сервере master.
- N - не выполнять никаких команд. Я так понимаю, если вдруг в сценариях logon на сервере master заданы
какие-то команды - выполнение их пропускается. - L - задаёт port forwarding. В данном случае, локальный порт 33060 на сервере slave мапится на локальный
порт 3306 на сервере master.
Используя только эту команду нужно следить за работоспособностью этого ssh-тунеля. Для автоматизации этого процесса есть утилита autossh, которая следит за тем, что тунель работает, и в противном слуае запускает его заново.
- M - задает порт мониторинга. По этим портам происходит проверка работоспособности тунеля. 0 отключит мониторинг, а autossh перезапустит ssh только при выходе из ssh.
- o - задание дополнительных опций.
- L - маппинг портов.
- i - путь к ключу, по которому будет происходить авторизация при подключении к серверу master.
- N - не выполнять команд при подключении.
- f - выполнять в фоне. Этот параметр не передается в ssh, а выполнение в фоне обеспечивает сама утилита autossh.
Но эту команду придется выполнять всякий раз после перезагрузки системы. Теперь надо настроить запуск этой команды при загрузке системы. Это можно сделать используя systemd.
- Создаем сервис. Для этого создаем файл
sudo vi /etc/systemd/system/autossh-mysql-tunnel.service
со следующим содержанием
Параметр -f можно не использовать, так как systemd не понимает этот параметр. - Перезагружаем systemd, чтобы сервис стал доступен:
sudo systemctl daemon-reload - Запускаем сервис и помещаем его в автозагрузку:
sudo systemctl start autossh-mysql-tunnel.service
sudo systemctl enable autossh-mysql-tunnel.service - Проверить статус можно с помощью команды:
sudo systemctl status autossh-mysql-tunnel
В результате, должны получить примерно такой вывод:● autossh-mysql-tunnel.service - AutoSSH tunnel service for MySQL on local port 33066 Loaded: loaded (/etc/systemd/system/autossh-mysql-tunnel.service; enabled; vendor preset: enabled) Active: active (running) since Thu 2019-02-28 16:10:49 MSK; 5h 2min ago Main PID: 1076 (autossh) Tasks: 2 Memory: 5.6M CPU: 5.528s CGroup: /system.slice/autossh-mysql-tunnel.service ├─1076 /usr/lib/autossh/autossh -M 0 -o ServerAliveInterval 30 -o ServerAliveCountMax 3 -L 33060:localhost:3306 -i /home/user/.ssh/id_rsa -N user@slave.domain └─1092 /usr/bin/ssh -o ServerAliveInterval 30 -o ServerAliveCountMax 3 -L 33060:localhost:3306 -i /home/user/.ssh/id_rsa -N user@slave.domain
Полезные ссылки:
- StackOverflow
- Creating a persistent ssh tunnel in Ubuntu
- Start AutoSSH on Boot
- Магия SSH
- SSH TUNNELLING FOR FUN AND PROFIT: AUTOSSH
Как настроить постоянно работающий SSH-туннель
Иногда в работе над проектами приходится прибегать к уловкам для организации сетевых доступов. В тех случаях, когда согласован SSH с поддержкой перенаправления портов, альтернативным способом организации доступа становится SSH-туннель.
Рассмотрим пример создания такого туннеля с поддержанием работы с помощью systemd.
Представим, что есть два сервера: сервер A (alice.example.com) с IP-адресом 10.0.0.1
и B (bob.example.com) с IP-адресом 10.0.0.2. Задача: пробросить порт 3128/tcp с
сервера B на сервер A для доступа к HTTP-прокси.
Настройка
Перед началом убедитесь, что Port Forwarding разрешён на сервере: включите опцию AllowTcpForwarding. Подробнее об использовании перенаправлении TCP-портов в справке sshd_config(5).
Далее заводим непривилегированного пользователя autossh на обоих серверах. Этот пользователь будет подключаться к серверу B, а там, в свою очередь, аутентифицироваться и перенаправлять порт.
sudo useradd -m -d /home/autossh/ -s /bin/bash autossh
Генерируем пару закрытого и открытого ключей (RSA 4096 бит) на сервере A. В 2019 году 4096 бит достаточно для обеспечения должного уровня безопасности, не опасаясь подбора ключа. Вероятно, если вы читаете эту заметку в будущем, увеличьте размер ключа до 8192 бит или выше. Парольную фразу указывать не нужно.
Копируем текст публичного ключа в файл /home/autossh/.ssh/authorized_keys вручную или с помощью ssh-copy-id(1) на сервер B. Это позволит пользователю autossh аутентифицироваться по нему при подключении.
Проверяем подключение к серверу B. Продолжаем, если всё в порядке.
ssh -i /home/autossh/.ssh/ident/ident@bob.example.com autossh@bob.example.com
Конфигурируем SSH-клиент на сервере A.
# vim /home/autossh/.ssh/config
Создаём systemd-юнит. Обратите внимание на символ @ в названии: после него может быть указан параметр для юнита. Конфигурация шаблонизируется спецификаторами, описанными в документации к systemd.unit.
# sudo vim /usr/lib/systemd/system/autossh@.service
Применяем изменения.
sudo systemctl daemon-reload
Запускаем юнит и добавляем в автозапуск. Имя параметра соответствует названию профиля SSH-клиента в $HOME/.ssh/config.
sudo systemctl start autossh@b-example-com-proxy.service
sudo systemctl enable autossh@b-example-com-proxy.service
Готово. Проверяем перенаправление портов на сервере A.
cat < /dev/null > /dev/tcp/10.0.0.1/3128 && echo OK || echo NOK
Отладить подключение можно либо из-под пользователя autossh, либо добавив -vvv в systemd-юнит. Приведённое выше работает и для LocalForward для перенаправления порта с удалённого сервера на локальный. Легко комбинировать с и другими возможностями SSH, когда в цепочке несколько узлов.
https://github.com/aktos-io/link-with-server
Создание SSH-туннеля. Часть третья
SSH-туннели — пробрасываем порт