Ваш тунель піднято, сервіс слухає, а офісна LAN усе одно нічого не отримує назад. Ніхто не ламав VPN. З боку LAN адреса тунелю ноутбука не існує, доки щось не скаже LAN, як до неї дістатися, і відповідь має повернутися тим самим шляхом, яким пішов запит. Я бачив, як люди тричі перебудовували цілком справний тунель, перш ніж хтось подивився на зворотний шлях.

Зламався не тунель

Обидва кінці сидять у приватних діапазонах, і це нормальний випадок, а не помилка конфігурації. Адреса на кшталт 10.8.0.6 реальна всередині тунелю і ніде більше не існує, тому LAN не має причин щось туди надсилати. Перш ніж чіпати маршрутизацію, переконайтеся, що сервіс узагалі доступний усередині тунелю: на клієнті ss -ltn показує, чи слухач прив’язаний до 127.0.0.1, до інтерфейсу LAN чи до адреси тунелю. Демон, прив’язаний лише до loopback, не відповідає нікому, крім себе, і жоден маршрут, DNAT чи проброс порту цього не змінює.

Проксі на порту 80 або 443 — інший інструмент з іншою видимістю. Він переміщує запити, а не пакети, тому це невдалий рівень для прямого підключення до бази даних, і саме звернення до нього призводить до того, що ця проблема опиняється на три інструменти глибше, перш ніж хтось щось виміряє.

Форма маршруту: скажіть LAN, де розміщено пул

Статичний маршрут на шлюзі LAN — найчистіша відповідь, коли LAN і пул тунелю не перетинаються. Спрямуйте пул на машину, яка завершує тунель:

ip route add 10.8.0.0/24 via 192.168.1.12
route add -p 10.8.0.0 mask 255.255.255.0 192.168.1.12   # Windows, persistent

Це виправляє лише один напрямок, тому напівготові версії цієї зміни виглядають як прогрес. Боці тунелю потрібна відповідна половина, інакше відповідь залишає клієнта власним маршрутом за замовчуванням і гине в дорозі:

push "route 192.168.1.0 255.255.255.0"

Для підмережі, що стоїть за одним клієнтом, а не за сервером, серверові потрібні і системний маршрут, і запис iroute у файлі того клієнта під client-config-dir. Без iroute OpenVPN знає, що префікс існує, і не має уявлення, який клієнт ним володіє: пакети надходять, а демонові нема з чим їх зіставити.

Ось міф, який варто назвати. Маршрут робить адресу досяжною; він не робить протилежний бік готовим відповісти. Партнери «сайт-сайт» додають ще один рівень згори, бо віддалений шлюз приймає лише джерела всередині префіксів зі своєї політики, а ноутбук, що приходить із домашнього пулу, до них не належить.

Форма NAT: DNAT усередину і рядок SNAT, який усі пропускають

Коли не можна чіпати шлюз LAN або потрібно опублікувати рівно один порт, трансляція на хості VPN працює взагалі без маршруту в LAN. Опублікуйте порт, пробросьте його і транслюйте джерело на шляху в тунель:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 10.8.0.6:3000
iptables -A FORWARD -i eth0 -o tun0 -p tcp -d 10.8.0.6 --dport 3000 -j ACCEPT
iptables -t nat -A POSTROUTING -o tun0 -d 10.8.0.6 -p tcp --dport 3000 -j SNAT --to-source 10.8.0.1

Третій рядок — той, що губиться. Пропустіть його, і клієнт бачить початкову адресу LAN як джерело, відповідає своїм маршрутом за замовчуванням, і ця відповідь іде в тунель замість повернення до LAN. Чи виживе з’єднання, тоді залежить від маршрутизації, яку ви ніколи не планували. З SNAT клієнт бачить адресу тунелю сервера, тому відповідь іде тунелем назад до єдиного хоста, який може скасувати трансляцію.

Споживча прошивка використовує власні назви ланцюжків і не генерує цю трансляцію за вас. На Tomato вхідне правило потрапляє в WANPREROUTING, а потім у ланцюжок фільтрації на кшталт wanin, і набір правил, що виглядає повним, усе одно потребує ручного рядка POSTROUTING. Це не помилка прошивки; це набір правил, написаний лише для вхідного трафіку.

Чому правило, яке виглядає правильним, усе одно відкидає пакет

Більшість цих збоїв не в тому правилі, на яке ви дивитеся. Перевірте чотири речі в цьому порядку і зупиніться на першій, що не виконується:

  • Порядок ланцюжків. iptables -I вставляє згори, а -A додає в кінець, тому раніше дозвільне або блокувальне правило вирішує першим.
  • Не той ланцюжок. Трафік, адресований самому маршрутизатору, проходить через INPUT, а трафік, що пересилається, її ніколи не торкається. Публікація одного сервісу може вимагати правил в обох.
  • Прапорці напрямку. -i tun0 збігається з трафіком, що надходить від клієнтів, а -o tun0 — з тим, що йде до них. REJECT з неправильним прапорцем блокує те, чого ви не мали на увазі.
  • Обмеження джерела. Пересилання, що приймає одну адресу клієнта, працює від цього клієнта і відкидає будь-яке інше джерело без жодного слова.

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

Локальний проброс, коли в LAN нічого не можна змінити

Локальний проброс SSH обходить усе питання. Йому не потрібен маршрут у LAN, не потрібна співпраця брандмауера клієнта і не потрібен порт, опублікований будь-де:

ssh -N -f -L 3000:10.8.0.6:3000 user@vpn-host

Тоді сервіс з’являється на localhost:3000 машини, яка тримає тунель, і ніде більше. Це і є межа: одна робоча станція, один порт, і проброс помирає разом із сеансом, якщо щось його не перезапустить. Для адміністратора, який перевіряє тестову базу даних, це правильний інструмент. Для камери чи сканера, до яких мають дістатися інші люди, — ні, бо кожному користувачеві знадобився б власний проброс.

Перевірте обидва напрямки, перш ніж додавати ще одне правило

Трансляція залишає сліди, і читати їх краще, ніж гадати. На хості VPN conntrack -L показує, чи трансляція взагалі відбулася, iptables -t nat -L -n -v показує, чи зрушили лічильники, а tcpdump -ni any port 3000 показує, яка адреса джерела справді надійшла. На клієнті ss -ltn підтверджує, що слухач на адресі, до якої тунель може дістатися.

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

Схожі статті