← все записи

~/.ssh/config - топ за свои бабки

Предположим, у тебя есть зоопарк на десяток серверов и каждый раз ты колотишь в терминал что-то типа ssh -p 22 user@176.111.222.333, предварительно скопировав это из какого-нибудь файлика - у меня для тебя новость. Так делать не надо. Вообще. Ну или иногда, если прям очень приперло.

Есть такая штука ~/.ssh/config. Замечательный файл, в который один раз записываешь все свои сервера с нужными параметрами подключения, а потом ходишь к ним вот так ssh user@hostname. Звучит банально, но оказывается многие про это не ведают, потому этот пост я и написал.

Давай покажу кусок своего реального конфига и пройдусь по нему построчно. А ты уже решай, что из него можно вытащить полезного.

Host *
   ServerAliveInterval 60
   ServerAliveCountMax 3
   TCPKeepAlive yes

Host dz-net
   Hostname 176.222.222.222
   User dz
   Port 22
   LocalForward 8443 127.0.0.1:8443
   LocalForward 8006 127.0.0.1:8006
   LocalForward 2053 127.0.0.1:2053
   LocalForward 3000 127.0.0.1:3000

Host dz-net-irunode
   Hostname 91.222.222.222
   User dz
   Port 22
   LocalForward 2054 127.0.0.1:2053

Host lf
   Hostname 176.222.222.222
   User lf-sys
   Port 22

Host lf-sys-node
   #Hostname 176.222.222.222
   Hostname 10.15.15.100
   User lf-sys
   Port 22
   ProxyJump lf
   IdentityFile ~/.ssh/id_rsa.lf-sys-node

Host dz-lab-local
   Hostname 192.168.000.000
   User dz
   Port 22

Host dz-lab
   Hostname 212.222.222.222
   User dz
   Port 5022

Блок Host * - настройки для всех соединений сразу.

Звёздочка означает применить параметры ко всем хостам, к которым ты подключаешься. Удобно. Вообще, эти строки можно прописать в /etc/ssh/ssh_config.d/, но это system-wide файл, и закинутые тобой параметры распространятся на всех юзеров системы, а ~/.ssh/config только на пользователя, в чьей домашней папке он лежит. Как тебе лучше решай сам.

ServerAliveInterval 60 - раз в 60 секунд клиент отправляет на сервер маленький служебный пакет. Просто чтобы соединение не считалось простаивающим. Если этого не делать, любой роутер по дороге через несколько минут молчания может решить, что соединение мёртвое, и прибить его. Знакомая боль: открыл ssh, начал что-то делать, отвлёкся на чай/кофе/фаянсовый_трон, вернулся - а терминал не алё.

ServerAliveCountMax 3 - сколько таких пакетов может остаться без ответа, прежде чем клиент решит "ну всё, прощаемся" и отвалится. У меня три пакета по 60 секунд - то есть три минуты тишины и разрыв. Можно поставить больше, если у тебя связь так себе.

TCPKeepAlive yes вроде то же самое что ServerAliveInterval, но на уровне TCP.

В сумме эти три строчки делают одну простую вещь: ssh-сессия не отваливается. После того как я это прописал, я забыл, что такое протухшая сессия.

Блок Host dz-net - алиас вместо IP.

Вот тут самый сахар. Помнить кучу IP адресов не очень приятно, гораздо приятней помнить понятные имена, которые в свою очередь примаплены к этим IP.

Теперь вместо ssh -p 22 dz@176.222.222.222 я пишу:

ssh dz-net

И всё. Имя пользователя, IP, порт - берутся из конфига. Память освобождается под более полезные вещи, например под то, что бы не забыть как выйти из vim. Ух как классно пошутил.

Маленький, но приятный бонус - табуляция. После ssh нажимаешь Tab, и шелл подставляет имена хостов из конфига. Дальше, если хост короткий, можно вообще писать первые две буквы и добивать табом.

Кстати, имена хостов - это место, где стоит подумать заранее. Как правило формат "проект-роль", но у меня основной хост имеет просто имя проекта, а остальные хосты этого проекта имеют маску "проект-роль": например dz-net и dz-net-irunode, или lf и lf-sys-node. Когда пара серверов в целом пофиг как ты их обзовешь. А вот когда 30 - лучше заморочься.

Блок с LocalForward - автоматический проброс портов.

Это та фича, ради которой стоит читать всё остальное. Смотри, что делает эта пачка строк:

LocalForward 8443 127.0.0.1:8443
LocalForward 8006 127.0.0.1:8006
LocalForward 2053 127.0.0.1:2053
LocalForward 3000 127.0.0.1:3000

