SSH — тот самый сервис, который правят «на живую» и чаще всего по удалёнке. Ошибка в sshd_config, неудачный перезапуск или конфликт порта — и вы внезапно без доступа к серверу. Ниже — практичный подход: валидируем конфигурацию (sshd -t), смотрим эффективные параметры (sshd -T), читаем логи через journalctl, проверяем фактически слушающие порты (ss -tlpn) и умеем делать быстрый rollback.
Перед изменениями: план «не потерять доступ»
Главное правило: не делайте рискованные изменения SSH в единственной сессии. Минимальный набор страховок:
Оставьте открытую текущую SSH-сессию до финальной проверки (не закрывайте терминал).
Откройте вторую параллельную сессию и держите её «чистой» (для проверки нового подключения).
Если меняете порт — сначала добавьте новый, проверьте вход на него, и только потом убирайте старый.
Фиксируйте исходное состояние: снимите бэкап конфига и диагностику до правок.
Снимок текущего состояния (2 минуты, но спасает)
Перед правками сделайте небольшой «сейф» — это ускорит откат и поможет сравнить «до/после».
sudo cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%F-%H%M%S)
sudo sshd -T | sed -n '1,120p'
sudo ss -tlpn | grep -E ':(22|2222)\b' || true
sudo systemctl status ssh --no-pager -l
Команда sshd -T показывает итоговую эффективную конфигурацию (с учётом Include/Match и дефолтов), а ss -tlpn — какие TCP-порты реально слушают процессы.
Как устроены конфиги SSH: sshd_config, Include и приоритеты
Классика — редактировать /etc/ssh/sshd_config. На современных дистрибутивах часто есть директория с фрагментами, например /etc/ssh/sshd_config.d/ (зависит от сборки OpenSSH и политики дистрибутива). Важно понимать: у OpenSSH нет «drop-in» в смысле systemd, но systemd может переопределять способ запуска сервиса (аргументы бинарника).
У вас есть два уровня, где можно влиять на поведение SSH:
Уровень OpenSSH: директивы в
sshd_config(и подключаемые include-файлы).Уровень systemd unit: команда запуска
sshdи её параметры через systemd drop-in.
Смысл systemd drop-in не в том, чтобы «заменить»
sshd_config, а в том, чтобы управляемо переопределить запуск сервиса: добавить флаги, временно переключить путь к конфигу, включить нужный режим работы или быстрее сделать откат.
Если вы ведёте инфраструктуру на отдельных серверах, удобно держать такие изменения и эксперименты на изолированных окружениях, например на VDS, чтобы не трогать боевые узлы без необходимости.

Проверка конфигурации до рестарта: sshd -t и sshd -T
Перед тем как применять изменения, проверьте синтаксис и «собираемость» конфигурации. Это самый дешёвый способ не уронить доступ.
Быстрый тест синтаксиса: sshd -t
sudo sshd -t
Если есть ошибка — команда вернёт ненулевой код и обычно напечатает причину. Делайте этот шаг после каждой правки sshd_config (или include-файла).
Посмотреть итоговую конфигурацию: sshd -T
sudo sshd -T | less
Полезно, когда параметр переопределяется где-то ещё или вы используете Match. Например, быстро убедиться, какие порты заданы в эффективной конфигурации:
sudo sshd -T | grep -i '^port '
systemd drop-in для ssh/sshd: переопределяем unit правильно
Systemd drop-in — это файл переопределений для unit’а в /etc/systemd/system/; пакетные файлы в /lib/systemd/system/ или /usr/lib/systemd/system/ вы не трогаете. Это «чистый» способ локальных изменений: при обновлениях пакетов ваши правки не затираются.
Посмотреть текущий unit и понять имя сервиса
В разных системах сервис называется ssh или sshd. Проверьте, какой есть:
systemctl status ssh --no-pager -l
systemctl status sshd --no-pager -l
Дальше используйте тот unit, который существует.
Создаём drop-in и переопределяем ExecStart
Откройте редактор drop-in (systemd сам создаст директорию):
sudo systemctl edit ssh
В systemd нельзя «дописать» кусок к ExecStart — его нужно переопределять целиком. Типовой приём: сначала сбросить список, затем задать новую команду запуска. Пример: заставим sshd явно использовать конкретный конфиг и работать в foreground (это стандартно для systemd):
[Service]
ExecStart=
ExecStart=/usr/sbin/sshd -D -f /etc/ssh/sshd_config
После сохранения примените изменения:
sudo systemctl daemon-reload
Проверьте, что drop-in применился:
systemctl cat ssh
Зачем это может понадобиться
Явно указать конфиг, если вы тестируете альтернативный файл и хотите понятный откат.
Временно добавить диагностические флаги на период расследования проблем.
Привести запуск к ожидаемому виду, если в кастомном образе unit сильно отличается от типового.
Проверяем, что порт слушается: ss -tlpn и что смотреть в выводе
После правок важно убедиться фактами: процесс поднялся, слушает нужный порт, слушает на нужном адресе (0.0.0.0/:: или конкретный IP), и это именно sshd.
Базовая проверка
sudo ss -tlpn | grep -E ':22\b'
Ключи:
-t— TCP-l— listening-p— показать процесс-n— не резолвить имена
Типичные проблемы по ss
Слушает только на localhost: изменили
ListenAddressили запускаете тестовый инстанс.Слушает только IPv6 (или только IPv4): проверьте адреса и то, как клиент выбирает семейство.
Процесс не sshd: порт занят другим сервисом, sshd не смог стартовать или запущен не тот unit.
Если параллельно вы готовите перенос/обновление сервера, полезно держать план на случай смены IP и проверок доступности; см. чеклист в статье про миграцию без простоя.
Диагностика запусков и ошибок: journalctl -u ssh
Когда sshd не поднимается после правок — ответ почти всегда уже есть в journald.
Смотрим последние ошибки юнита
sudo journalctl -u ssh -n 200 --no-pager
Если unit называется sshd:
sudo journalctl -u sshd -n 200 --no-pager
Следим за логами во время рестарта
sudo journalctl -u ssh -f
Фильтрация по ключевым словам
Иногда удобнее искать по журналу в целом (учтите, что это может быть шумно):
sudo journalctl --no-pager | grep -i 'sshd' | tail -n 200
Частые причины фейла старта
Синтаксическая ошибка в
sshd_config(ловитсяsshd -t).Неподдерживаемая директива (перенесли конфиг со старой версии OpenSSH).
Порт занят или нет прав на bind (в нестандартных схемах запуска).
Ошибки прав/владельца файлов ключей хоста в
/etc/ssh/.
Безопасный сценарий смены порта SSH без простоя
Если ваша задача — поменять порт, делайте это так, чтобы в момент перехода работали оба порта.
Шаг 1: добавьте второй порт
В sshd_config можно указать несколько Port:
Port 22
Port 2222
Далее проверяем и применяем:
sudo sshd -t
sudo systemctl reload ssh
Если reload не поддержан или вы сомневаетесь — используйте restart, но держите активную сессию открытой:
sudo systemctl restart ssh
Проверяем, что слушаются оба порта:
sudo ss -tlpn | grep -E ':(22|2222)\b'
И пробуем подключиться новым клиентом на новый порт (в отдельной сессии).
Шаг 2: когда убедились — убирайте старый
Удалите Port 22, оставьте только Port 2222, затем:
sudo sshd -t
sudo systemctl restart ssh
sudo ss -tlpn | grep -E ':2222\b'

