ZeroTier в локальную сеть: правила маршрута UFW, а не разрешение порта
Разрешить порт на шлюзе — не то же самое, что пересылать на хост за ним. Задайте управляемый маршрут, включите транзит и выберите обратный путь.
Добраться до принтера в офисной локальной сети через участника ZeroTier звучит как одно правило, но на самом деле это три решения в трёх разных местах. Оверлей должен знать, где находится локальная сеть, хост Linux должен быть готов пересылать пакеты, а локальная сеть должна знать, как отправить ответ обратно. Входящее правило, открывающее порт на шлюзе, не затрагивает ничего из этого. Это неправильный инструмент на правильном хосте.
Три задачи, три владельца
Управляемый маршрут относится к конфигурации сети ZeroTier. Он сообщает участникам, что префикс доступен через определённый адрес участника.
Пересылка относится к ядру Linux и к тому, кто владеет политикой его межсетевого экрана. Она решает, покинет ли пакет, пришедший по оверлею, физический интерфейс снова. Хост, который не пересылает, молча отбросит пакет после его приёма. Отправитель видит тайм-аут, и в журнале службы ничего не появляется.
Обратный путь относится к локальной сети. Её хосты и её маршрутизатор должны знать, что префикс оверлея доступен через адрес шлюза в локальной сети, иначе что-то должно транслировать трафик, чтобы этот вопрос вообще не возникал.
Каждое из этого может быть правильным, пока остальные не работают, и поэтому проверка, которая только пингует шлюз, ничего не доказывает о службе за ним.
Направьте управляемый маршрут на участника
Добавьте маршрут для нужного префикса локальной сети через адрес оверлея шлюза, а не через его адрес в локальной сети. Адрес оверлея — тот, до которого могут добраться другие участники; адрес локальной сети имеет смысл только на кабеле.
Чтобы схема работала, участники должны принимать управляемые маршруты, а их собственные локальные сети не должны уже использовать объявляемый вами префикс. Удалённый ноутбук, который дома находится в 192.168.60.0/24, тоже не может маршрутизировать 192.168.60.0/24 через оверлей.
Держите объявляемый префикс настолько узким, насколько позволяет задача. Объявление более крупного агрегата ради влияния на предпочтение может также претендовать на адресное пространство, которое вам не принадлежит, и возникший конфликт проявляется на устройствах, подключённых к обеим сетям. Это может также заставить участника предпочесть путь, который никуда не ведёт. Держите маршрут честным, а остальное пусть делает политика.
Запишите префикс и адрес участника в ту же заметку, что и правила межсетевого экрана, потому что самая частая неисправность — маршрут, указывающий на неверного участника.
Включите транзит в ядре
Прочитайте текущее значение пересылки, прежде чем что-либо менять, затем сделайте настройку постоянной через механизм, который ваша система уже использует, а не через разовую команду, исчезающую при перезагрузке.
Если политикой владеет UFW, его правила маршрута выражают пересылку для пары источника, назначения и интерфейса. Они отделены от входящих правил, открывающих службу на самом шлюзе:
sysctl net.ipv4.ip_forward
sudo ufw route allow in on zt3f2a1c9d out on eth0 proto tcp to 192.168.60.20 port 443
sudo ufw status verbose
Имя интерфейса — это реальное устройство оверлея на этом хосте, которое можно прочитать с помощью ip link; это не фиксированная строка во всех установках. Если хост пересылает по умолчанию, а UFW не на пути, правило маршрута будет проигнорировано, и важны настройки ядра.
Выберите, как возвращаются ответы
При сохранении источника служба в локальной сети видит настоящий адрес оверлея и отвечает на него. Для этого нужен маршрут на хосте локальной сети или на его маршрутизаторе, направляющий префикс оверлея на ваш шлюз, а это изменение за пределами Linux-машины.
Когда такой маршрут добавить нельзя, ограниченная трансляция источника заставляет запрос выглядеть так, будто он пришёл со шлюза в локальной сети. Тогда ответы возвращаются локально и менять маршрутизацию локальной сети не нужно, но ценой этого становится потеря исходного источника в журналах службы.
Ограничьте трансляцию источником оверлея и конкретным назначением в локальной сети. Транслировать всё, что покидает интерфейс локальной сети, — это широкая версия, которая потом удивляет каждого, кто читает правила, и она же скрывает трафик, который должен был быть заблокирован.
Ни один из вариантов не даёт нежелательного доступа из локальной сети обратно к произвольным участникам оверлея. Если это нужно, это отдельное правило с собственным рассмотрением.
Проверяйте с настоящего участника
Подключитесь с другого участника, а не со шлюза, и запросите одну разрешённую службу. Затем попробуйте службу, которая должна остаться закрытой, и повторите обе проверки после переподключения и после перезагрузки шлюза.
Участник, который сообщает ONLINE, или успешный пинг адреса оверлея шлюза не подтверждают ни маршрут, ни правило пересылки, ни обратный путь:
zerotier-cli listnetworks
ip -4 route get 192.168.60.20
sudo ufw status numbered
Вторая команда показывает, какой интерфейс использовал бы пакет к хосту локальной сети, а третья — существует ли правило маршрута в задуманном виде. Если оба выглядят правильно, а служба всё равно заканчивается тайм-аутом, оставшийся подозреваемый — обратный путь.