В разное время показывал фичи SSH разным людям, и неожиданно давние пользователя бывали удивлены, что вот и так ещё можно. Я далёк от полной нирваны, например, ничего не знаю про сертификаты и PKCS#11 (не было повода пощупать), но решил всё-таки сделать карту таких объяснятельных моментов, потому что вдруг кто-то в шаге от чего-то полезного и она поможет этот шаг сделать. Постараюсь отсортировать от банального к экзотическому, но строгости не обещаю (объективности уж точно не будет). Группировка по смежности тем отсутствует, поскольку она противоречит сортировке.
Опираюсь на конкретную реализацию клиента и сервера, а именно OpenSSH, но многие вещи для него неспецифичны или имеют аналоги. Итак:
- конфиги: сервер настраивается через /etc/ssh/sshd_config, клиент настраивается общесистемно через /etc/ssh/ssh_config, индивидуально через ~/.ssh/config. Командно-строчные опции клиента обычно имеют аналог в виде опций ~/.ssh/config. По ssh_config, sshd_config есть отдельные man-страницы. Самая пушка: в конфиге клиента ~/.ssh/config можно настраивать конкретные подключения или группы подключений (директивы HostName, Match). То есть вы ему в ~/.ssh/config рассказываете, что подключаться к kitty надо через один прокси, две страны и три файрволла, а потом в командной строке просто "ssh kitty" и клиент цепляет все эти настройки
- авторизация по ключам: если вы это ещё не освоили, поверьте, это нестрашно и удобно. См. команды ssh-keygen, ssh-copy-id. Для некоторых применений авторизация по ключам прямо обязательна. Если вы дошли в своём отрицании ключей до использования sshpass или expect, то вы идёте неправильным путём. Если не дошли, то забудьте упоминание sshpass, я эту штуку вам не рекламировал. Если у вас "не заработало", то дело скорее всего в правах на ~/.ssh/authorized_keys на серверной машине (права СЛИШКОМ ПЕРМИССИВНЫЕ на ~/.ssh или на сам файл). Чтоб заработало, пусть лучше ssh-copy-id сразу делает как правильно.
- хранение ключей в агенте ssh-agent: не факт, что это вам надо, но можно словить некоторое повышение безопасности и/или удобства. Если вы дошли до копирования закрытых ключей на чужие машины, вы идёте неправильным путём и вам нужен агент и agent forwarding. См. команду ssh-add, опции ssh -A, ForwardAgent.
- таскание сетевых портов из удалённой на локальную сторону (local forwarding), из локальной на удалённую (remote forwarding). Опции клиента -L, -R, -D, LocalForward, RemoteForward, DynamicForward. "Как мне сходить домой и открыть в браузере настройки моего Wi-Fi роутера", "как мне сходить в свободный мир и наслаждаться в браузере свободным интернетом", вот это вот всё. Обратите внимание, что -R может высунуть наружу socks5-прокси к вашим локальным ресурсам, это когда вы просто не указываете локальный Host:Port. То есть -L, -D отдельные опции, а в -R реализована комбинация.
- опция клиента -N дабы не пытаться открывать командную сессию когда не нужно, опция -f для ухода клиента в фон. Помогают автоматизированной прокладке туннелей.
- опция клиента ProxyCommand для коннекта изнутри огороженного окружения с помощью netcat.openbsd или какого-либо аналога. Как выходить наружу через tor, как выходить через https proxy с поддержкой connect, и так далее.
- опция клиента -J, ProxyJump для вылезания на хосты через другие хосты. Вот я попал на свою машину на работе, а как мне попасть на другие машины. См. также сервис https://ssh-j.com, о котором я недавно рассказывал.
- опции клиента ControlMaster, ControlPath, ControlPersist: можно держать одного клиента присоединённым (в том числе в фоне) и чтобы другие запуски клиентов запрашивали через него новые shell-сессии, новый forwarding и всякое такое -- то есть идея в том, что на каждый запуск ssh/scp/rsync переиспользуется существующее соединение, а не создаётся новое. Помогает против тормозов на этапе соединения. Может создавать неудобства и неожиданности в сочетании с форвардингом портов. Может создавать тормоза из-за отсутствия распараллеливания в случае с единым master connection.
- "настоящий VPN" через tun/tap устройства, может быть как на уровне L2(tap), так и на уровне L3(tun). Надо быть немножко сетевым джедаем (ip tuntap) и в принципе иметь рута на обоих концах (для установления туннеля рут не нужен, если ownership туннеля назначен через ip tuntap не-руту). Опции клиента -w, Tunnel, TunnelDevice, опция сервера PermitTunnel. С помощью brctl и такой-то матери можно даже сбриджить две локальных сети по обе стороны ssh connection.
- проверка живости соединения сервером (sshd_config: ClientAliveInterval, ClientAliveCountMax) или клиентом (ssh_config: ServerAliveInterval, ServerAliveCountMax). Помогает в ситуациях "у меня конец туннеля с remote forwarding отвалился, а сервер этого не осознал и порт держит занятым, поэтому туннель не переподнимается", "у меня клиент туннеля не перезапускается, потому что не осознал, что подключение к серверу повисло".
- терминальные мультиплексоры (tmux или screen) на стороне сервера: помогают в ситуации "запустил длинную задачу на удалённой стороне, подключение умерло и задача прибилась". Плохо дружат с X11 forwarding и Agent forwarding. Способствуют прокрастинации вида "я не буду для этой байды писать systemd-юнит, просто запущу её в tmux".
- опции для конкретного ключа в ~/.ssh/authorized-keys: позволяют в частности ограничить, что с этим ключом вообще можно делать. Можно пускать друзей наслаждаться свободным интернетом, не давая им при этом shell. Но обратите внимание: если у вас security assumption "на loopback-интерфейс чужие не ходят", то этот assumption очень легко может стать ошибочным из-за forwarding. Кстати, здесь же можно указать срок действия ключа.
- sshfs: утилита, чтобы монтировать (через fuse) поддеревья удалённых файловых систем на локальную машину. Из полезных опций sshfs: -o reconnect,transform_symlinks.
- альтернативные агенты: gnupg-agent умеет выступать в роли ssh-agent; есть также trezor-agent для использования соответствующего криптокошелька в качестве ключа. Я в целом это всё не котирую.
- escape char для клиента, по умолчанию "тильда ~", опция EscapeChar. Будучи введённым после символа новой строки, позволяет поуправлять клиентом (например, форсированно отключиться через ~., или добавить/убрать форвардинг портов). Справочка по доступным командам выдаётся через ~?. Обычно знакомство с этой фичей начинается с вопроса "кто портит мои тильды".
- настройка сервера GatewayPorts: позволяет делать remote forwarding на сервер, слушая не только loopback interface, а какой захочешь.
- всякие разные штуки, работающие через ssh: rsync (он так в основном и используется), git (он так умеет помимо прочего), virt-manager (будь проклят тот день...), может ещё кого забыл.
- Exclave для Андроида (он есть в F-Droid, если что) -- антицензурный прокси-клиент, одна из возможностей которого -- ходить через туннели по SSH. Можно
грабить корованыстроить цепочки соединений через несколько шагов. dyhkwong@github это голова.
Возможно, буду сюда что-то дописывать, сам жанр странненький, frequently asked questions that nobody asked. У кого есть feedback насчёт полезности или бесполезности, не сдерживайте себя.
Comments (5)
вот интересно, что идея ssh форвардинга/проксиинга/прочего туннелирования всегда казалась мне красивой и простой, но на практике мне почему-то проще поднять wireguard, хотя он и требует больше колдуства. тем более, что домашней сетке я не хочу открывать ssh даже на нестандартном порте, в него всякая сволочь сразу стучаться начинает.
зато screen очень полезная штука. только вот пригождается раз в года полтора и приходится заново гуглить флаги 😁
WG отличный, но его цензурят в РФ, не то чтобы совсем не работало, но как-то внезапно и некстати перестаёт.
а ну тогда да, только ssh или https прокси
Над wg ещё надстроены tailscale и zerotier, оба проекта интересные
Штука очень полезная. Самое сложное со всякими тулзами и библиотеками - это не найти, как что-то сделать, а узнать, что это вообще можно сделать.