Публікація служби LAN на власній адресі VPN-шлюзу
Прослідкуйте перенаправлений порт від клієнта до пристрою і назад: обмежте трансляцію призначення, потім вирішіть, чи відповіді маршрутизуються, чи транслюються.
Щоб показати пристрій LAN на одній із власних тунельних адрес шлюзу, потрібен лише один рядок NAT. З'єднання все одно не встановлюється, бо пристрій, що відповідає, не знає, що адреса клієнта доступна через цей шлюз. Пройдіть пакет від клієнта всередину, потім пройдіть відповідь назад назовні, і відсутня половина стане очевидною.
Почніть із погляду клієнта
Клієнт у цьому прикладі перебуває в пулі VPN 10.62.0.0/24 і підключається до 10.62.0.1 на порту 8080. Ця адреса належить самому шлюзу, тому пакет надходить до ядра шлюзу, а не до іншого учасника. За шлюзом LAN — 172.21.4.0/24. Шлюз займає 172.21.4.10, а пристрій, який справді обслуговує HTTP, — 172.21.4.40.
Адреса, що належить іншому учаснику VPN, не замінює службову адресу шлюзу. Якщо клієнт підключається до адреси учасника, правило шлюзу тут взагалі не задіяне, і весь цей розбір не про той випадок.
Обмежте трансляцію призначення навмисно
Вузький варіант показує один порт і переписує лише призначення. Пакет зберігає протокол і джерело, і саме це робить решту шляху цікавою.
iptables -t nat -A PREROUTING -i tun0 -s 10.62.0.0/24 -d 10.62.0.1 -p tcp --dport 8080 -j DNAT --to-destination 172.21.4.40:80
Правило без критеріїв протоколу і порту — це широкий варіант: воно зберігає будь-який вибраний клієнтом порт і змінює лише адресу. Це законно, коли треба показати весь хост, і помилково, коли задумано одну службу. Перечитайте правило і підтвердьте назву інтерфейсу. Правило DNAT на неправильному інтерфейсі не збігається ні з чим, що дає той самий тайм-аут, що й відсутнє правило, і витрачає годину на розглядання пристрою.
Нехай межа перенаправлення погодиться
Трансляція змінює заголовок, але не дає дозволу. За типової політики відкидання перенаправлений потік потребує власного дозволу, а зворотний напрямок — правила встановленого з'єднання, яке у вашій політиці, найімовірніше, вже є.
iptables -A FORWARD -i tun0 -o lan0 -d 172.21.4.40 -p tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Безумовний дозвіл для кожного потоку DNAT ширший за це рішення і дозволить також відображення, додані пізніше кимось іншим. Назвіть призначення і порт, а решту залиште закритою. Якщо лічильники на правилі перенаправлення залишаються нульовими, а лічильники NAT зростають, пакет відкидається до вашого правила. Читайте порядок ланцюжків, а не додавайте другу копію.
Пристрій має якось відповісти
Після трансляції пристрій бачить джерело в 10.62.0.0/24. Його відповідь іде на типовий шлюз, яким є маршрутизатор LAN, а не VPN-шлюз, якщо щось не скаже йому інакше. Це виправляють дві схеми, і вони не еквівалентні. Маршрут на пристрої або на маршрутизаторі LAN надсилає 10.62.0.0/24 на 172.21.4.10, зберігаючи джерело клієнта. Обмежена трансляція джерела натомість ховає клієнта за LAN-адресою шлюзу.
ip route add 10.62.0.0/24 via 172.21.4.10 dev eth1
iptables -t nat -A POSTROUTING -s 10.62.0.0/24 -d 172.21.4.40 -o lan0 -p tcp --dport 80 -j SNAT --to-source 172.21.4.10
Вибирайте за тим, що потрібно службі. Політика для кожного клієнта і змістовні журнали хочуть маршрутизованої форми; пристрій, якому не можна дати маршрут, або служба, якій просто треба бачити адресу LAN, вказують на трансльовану форму. Не хапайтеся за глобальне правило masquerade, щоб запрацювала одна відповідь. Воно ховає кожного клієнта від кожного призначення і тихо ламає політики, що залежать від адрес джерела.
Не перевіряйте з самого шлюзу
Запит, створений на шлюзі до 10.62.0.1, виходить через ланцюжок OUTPUT, а не через вхідний PREROUTING. Його невдача чи успіх нічого не кажуть про правило, обернене до клієнта, і саме так люди роблять висновок, що робоче правило зламане.
conntrack -L | grep 172.21.4.40
tcpdump -ni any 'port 8080 or port 80'
Запустіть справжній запит клієнта і прочитайте обидва. Запис conntrack показує застосовану трансляцію, а перехоплення показують, чи пройшов запит у LAN і чи повернулася відповідь у бік тунелю. Після зміни правил використовуйте нове з'єднання, бо наявний стан зберігає попереднє відображення і далі збоїтиме по-старому. Потім підтвердьте всю розмову: адреса пристрою, дозвіл перенаправлення і маршрут відповіді описують один і той самий потік.