MAATRIX / Блог / Ошиблись в правиле firewall и потеряли доступ к серверу

Ошиблись в правиле firewall и потеряли доступ к серверу

MAATRIX

Вы меняете одно правило firewall, нажимаете Enter — и SSH-сессия молча умирает. Новая не устанавливается вообще. Знакомая ситуация: iptables, nftables или ufw применили политику раньше, чем вы успели разрешить себе же вход. Разберём, почему так происходит, что делать прямо сейчас и как настроить процесс, чтобы больше никогда не остаться снаружи собственного сервера.

Момент, когда SSH обрывается

Обычно всё выглядит одинаково. Вы правите правила firewall — добавляете новую политику, включаете UFW, применяете набор правил nftables — и через секунду терминал зависает. Курсор мигает, но ответа нет. Вы открываете новое окно, пробуете подключиться заново — ssh: connect to host X.X.X.X port 22: Connection refused или просто таймаут без единого пакета в ответ.

Это не глюк сети и не временная задержка. Это значит, что правило сработало ровно так, как вы его написали, только написали вы его неправильно: политика по умолчанию DROP встала в силу до того, как разрешающее правило для порта 22 успело попасть в таблицу, либо порядок правил оказался таким, что блокирующее совпадает раньше разрешающего.

Типичные сценарии, которые приводят к этому:

  • iptables -P INPUT DROP выполнен до iptables -A INPUT -p tcp --dport 22 -j ACCEPT — окно между двумя командами уже отрезает вас, если в этот момент прилетел новый пакет или порвалось состояние соединения в conntrack.
  • iptables -F (flush) выполнен при политике DROP — вы стёрли все разрешающие правила, а политика по умолчанию осталась закрытой.
  • В nftables правило drop добавлено в цепочку раньше правила tcp dport 22 accept — для нетфильтра, как и для iptables, работает принцип «первое совпавшее правило побеждает», порядок построчный.
  • ufw enable выполнен без предварительного ufw allow OpenSSH (или ufw allow 22/tcp), при этом дефолтная политика ufw default deny incoming уже стоит.
  • Правило ограничило доступ по конкретному интерфейсу или подсети, а вы подключаетесь с другого IP, чем предполагали (например, провайдер сменил ваш внешний адрес).

Проверить, какое правило виновато, вы уже не сможете обычным способом — сама причина в том, что канал для проверки исчез вместе с доступом.

Почему так легко отрезать самого себя

Firewall — это не система с проверкой «не заблокирую ли я самого себя», а исполнитель списка инструкций построчно и без рассуждений. Здесь совпадают три особенности, которые вместе создают ловушку.

Во-первых, порядок правил критичен. И в iptables, и в nftables пакет проходит цепочку сверху вниз, и применяется первое совпавшее правило — все последующие уже не имеют значения. Если правило DROP для всего трафика стоит раньше, чем ACCEPT для SSH, до второго правила пакет просто не доходит.

Во-вторых, политика по умолчанию (default policy) применяется мгновенно и безусловно, а не «после того как вы точно ничего не сломали». iptables -P INPUT DROP — это не отложенное действие и не тестовый режим, это немедленная смена поведения для всех пакетов, которые не совпали ни с одним explicit-правилом выше.

В-третьих, состояние уже открытого соединения не гарантирует, что оно останется живым. Если в правилах нет -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT, а сработала политика DROP, новые пакеты той же TCP-сессии (например, ретрансмиты или keepalive) тоже начнут отбрасываться — активная сессия оборвётся не сразу, а в течение нескольких секунд или минут, что создаёт ложное ощущение, будто «пока всё работает, значит правило безопасное».

Отдельно стоит перепутанный порядок команд в скриптах автоматизации (Ansible, Terraform-провижининг, cloud-init): если плейбук сначала выполняет ufw --force enable, а разрешающее правило для SSH идёт следующим шагом, любой сбой или задержка между шагами оставляет сервер закрытым на неопределённое время.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Первым делом: не паникуйте и определите тип блокировки