Когда я подключаюсь к dz-net, ssh автоматически пробрасывает с моей локальной машины на удалённый сервер четыре порта. Простыми словами: на сервере по адресу 127.0.0.1:8006 крутится морда Proxmox, на 127.0.0.1:8443 web сервер VSCode, на 127.0.0.1:3000 - Grafana, на 127.0.0.1:2053 наверное уже сам знаешь что. Всё это работает на localhost'е сервера, наружу не торчит, и мне так спокойнее спится.

Вообще, конечно лучше поставить на 443 порт nginx, подкинуть tls и разруливать это дело по поддоменам - но мне лень, так у меня другие проекты работают. Тут просто и быстро, после ssh dz-net я на своей машине открываю http://localhost:8006 - и вижу веб-морду Proxmox, которая физически крутится за тысячу километров от меня.

Без конфига это выглядело бы так:

ssh -L 8443:127.0.0.1:8443 -L 8006:127.0.0.1:8006 -L 2053:127.0.0.1:2053 -L 3000:127.0.0.1:3000 dz@176.222.222.222

Каждый раз. Пездес гемморой.

Что ещё полезного сюда можно добавить.

Пара моментов, не претендую на истину, но глянь - может зайти.

IdentityFile - тут можно указать, какой именно ключ использовать для конкретного хоста. Если у тебя один ключ на всё - оно тебе не надо. Если для работы один, для пет-проектов другой, для какого-нибудь GitLab третий - норм штука.

Host work-server
   Hostname 1.2.3.4
   User me
   IdentityFile ~/.ssh/work_rsa

ProxyJump (он же -J) - классная фишка для серверов, до которых нет прямого доступа. Например, у вас есть бастион (jump-хост), и через него надо ходить на внутренние машины. В моем случае, есть сервер на котором нарезана пачка виртуалок, которые из вне не доступны по ряду причин. Раньше не знал про эту штуку и ходил таким способом: на бастионе сделал отдельного пользователя lf-sys, в ~/.ssh/config локальной тачки и в /etc/ssh/sshd_config бастиона добавил блоки:

Host lf-sys-node
   Hostname 176.222.222.222
   User lf-sys
   Port 22

И вот такой блок залетел в самый низ файлика /etc/ssh/sshd_config:

Match User lf-sys
   X11Forwarding no
   AllowTcpForwarding yes
   PermitTTY yes
   AllowAgentForwarding yes
   ForceCommand ssh lf-sys@10.15.15.100 

И так, что тут произошло? Когда на ноутбуке я ввел команду ssh lf-sys-node ssh пошел смотреть мой файл ~/.ssh/config, нашел блок с алиасом lf-sys-node и начал подключаться к удаленной машине по указаному в этом блоке адресу. Удаленная машина получив запрос на подключение проверила ключи, дала добро. После создания сессии сработала строка Match User lf-sys, потом ForceCommand ssh lf-sys@10.15.15.100 и тебя пробросило на виртуалочку. Прикольно, да? Область применения параметра ForceCommand ограничена исключительно твоими фантазиями.

Ну а потом, почитав умных дядек я прозрел и понял что надо переделать на фен-шуй:

Host lf-sys-node
   Hostname 10.15.15.100
   User lf-sys
   Port 22
   ProxyJump lf (тут указываем хост, через который прокинется сессия)
   IdentityFile ~/.ssh/id_rsa.lf-sys-node (если у тебя спец ключик для доступа)

Теперь ssh lf-sys-node сначала молча зайдёт на lf, а оттуда на 10.15.15.100. При этом, обрати внимание, для хоста lf будет использоваться ключ по умолчанию, а вот для хоста lf-sys-node уже специальный. В итоге получилось просто и красиво, и если что-то понадобится поправить - весь блок подключения в одном месте. На удаленной машине можно убрать добавленные строки в /etc/ssh/sshd_config.

Как итог.

~/.ssh/config - это не что-то мега продвинутое для супер профи. Это базовая база. Десять минут на настройку - и каждый день ты экономишь время, нервы и вот эти микроскопические порции раздражения, из которых складывается твое ощущение взаимодействия с такой прекрасной штукой, как консолька. Люблю ее :*

В следующем посте накидаю свою базовую базу по первоначальной настройке серверов после нарезки, и быть может закину примеры и ссыль на репозиторий с небольшой автоматизацией этой однотипной и скучной задачи. Да, и пиши комментарии.

👍 0 👎 0

Комментарии (0)

← все записи