Односторонний трафик после отключения SNAT подсети Tailscale
Отключите SNAT на маршрутизаторе подсети Tailscale, и ответы перестанут приходить. Настоящий адрес источника сохраняется, поэтому LAN нужен обратный маршрут к 100.64.0.0/10.
Отключите исходный NAT на маршрутизаторе подсети Tailscale, и туннель продолжит работать, а соединения через него перестанут. Запросы приходят к получателю с собственным overlay-адресом удалённого клиента, что и является смыслом изменения, и ответам теперь нужен путь, о котором LAN никогда не должна была знать. Без этого пути пакеты приземляются, ответы уходят через обычный шлюз, и сбой выглядит как проблема межсетевого экрана, которую не объясняет ни одно правило. Туннель здоров; обратное плечо отсутствует.
Что скрывал SNAT
При включённом SNAT маршрутизатор переписывает адрес источника на свой LAN-адрес перед передачей в подсеть, поэтому получатель отвечает хосту, до которого уже умеет добираться, и больше ничего настраивать не нужно. Отключение сохраняет исходный источник, и получатель видит адрес внутри диапазона overlay, а не соседа на своём проводе. Этот адрес реален и маршрутизируется по всему tailnet, но из LAN через шлюз по умолчанию он недостижим. Документированный переключатель — --snat-subnet-routes=false, он применяется к самому Linux-маршрутизатору подсети.
Это постоянная настройка, а не переключатель для каждого пакета, поэтому обратный путь должен существовать для каждой сети назначения, которую обслуживает этот маршрутизатор. Именно поэтому изменение является решением о развёртывании, а не галочкой. Всё, что обслуживает этот маршрутизатор, наследует требование в тот же момент.
Где может находиться обратный путь
Три размещения обычны, и они различаются охватом, а не правильностью. Статический маршрут на хосте назначения самый прямой и наименее масштабируемый, поскольку каждому устройству нужна своя копия. Таблица маршрутов в VPC или на маршрутизаторе площадки покрывает всю сеть сразу, а опция DHCP с бесклассовыми статическими маршрутами доходит до клиентов автоматически, но тихо отказывает на устройствах, которые её игнорируют.
ip route add 100.64.0.0/10 via 192.168.1.10
ip route get 100.64.0.5
Какое бы размещение вы ни выбрали, следующий шаг — это LAN-адрес маршрутизатора и никогда не его tailnet-адрес. Хост в LAN не достигнет overlay, пока у него нет этого маршрута, поэтому следующий шаг внутри overlay цикличен и никуда не отправляет пакет. Эта единственная ошибка объясняет большинство конфигураций, которые выглядят правильно и всё равно не работают, и она переживает любую проверку, читающую только собственную таблицу маршрутизатора. Запишите, какое размещение вы использовали, иначе следующий человек проверит не то.
Чтение сбоя как одностороннего трафика
Симптом проще распознать, чем причину: служба отвечает на самом маршрутизаторе и молчит со стороны удалённого клиента. Запись на стороне назначения показывает приходящие запросы и уходящие ответы, что выглядит как успех, пока не заметишь, куда эти ответы направляются. Они идут к шлюзу по умолчанию, а значит, входящее плечо работало, а обратное — нет.
Записывайте вместо этого на маршрутизаторе, потому что он видит оба направления одного обмена и показывает, приходил ли ответ вообще. Если ответ появляется на назначении, но никогда на маршрутизаторе, маршрут отсутствует или неверен на стороне назначения. Если он появляется на маршрутизаторе и там останавливается, проблема дальше и относится к другому расследованию.
sudo tcpdump -ni any host 100.64.0.5
ip route get 100.64.0.5
Стоит ли настоящий адрес маршрута
Сохранение SNAT остаётся более простым ответом, когда сеть назначения нельзя перенастроить, а цена в том, что каждый клиент выглядит как маршрутизатор в журналах и политике назначения. Отключение оправдано, когда приложению нужен настоящий адрес источника или когда сетевая политика должна различать клиентов, пользующихся одним маршрутизатором. Обе причины законны, и ни одна не бесплатна. Выгода должна оправдывать поддержание маршрута в каждой сети назначения плюс описанную ниже проверку межсетевого экрана.
Для одной небольшой LAN обмен обычно оправдывается, а для множества устройств, которые не могут принять статический маршрут, обычно нет. Запишите решение и причину рядом с конфигурацией маршрутизатора, чтобы следующий администратор знал, какое поведение намеренное. Значение по умолчанию, которого никто не записал, неотличимо от недосмотра.
Межсетевой экран, журналирование и двойная роль
Каждое правило, совпадавшее с LAN-адресом маршрутизатора, теперь совпадает с другим источником, включая правила разрешения и любое поле журнала, где маршрутизатор записывался как клиент. Прочитайте эти правила до первого теста, а не после первого отказа, потому что правило, разрешающее только адрес маршрутизатора, полностью блокирует новый источник. Сузьте замену до клиентов и портов, которым она нужна, и затем убедитесь, что она не пропускает тихо весь tailnet.
sudo nft list ruleset | grep -n '100\.64'
sudo iptables-save | grep -n '100\.64'
Один узел, служащий одновременно выходным узлом и маршрутизатором подсети, — документированная комбинация, которая может терять восходящий трафик после отключения SNAT подсети. Разделение этих ролей на разных узлах снимает эту оговорку и даёт каждому маршруту и политике экрана одного владельца. Если роли должны оставаться вместе, ожидайте такого поведения и проверьте его, прежде чем винить клиента. Храните маршрут, настройку переключателя и распределение ролей в одной заметке, потому что их читают вместе, когда следующее соединение не удаётся.