Прежде чем бросаться в консоль хостера, за 10 секунд стоит понять, с чем вы имеете дело — это сэкономит время на восстановлении.

  • Если вы точно знаете, какую команду выполнили последней — вспомните её. Это почти всегда даёт прямой ответ, что откатывать.
  • Если использовали ufw — почти наверняка причина в порядке enable/allow или в удалении правила для SSH.
  • Если правили iptables/nftables вручную — ищите, не встала ли политика DROP/drop раньше нужного ACCEPT/accept, и не было ли -F/flush ruleset без восстановления.
  • Если применяли профиль через панель хостинга (некоторые провайдеры дают firewall на уровне гипервизора, отдельно от ОС) — проблема может быть вообще не в ОС сервера, а в правиле сетевого firewall провайдера, который фильтрует трафик до того, как он доходит до вашей ОС. В этом случае даже консоль VNC ничего не покажет в самой ОС — надо чинить правило в панели хостинга.

Эта диагностика по памяти работает в 80% случаев и определяет, куда идти дальше: в консоль ОС через VNC или в раздел «Firewall» панели управления хостингом.

Спасательный канал: консоль хостера

Это главное, что нужно знать про такие ситуации: серверная консоль хостинг-провайдера (VNC, serial console, KVM-over-IP) не проходит через сетевой стек вашей ОС и её firewall вообще. Она подключается напрямую к виртуальному или физическому экрану сервера — так, будто вы физически подошли и подключили монитор с клавиатурой. Правила iptables, nftables и ufw фильтруют только сетевые пакеты, идущие через интерфейсы вроде eth0; консоль этот путь не использует.

Практически на любой панели VPS-хостинга есть кнопка вида «Console», «VNC», «Serial Console» или «Аварийный доступ» — обычно в карточке сервера, часто с иконкой монитора. Открывается либо во всплывающем окне с noVNC-клиентом прямо в браузере, либо в отдельной вкладке. Дальше — обычная работа за терминалом, только вводом с виртуальной клавиатуры (иногда неудобной, но рабочей):

# Проверить состояние ufw
sudo ufw status verbose

# Если проблема в ufw — добавить правило для SSH и перечитать
sudo ufw allow OpenSSH
sudo ufw reload

# Проверить политику и правила iptables
sudo iptables -L -n --line-numbers
sudo iptables -S INPUT

# Вернуть политику INPUT в ACCEPT (временно, чтобы не запереться повторно)
sudo iptables -P INPUT ACCEPT

# Добавить недостающее правило для SSH первым в цепочке
sudo iptables -I INPUT 1 -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

# Для nftables — посмотреть текущий ruleset и найти, где встал drop раньше accept
sudo nft list ruleset

После правки — не закрывайте консоль сразу. Откройте вторую вкладку терминала (или второе окно на своей машине) и попробуйте зайти по обычному SSH. Только убедившись, что новое подключение проходит, возвращайте политику к боевой (DROP вместо временного ACCEPT) и снова проверяйте SSH — уже с рабочим разрешающим правилом на месте.

Если у выделенного сервера консоли нет в стандартной панели, но есть встроенный IPMI/iDRAC/iLO-контроллер — тот же принцип: подробнее о том, как он устроен и как им пользоваться, в статье про KVM-доступ к серверу.

Если консоли нет: что делать тогда

Если тариф не включает веб-консоль и IPMI недоступен (или вы арендуете сервер там, где такой функции нет вовсе), вариантов немного, и все они идут через поддержку хостинга:

  • Тикет в поддержку с просьбой открыть консоль. Даже если консоль не входит в тариф по умолчанию, часть провайдеров временно предоставляет доступ к ней по запросу именно для таких случаев — стоит спросить прямо.
  • Перезагрузка в rescue/recovery-режим. Большинство серьёзных хостингов дают загрузку с отдельного recovery-образа (иногда через панель, иногда только через поддержку), который поднимает временную ОС с сетевым доступом отдельно от вашей основной системы. Из rescue-режима монтируете диск основной системы и правите файлы конфигурации firewall напрямую:
# Пример для окружения rescue на базе Debian/Ubuntu
mount /dev/sda1 /mnt
chroot /mnt

# Если правила ufw хранятся персистентно — отключить перед следующей загрузкой
systemctl disable ufw

# Или, если правила iptables поднимаются юнитом systemd/скриптом при загрузке —
# найти и временно закомментировать соответствующую строку
grep -rl "iptables-restore\|ufw enable" /etc/systemd/system/ /etc/network/

