Вы прошли контрольный список: запретить исходящий трафик, разрешить туннель, включить ufw. Затем клиент ждёт на рукопожатии и никогда не подключается, или подключается, и ни одна страница не загружается. Обе неудачи происходят из одной и той же дыры. Правило, которое позволяет туннелю существовать, отсутствует, потому что туннель — не интерфейс, через который выходят ваши пакеты.

Почему разрешение на tun0 сначала ничему не соответствует

tun0 создаётся клиентом после того, как появляется сессия. Датаграммы, которые строят эту сессию, — обычные UDP-пакеты, адресованные провайдеру на порт 1194, и они выходят через wlan0 или eth0 с физическим адресом источника. allow out on tun0 соответствует только трафику, у которого исходящий интерфейс tun0, поэтому во время рукопожатия он не соответствует вообще ничему.

Поставьте default deny outgoing сверху, и внешние пакеты отбрасываются ещё до появления интерфейса. Клиент повторяет попытку, упирается в тайм-аут и сообщает об ошибке TLS или рукопожатия, из-за чего люди начинают рыскать по сертификатам и MTU, пока брандмауэр тихо съедает соединение. Правило, которое должно было сдерживать ваш трафик, мешает этому трафику быть сдержанным.

Рефлекторное исправление делает утечку постоянной. sudo ufw allow out on wlan0, или возврат значения по умолчанию к разрешению, поднимает туннель и оставляет машину без аварийного выключателя: в следующий раз, когда туннель падает, всё продолжается через физический адаптер. Я потерял полдня именно на этой паре правок, прежде чем понял, какой пакет я на самом деле фильтрую.

Что нужно двум наборам пакетов

Ваш трафик проходит через брандмауэр дважды, в двух формах. Внутренний пакет идёт от адреса туннеля наружу через tun0. Внешний пакет идёт от физического адреса к пиру, и это единственное, что видно на проводе. Одно правило на форму:

sudo ufw allow out on tun0
sudo ufw allow out to 203.0.113.10 port 1194 proto udp
sudo ufw allow out to 203.0.113.10 port 443 proto tcp comment 'tcp fallback'

Замените адрес и порт на те, что в вашем собственном профиле. Пиры WireGuard обычно отвечают на 51820/udp; профилям OpenVPN, идущим через TCP 443, вместо этого нужен тот порт. Детали различаются, форма нет: оба правила узкие, и вместе они определяют единственные пункты назначения, до которых машина может дотянуться, пока туннель лежит.

Порядок — второй миф. С сырым iptables вы читаете цепочку сверху вниз и рассуждаете, какое правило победит. ufw не тонкая обёртка вокруг введённого вами списка; он компилирует ваши правила в собственные цепочки и выбирает точки вставки. ufw status печатает их в порядке ufw, а не вашем. Когда правило выглядит проигнорированным, сравните ufw show added с скомпилированным набором из iptables -S | grep ufw прежде чем что-либо переписывать.

Исключение должно оставаться шириной в один адрес

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

Расширение на целую подсеть или на каждый пункт назначения на порту 1194 снова превращает политику в брандмауэр с дырой. Исключение — это и есть аварийный выключатель; как только он широк, выключать больше нечего. Держите его на одном адресе и оставьте комментарий с названием профиля и провайдера, которым он принадлежит, потому что через полгода адрес будет выглядеть произвольным.

Разрешение имён заслуживает отдельной строки. Поиск происходит до того, как туннель существует, через физический интерфейс, поэтому строгая политика запрета исходящего трафика может оставить клиент неспособным найти собственный сервер. Разрешите порт 53 к адресу вашего резолвера или разрешите один раз и закрепите адрес в профиле. Разрешать DNS на каждом интерфейсе — это решение, а не значение по умолчанию.

Постройте политику до того, как понадобится туннель

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

sudo ufw default deny incoming
sudo ufw default deny outgoing
sudo ufw allow out on tun0
sudo ufw allow out to 203.0.113.10 port 1194 proto udp
sudo ufw allow 22/tcp
sudo ufw enable
sudo ufw status verbose

ufw reset намеренно оставлен вне этого блока. Он удаляет каждое правило и отключает брандмауэр, а на удалённом хосте именно следующее включение сбрасывает вашу сессию. Если всё же сбросите, добавьте правило SSH и подтвердите второй путь обратно через консоль, прежде чем идти дальше.

Последовательность не косметическая. Правила, добавленные пока ufw работает, ничего не сбрасывают, но в момент, когда вы переворачиваете политику по умолчанию, цепочки перезагружаются, и сессия, которую разрешала старая политика, уходит вместе с ними. Сделайте значения по умолчанию, разрешения и включение за один проход, пока у вас ещё есть путь внутрь, не зависящий от машины.

Проверьте заблокированное состояние и сохраните откат

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

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

sudo ufw reset
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw enable

Запускайте его, когда туннель уже лежит и правила надо снять, а не как рутинный шаг. Прежде чем закрыть терминал, должны выполняться четыре вещи: правило для пира называет ровно один адрес, у DNS есть именованное исключение, включение произошло после разрешений, а выдёргивание туннеля убивает обычный трафик, не убивая клиент навсегда.

Похожие статьи