Конфиг ssh очень полезная и удобная штука. Пользуюсь им давно, но недавно открыл ещё несколько замечательных возможностей. Решил поделиться парой полезных фич и рассказать об одном маленьком лайфхаке.
Шаринг соединений
Часто бывает необходимо по работе держать много консолей с ssh на один сервер. Для упрощения такой работы (с точки зрения компьютера) в OpenSSH есть возможность шарить соединения. Т.е. если вы зашли на сервер, то в системе создается ControlSocket и все последующие соединения на этот сервер будут использовать уже созданный сокет, а не создавать новое подключение. И если при первом соединении сервер спрашивает у вас пароль, то при повторном использовании уже сокета авторизация не потребуется.
Для настройки Connection sharing необходимо добавить следующие строчки в начало конфига ssh:
ControlMaster auto
ControlPath /tmp/ssh_%h_%p_%r
Проброс соединений через сервер
Другая не менее полезная штука - это возможность настроить соединение через сервер. Т.е. вместо двух команд: ssh server1
и потом уже оттуда ssh server2
, можно сразу в конфиге всё прописать и ходить одной командой.
Выглядеть такой конфиг будет примерно так:
Host server2
HostName server2.domain.org
ProxyCommand ssh -W %h:%p -C server1
Тут стоит пояснить, что ssh подставит вместо %h
хост, а вместо %p
порт.
Но и это ещё не всё. Помимо это ssh понимает паттерны внутри своего конфига. Приведу пример:
Host db*
ProxyCommand ssh -W %h:%p -C gateway
Теперь мы можем одной командой, скажем ssh db2.domain.org
попасть на сервер пробросив соединение через другой.
Этот метод в сочетании с шарингом соединений даёт мощный инструмент.
Проброс соединений для серверов с похожими именами
А теперь о проблеме с которой я столкнулся и “героически” решил.
ПРоблема была в том, что есть два набора серверов с одинаковыми именами, пусть для примера это будут db1 db2 dbN, находящихся за разными серверами, через которые на них надо ходить, пусть это будет gate1 и gate2. Предыдущий пример с использованием паттернов покрывает задачу лишь частично. Можно, конечно, выкрутиться используя паттерны с доменным именем, но в таком случае надо набирать полное доменное имя сервера, хотя с гейта на него можно попасть по короткому имени без домена.
Решить эту проблему удалось с помощью использования факта, что ProxyCommand
интерпретируется bash’ем =)
В итоге конфиг выглядит приблизительно так:
Host db*.dc1
ProxyCommand ssh -W $(echo %h| cut -d. -f1):%p -C gate1
Host db*.dc2
ProxyCommand ssh -W $(echo %h| cut -d. -f1):%p -C gate2
Т.е. в консоле мы вводим ssh db5.dc2
, данный сервер матчится со вторым паттерном, но пре передачи имени хоста в прокси-команду ненужная часть домена отбрасывается.
Больше о конфиге ssh можно узнать из документации: ssh_config