SSH config: один файл вместо рутины

Один файл, который убирает лишнюю рутину. Часть 1

Каждый день вы подключаетесь к серверам. Каждый раз заново вводите IP, имя пользователя, порт и путь к ключу. Это работает, но забирает время и отвлекает.

Файл ~/.ssh/config снимает эту проблему. В нём можно один раз описать все параметры подключения и затем обращаться к серверу по короткому имени. Но на этом возможности не заканчиваются. Через тот же файл настраиваются jump-хосты, автоматический выбор ключей, повторное использование соединений и многое другое.

В первой части разберём базу: алиасы, шаблоны и ProxyJump.

Как это устроено

~/.ssh/config читается при каждом вызове ssh, scp, sftp или rsync. Файл состоит из блоков Host, и каждый из них задаёт параметры для конкретного хоста либо для группы хостов по шаблону.

Если файла ещё нет, создайте его:

mkdir -p ~/.ssh
touch ~/.ssh/config
chmod 600 ~/.ssh/config

Структура простая:

Host staging
    HostName 203.0.113.50
    User ubuntu
    Port 2222
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes

Теперь вместо длинной команды с множеством флагов достаточно написать:

ssh staging

То же самое работает с scp и rsync:

scp staging:/var/log/app.log ./
rsync -avz staging:/var/www/html/ ./backup/

Шаблоны и подстановки

Блок Host поддерживает wildcards. Например, чтобы задать настройки сразу для всех продакшн-серверов:

Host *.prod.example.com
    User ec2-user
    IdentityFile ~/.ssh/id_ed25519_prod
    ServerAliveInterval 60

Символ ? используется как подстановка одного символа. Host web-? совпадёт с web-1, web-a, но не с web-10.

Можно перечислить несколько имён в одном блоке:

Host web db cache
    User ubuntu
    IdentityFile ~/.ssh/id_ed25519_work

А через ! исключить конкретный хост:

Host * !bastion.prod.example.com
    ServerAliveInterval 30

Блок Host * применяется ко всем подключениям и удобен для общих настроек. Важный нюанс: SSH читает файл сверху вниз и для каждой директивы берёт первое подходящее значение. Поэтому более конкретные блоки нужно ставить выше общих.

ProxyJump. Прозрачный доступ через bastion

Продакшн-серверы обычно закрыты для прямого подключения. Доступ к ним идёт через bastion-хост. Без конфига это два шага: сначала SSH на bastion, затем уже с него на целевой сервер. С конфигом всё становится прозрачно:

Host bastion
    HostName bastion.prod.example.com
    User ubuntu
    IdentityFile ~/.ssh/id_ed25519_prod

Host *.prod.internal
    User ubuntu
    IdentityFile ~/.ssh/id_ed25519_prod
    ProxyJump bastion

Теперь ssh db.prod.internal автоматически пойдёт через bastion. Это работает и с scp, и с rsync.

Если нужна цепочка из нескольких jump-хостов, перечислите их через запятую:

Host deep.internal
    ProxyJump bastion.example.com,internal-gateway.example.com

В старых конфигурациях можно встретить ProxyCommand ssh -W %h:%p bastion.example.com. Он делает то же самое, но ProxyJump короче и понятнее. Для новых конфигов лучше использовать его.