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

Роутер пересылает туннель, хост оценивает пакет

Нарисуйте путь от удалённого источника до сервиса, прежде чем смотреть на единственное правило. Внешний участок — это транспорт VPN, которым занимаются роутер и шлюз. Внутренний участок начинается, когда конечная точка снимает туннельный слой и хост получает пакет, адресованный его VPN-адресу.

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

Слушатель с подстановочным знаком — не публичный сервис

В Linux привязка к INADDR_ANY означает каждый локальный адрес, поэтому сервис может отвечать на туннельном интерфейсе, который он никогда не называл. Справочник по IP-сокетам описывает эту привязку, и его стоит прочитать, прежде чем делать выводы из списка слушателей. Запись с подстановочным знаком — это факт о сокете, а не утверждение о доступности.

Две строки ниже — один и тот же сервис в двух разных привязках, и разница — весь ответ на вопрос, имеет ли значение интерфейс. Сначала прочитайте, на каком адресе сидит сокет.

ss -lntp "sport = :22"
LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=812,fd=3))
LISTEN 0 4096 10.8.0.6:22 0.0.0.0:* users:(("sshd",pid=812,fd=4))

Назовите расклад, который мог бы достичь порта

Три расклада ставят пакет на этот интерфейс, и у них разные владельцы. Назвать правильный — значит решить, кто должен менять политику.

ArrangementWhat reaches the portWhere the decision lives
Another permitted VPN peerA packet from the same tunnel subnetGateway forwarding policy and host input rules
A deliberate public forwardTraffic the gateway publishes on purposeGateway service definition
A subnet routed behind the gatewayClient traffic from the far sideGateway route and host input rules

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

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

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

nft add rule inet filter input iifname "tun0" ip saddr 10.8.0.0/24 tcp dport 22 accept
nft list chain inet filter input

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

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

Примите исправление с одним успехом и одним отказом

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

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

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