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

Два входа, один порт службы

У хоста есть адрес со стороны LAN и адрес VPN, и sshd слушает на обоих. Поэтому прямой сеанс и туннельный сеанс разделяют порт службы и различаются только тем, какой локальный адрес принимает соединение.

Этого различия достаточно для выбора пути ответа, и именно это различие отбрасывает правило, основанное на порте. Оба сеанса создают ответы, порт источника которых равен 22, поэтому правило, совпадающее с этим портом, не может их разделить. Оно отправляет оба поиска в одну и ту же таблицу, и один из них получает ответ, который не подходит. Исправление — сопоставление с признаком, который действительно различается.

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

Прочитайте правило, затем таблицу

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

Затем прочитайте таблицу, на которую указывает это правило, потому что правило, которое успешно разрешается, не обязательно разрешается полезно. Таблица, содержащая только маршрут по умолчанию, отправляет ответ от VPN наружу через интерфейс WAN. Более конкретный маршрут в более поздней таблице никогда не рассматривается, и поэтому добавление второй таблицы так часто ничего не меняет. Именно выбранную таблицу и нужно проверять.

ip -4 rule show
ip route show table 100
ip route show table main

Эти два вывода вместе объясняют результат; каждый по отдельности ведёт к неверному заключению.

Ограничьте правило тем потоком, который вы имеете в виду

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

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

sudo ip rule add from 10.90.0.1 lookup 100 priority 100
sudo ip route add 10.90.0.0/24 dev wg0 table 100
ip route get 10.90.5.20 from 10.90.0.1

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

Держите отдельно слушатель, разрешение и выбор ответа

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

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

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

Докажите это новым сеансом, а не старым

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

ss -ltnp | grep ':22'
sudo sshd -T | grep -i listenaddress
ssh -v [email protected] true
sudo journalctl -u ssh -n 30

Затем повторите переподключение VPN и попробуйте снова, потому что маршрут, переживающий переподключение, — не то же самое, что маршрут, добавленный в таблицу, которую переподключение очищает. Наблюдайте за отклонёнными источниками отдельно от разрешённых, чтобы заблокированная попытка не скрылась за работающим сеансом. Сохраните локальный адрес, правило и таблицу рядом с результатом. Если вместо этого вы разделили порты, запишите это как операционное решение, а не как ограничение SSH.

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