SSH вглубь: ключи, конфиг, туннели, rsync
Базовый ssh user@host с паролем — только начало. Настоящая сила SSH — в ключах, конфиге, туннелях и быстрой синхронизации файлов. Разберём это слой за слоем.
SSH-ключи — пара из приватного и публичного ключа: публичный кладётся на сервер, приватный остаётся у вас. Аутентификация по ключу безопаснее пароля и позволяет заходить без ввода пароля каждый раз.
Зачем это на практике
Пароли можно подобрать, и серверы в интернете круглосуточно перебирают их по SSH. Ключи решают эту проблему: подобрать 4096-битный ключ невозможно. А ~/.ssh/config, туннели и rsync превращают SSH из «зайти на сервер» в полноценный инструмент: пробросить порт к закрытой базе данных, пройти через бастион-хост, синхронизировать каталог за секунды. Это ежедневная рутина любого DevOps.
Генерация ключей: ssh-keygen и ssh-copy-id
Создаём современную пару ключей на алгоритме Ed25519 (короче и быстрее RSA при той же стойкости):
ssh-keygen -t ed25519 -C "ernest@laptop" # создать пару ключей
# приватный: ~/.ssh/id_ed25519 (никому не отдавать!)
# публичный: ~/.ssh/id_ed25519.pub (его кладём на серверы)
На вопрос про passphrase лучше задать пароль — это шифрует приватный ключ на диске. Теперь скопируем публичный ключ на сервер одной командой:
ssh-copy-id [email protected] # добавит .pub в ~/.ssh/authorized_keys
После этого ssh [email protected] пустит вас по ключу, без пароля. Файл ~/.ssh/authorized_keys на сервере хранит список публичных ключей, которым разрешён вход.
Файл ~/.ssh/config: алиасы и настройки
~/.ssh/config — личный конфиг SSH-клиента: задаёт короткие имена (Host) и параметры подключения, чтобы не печатать длинные команды каждый раз.
Вместо ssh -i ~/.ssh/work_key -p 2222 [email protected] прописываем один раз:
cat ~/.ssh/config
Host prod
HostName 10.20.30.40
User deploy
Port 2222
IdentityFile ~/.ssh/work_key
Host *.internal
User admin
ProxyJump bastion
Теперь достаточно ssh prod — клиент сам подставит хост, пользователя, порт и ключ. Шаблоны вроде *.internal применяют настройки к группе хостов. Этот файл — основа удобной работы: scp, rsync и git тоже читают его.
Туннели: проброс портов -L и -R
Туннель заворачивает TCP-трафик внутрь зашифрованного SSH-соединения. Два направления:
Локальный проброс -L (доступ к закрытому сервису)
База данных слушает только на 127.0.0.1:5432 сервера и снаружи закрыта. Пробросим её к себе на ноутбук:
ssh -L 5432:localhost:5432 prod
# теперь localhost:5432 на ноутбуке == 127.0.0.1:5432 на сервере prod
Читается как «локальный порт 5432 → через prod → на его localhost:5432». Подключаете клиент БД к localhost:5432 — и работаете с удалённой базой через шифрованный канал.
Удалённый проброс -R (показать наружу свой сервис)
ssh -R 8080:localhost:3000 prod
# порт 8080 на сервере prod пробрасывается на localhost:3000 у вас
Полезно, чтобы временно показать коллегам локально запущенное приложение через публичный сервер.
ProxyJump: проход через бастион
Доступ к внутренним серверам часто только через один шлюз (bastion). Раньше для этого городили ProxyCommand, теперь есть лаконичный -J:
ssh -J bastion.example.com app-01.internal # прыжок через бастион
# или в ~/.ssh/config: ProxyJump bastion.example.com
Копирование файлов: scp vs rsync
Скопировать файл по SSH можно через scp — простой, но «тупой»: всегда копирует целиком. rsync умнее — передаёт только изменившиеся части и умеет докачивать:
scp report.pdf prod:/var/www/ # один файл на сервер
scp -r ./dist prod:/var/www/app/ # каталог рекурсивно
rsync -avz ./dist/ prod:/var/www/app/ # синхронизация: только различия
rsync -avz --delete ./dist/ prod:/var/www/app/ # + удалить лишнее на той стороне
Флаги rsync: -a архивный режим (права, время, симлинки), -v подробно, -z сжатие в пути. Для повторной выкладки каталога rsync в разы быстрее scp, потому что не гоняет неизменившиеся файлы.
ssh-agent: помнить ключ один раз
Чтобы не вводить passphrase ключа при каждом подключении, его держит в памяти ssh-agent:
eval "$(ssh-agent -s)" # запустить агента
ssh-add ~/.ssh/id_ed25519 # добавить ключ (passphrase спросят один раз)
ssh-add -l # список загруженных ключей
Опция ForwardAgent yes в конфиге позволяет «протащить» агента на сервер, чтобы оттуда ходить дальше по тем же ключам — удобно, но включайте только для доверенных хостов.
Как это работает под капотом
Аутентификация по ключу — это асимметричная криптография: сервер шлёт случайный вызов, клиент подписывает его приватным ключом, сервер проверяет подпись публичным ключом из authorized_keys. Приватный ключ при этом никогда не покидает вашу машину. Туннель -L/-R работает так: ssh открывает локальный слушающий сокет и каждый пришедший на него байт заворачивает в уже установленное шифрованное SSH-соединение, разворачивая на другом конце. ProxyJump устанавливает вложенное SSH-соединение: сначала к бастиону, а внутри него — к целевому хосту, так что трафик к цели шифруется дважды. rsync поверх SSH запускает свою копию на той стороне и обменивается контрольными суммами блоков, передавая только то, что реально различается.
Частые ошибки
- Слишком открытые права на ключи и каталог
.ssh. SSH откажется работать, если~/.sshдоступен другим: нужноchmod 700 ~/.sshиchmod 600 ~/.ssh/id_ed25519. - Скопировать или потерять приватный ключ. Публичный (
.pub) раздаём, приватный — никогда; его утечка = доступ ко всем серверам с этим ключом. - Забыть
/в конце путиrsync.rsync src/ dst/иrsync src dst/ведут себя по-разному: первый копирует содержимое, второй — сам каталог внутрь. Источник классических сюрпризов. - Путать
-Lи-R.-Lтянет удалённый сервис к себе,-Rвыставляет ваш сервис на удалённой стороне. Перепутали направление — туннель «не работает».
Итоги
- Ключи:
ssh-keygen -t ed25519+ssh-copy-id; приватный ключ держим у себя, публичный кладём вauthorized_keysсервера. ~/.ssh/configзадаёт алиасы (Host) с хостом, портом, ключом иProxyJump— короткийssh prodвместо длинной команды.- Туннели:
-Lтянет закрытый удалённый порт к себе,-Rвыставляет локальный сервис наружу;-Jходит через бастион. rsync -avzбыстрееscpдля повторной выкладки (шлёт только различия);ssh-agent+ssh-addизбавляют от повторного ввода passphrase.