Rollback: быстрый откат sshd_config и systemd drop-in
Rollback — это не «паника и ручная правка», а заранее подготовленный способ вернуть рабочее состояние. Разделим откаты на два уровня: откат sshd_config и откат systemd drop-in.
Откат sshd_config из бэкапа
Если после правок sshd не стартует или вы не можете зайти новым подключением, но старая сессия ещё жива:
ls -1 /etc/ssh/sshd_config.bak.* | tail -n 5
sudo cp -a /etc/ssh/sshd_config.bak.YYYY-MM-DD-HHMMSS /etc/ssh/sshd_config
sudo sshd -t
sudo systemctl restart ssh
После рестарта сразу проверьте:
sudo systemctl status ssh --no-pager -l
sudo ss -tlpn | grep -E ':22\b' || true
Откат systemd drop-in (возврат к пакетному unit)
Если проблема в drop-in (ошибка пути к бинарнику, неверный флаг, неправильный ExecStart), удалите override:
sudo systemctl revert ssh
sudo systemctl daemon-reload
sudo systemctl restart ssh
Затем проверьте логи и статус:
sudo journalctl -u ssh -n 100 --no-pager
sudo systemctl status ssh --no-pager -l
Если вы меняли путь к конфигу через drop-in
Если вы тестировали альтернативный конфиг (например, /etc/ssh/sshd_config.canary), rollback — это вернуть исходный -f в drop-in или выполнить systemctl revert. Перед рестартом проверяйте синтаксис именно того файла, который будет использован:
sudo sshd -t -f /etc/ssh/sshd_config.canary
Мини-чеклист после изменений
sshd -tпрошёл без ошибок.systemctl status sshпоказываетActive: active (running).ss -tlpnпоказывает слушающий порт и процесс sshd.Подключение в новой сессии работает (по новому порту/настройкам).
В
journalctl -u sshнет повторяющихся ошибок/перезапусков.
Практические заметки по безопасности (коротко, но важно)
Несколько вещей, которые чаще всего всплывают при аудите SSH и которые напрямую связаны с безопасными изменениями:
Не полагайтесь на смену порта как на защиту — это лишь снижение шума в логах.
Отключайте вход по паролю, если у вас везде ключи, и заранее проверьте доступ ключом.
Если используете
Match-блоки, учитывайте, чтоsshd -Tбез дополнительных параметров покажет «общую» картину; тестируйте сценарии так, чтобы не отрезать себе доступ политикой.
Итог
Связка «sshd_config + sshd -t/sshd -T + systemd drop-in + journalctl + ss -tlpn» закрывает большую часть рисков при администрировании SSH. Вы сначала валидируете конфиг, потом применяете изменения управляемо, сразу проверяете фактическое состояние порта и процесса, а rollback — это заранее подготовленная процедура, а не импровизация.
Если вы часто строите тестовые стенды и «канареечные» проверки перед изменениями на проде, проще всего выделять отдельную машину (или временный инстанс) и держать её под рукой; для этого подходят и виртуальный хостинг под мелкие задачи, и полноценный VDS под инфраструктурные эксперименты.