После правки — выход из chroot, размонтирование, перезагрузка в обычном режиме.

  • Полная переустановка ОС через панель. Крайний вариант, если данные не критичны или есть бэкап — быстрее, чем ждать ручного восстановления, но теряете всё, что не было сохранено отдельно.
  • Если сервер физический и без IPMI — по сути остаётся только поддержка хостинга с доступом к оборудованию: попросить перезагрузку, замену кабеля в консольный порт или помощь их дежурного инженера.

Ни один из этих путей не такой быстрый, как консоль VNC — счёт идёт на часы, а не на секунды. Поэтому раздел ниже важнее, чем кажется на первый взгляд: правильная практика делает саму ситуацию редкой.

Как больше не отрезать себя от сервера

Два простых правила закрывают почти все случаи такой самоблокировки — и оба не требуют ничего, кроме дисциплины.

Правило 1. Тестируйте новое правило firewall через консоль хостера параллельно с активной SSH-сессией, не закрывая её. Откройте консоль VNC/serial ДО того, как менять правила — не после того, как что-то пошло не так. Применяйте изменение через SSH (или через саму консоль), но старую SSH-сессию не закрывайте, пока не откроете новую и не убедитесь, что она подключается. Если новая сессия не открывается — у вас в консоли уже есть рабочий канал, чтобы откатить правило немедленно, без тикетов и ожидания.

Правило 2. Настройте отложенный откат правила через at или cron — своего рода «сеть страховки» на случай, если вы забыли про правило 1. Идея простая: планируете возврат к прежней конфигурации через 5 минут, и если к этому моменту вы вручную не подтвердили, что всё работает — откат срабатывает сам.

# Установить at, если его нет
sudo apt install at

# Перед применением нового правила — сохранить текущее рабочее состояние
sudo iptables-save > /root/fw-backup-$(date +%s).rules

# Запланировать откат через 5 минут
echo "iptables-restore < /root/fw-backup-1735900000.rules" | sudo at now + 5 minutes

# Дальше применяете новое правило и проверяете вход второй сессией

# Если всё работает — отменяете отложенный откат
atq
sudo atrm <номер_задания_из_atq>

Для ufw тот же принцип, но проще — откат сводится к отключению фаервола целиком, если вы не уверены в конкретном правиле:

echo "ufw disable" | sudo at now + 5 minutes
# после проверки, что SSH работает:
atq
sudo atrm <номер_задания>

Для nftables можно хранить снапшот ruleset тем же способом:

sudo nft list ruleset > /root/nft-backup-$(date +%s).nft
echo "nft -f /root/nft-backup-1735900000.nft" | sudo at now + 5 minutes

Эта связка — снапшот перед изменением плюс отложенный откат — стоит нескольких лишних команд каждый раз, но полностью снимает риск остаться снаружи сервера на часы. Те же принципы стоит закладывать и в автоматизированные плейбуки: шаг с ufw enable должен идти строго после шага с разрешающим правилом, а не до него, и в идеале плейбук проверяет доступность SSH-порта после применения, прежде чем считать деплой успешным. Смежные типовые ошибки UFW разобраны в статье про частые ошибки фаервола UFW, а базовая пошаговая настройка — в материале как установить и настроить UFW на VPS.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Почему SSH оборвался не сразу, а через минуту-две после команды?

Скорее всего, сработала политика DROP без правила для ESTABLISHED,RELATED: пакеты активной сессии продолжали проходить, пока conntrack «помнил» соединение, а затем новые пакеты (ретрансмиты, keepalive) начали отбрасываться.

У меня нет VNC-консоли в панели — что делать в первую очередь?

Открыть тикет в поддержку хостинга и явно попросить временный доступ к консоли или перезагрузку в rescue-режим — это почти всегда быстрее, чем самостоятельные попытки достучаться иными путями.

Поможет ли перезагрузка сервера, если правила применяются при старте?

Нет, если правила persistent (сохранены через netfilter-persistent, ufw как сервис или юнит systemd) — после перезагрузки та же конфигурация поднимется снова и снова отрежет доступ.

Можно ли вместо at использовать обычный cron для отложенного отката?

Можно, но at удобнее для разового задания: не нужно чистить crontab после срабатывания, и легко посмотреть/отменить задачу командами atq/atrm до того, как она выполнится.

Правило 1 (тестировать через консоль параллельно) действительно снимает необходимость в правиле 2 (отложенный откат)?

На практике — нет: люди забывают открыть консоль заранее в спешке или при рутинных изменениях. Отложенный откат — это защита от собственной невнимательности, а не дублирование одной и той же идеи.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →