Відповідь VPN між майданчиками не йде через тунель
Відповідь, що обходить тунель, — це рішення про маршрутизацію на далекому боці. Перевірте таблицю хостів, селектори та rp_filter, потім виберіть маршрут або NAT.
Я витратив ранок на тунель, який піднявся чисто й гнав трафік рівно в один бік: філія діставала файловий сервер у головному офісі, а кожне з’єднання, відкрите з офісу до філії, вмирало на першому SYN. SA були підняті, лічильники тунелю зростали, і рукостискання ніколи не було проблемою. Відповідь маршрутизувалася туди, куди тунель не дістає, і цей вибір належить далекому боку. VPN між майданчиками переносить лише пакети, які хост передає шлюзу, і кожен хост робить цей вибір окремо, у кожному напрямку, зі своєї таблиці маршрутизації.
Обидва напрямки маршрутизуються окремо
IP не пам’ятає напрямку розмови. Кожен хост, що надсилає пакет, виконує власний пошук найдовшого префікса, вибирає один наступний перехід і забуває рішення. Запит і відповідь — два незв’язані пакети, які випадково належать одному з’єднанню, а тунель — один перехід, яким будь-який із них може скористатися або не скористатися. Ніщо в обміні IKE не вчить далекий сервер, як дістатися до вашої підмережі; переговори лише домовляються, які префікси можна шифрувати.
Ця угода — другі ворота. У strongSwan селектори трафіку — це leftsubnet і rightsubnet, і пакет, чиє джерело або призначення виходить за межі узгодженої пари, не шифрується, що б не казала таблиця маршрутизації. Префікс, маршрутизований у тунель, але відсутній у селекторах, — тиха однобічна відмова: маршрут виглядає правильним, пакет усе одно виходить відкритим або відкидається, і лише журнал charon скаржиться.
Далекий хост нічого не знає про ваш тунель
Усередині далекої локальної мережі відповідь — звичайний пакет, адресований вашому клієнту. Хост призначення не бачить заголовка IPsec і не має причин віддавати перевагу VPN-шлюзу; він шукає ваш префікс, не знаходить нічого конкретнішого за свій маршрут за замовчуванням і йде ним. Якщо маршрут за замовчуванням вказує на основний міжмережевий екран, у нього або є маршрут назад у тунель, або немає. Коли немає, ви отримуєте тихе відкидання, ICMP unreachable або відповідь, що виходить через інтерфейс у бік інтернету й помирає.
Другого інтерфейсу достатньо, щоб це зламати, навіть коли маршрут існує. NAS із керівним каналом в іншому VLAN, сервер із резервним uplink, правило політики, що надсилає один діапазон джерел у другу таблицю: будь-що з цього може перехопити відповідь. У Linux ip rule show і ip route show table all показують правила й таблиці, які приховує звичайний список.
Прочитайте рішення на машині, яка надсилає відповідь
Запитайте ядро, перш ніж щось міняти, і дайте йому адресу джерела, бо правила, залежні від джерела, змінюють відповідь.
ip route get 10.10.5.10 from 10.20.30.15
ip rule show
ip route show table all
ss -tn state established "( sport = :445 )"
Вивід називає вихідний інтерфейс і наступний перехід. Якщо інтерфейс не той, що дивиться на VPN-шлюз, ви знайшли дефект, і лишається вибрати, де має бути маршрут. Ping зі шлюзу тут доводить мало: він відповідає адресою, яку далекий хост може розмістити, а не адресою вашого ноутбука.
У Windows відповідники — Find-NetRoute -RemoteIPAddress 10.10.5.10 для рішення і Get-NetRoute для таблиці. Маршрут, доданий через New-NetRoute з вищою метрикою за типовий, тихо програє, тож читайте стовпець метрики, а не запис. Потім підтвердьте пакетами: tcpdump -ni any "host 10.10.5.10 and tcp port 445" на далекому інтерфейсі LAN показує запит, а той самий фільтр з боку тунелю показує, чи повернулася відповідь. Запит видно, відповіді немає — отже відповідь було маршрутизовано в інше місце або відкинуто; відповідь на неправильному інтерфейсі дає вам винного, перш ніж ви торкнетеся маршруту.
Коли шлюз сервера не є кінцевою точкою VPN
Багато майданчиків ставлять міжмережевий екран між серверами й концентратором. Цей екран пересилає відповідь, тож йому потрібен маршрут для префікса вашого клієнта в бік VPN-шлюзу і політика пересилання в обох напрямках. Пристрої зі станом погіршують: запит пройшов крізь екран від хоста LAN, якому він дозволив, відповідь тепер надходить з іншого напрямку, і запис відстеження з’єднань більше не збігається, тому пакет відкидається як недійсний, а не як заборонений. Ось чому журнал політики виглядає порожнім, поки трафік зникає.
У шлюзу є власний другий фільтр. Зворотна перевірка шляху в Linux відкидає пакети, джерело яких недосяжне через інтерфейс, на який вони прийшли, і це точно форма законного асиметричного зворотного шляху. посібник strongSwan з пересилання вимагає net.ipv4.ip_forward і ослаблений net.ipv4.conf.all.rp_filter саме тому. Суворе значення 1 на будь-якому шлюзі тихо ламає правильний маршрут, і nstat -az показує відкидання, якщо знати, куди дивитися.
| Symptom | Where the reply is most likely lost |
|---|---|
| Gateway ping works, LAN host silent | Source address the far host cannot place in its table |
| SYN arrives, no SYN-ACK, tunnel counters flat | No route to the client prefix on the far host or its gateway |
| Reply counted on the internet-facing interface | Default route or policy rule on the far host |
| Firewall reports invalid state | Asymmetric path through a stateful device |
| Worked until a link failed over | New path is asymmetric, or rp_filter now rejects it |
Маршрутизуйте або транслюйте, потім перевірте в обох напрямках
Два виправлення не еквівалентні. Додавання маршруту зберігає адресу клієнта недоторканою, тож правила на основі джерела, журнали аудиту й застосунки, що записують того, хто викликає, продовжують працювати; ціна — кожен перехід, що ухвалює рішення, потребує маршруту, тобто більше місць, де можна помилитися. Маскарадинг на далекому шлюзі стискає зворотний шлях до одного переходу, бо відповідь тепер адресована самому шлюзу, і приховує, який клієнт що зробив.
iptables -t nat -A POSTROUTING -o eth1 -s 10.20.30.0/24 -j MASQUERADE
Виберіть це свідомо: щойно клієнти починають виглядати як адреса шлюзу, ACL на основі джерела перестають їх розрізняти, і conntrack має утримувати відповідність, щоб відповідь записувалася назад у тунель. Якщо селектори досі виключають префікс клієнта, NAT нічого не змінює, бо запит так і не ввійшов у тунель.
Перш ніж назвати це виправленим, підтвердьте чотири речі по черзі: маршрут на хості, який надсилає відповідь, маршрут на кожному переході, що його пересилає, селектори, що покривають обидва префікси, і запис, який показує, що відповідь входить у тунель з очікуваним джерелом. Потім повторіть тест з іншого майданчика. Проходження одного напрямку — це напіввідкритий дизайн, і другий напрямок зазвичай падає з іншої причини, ніж та, яку ви щойно виправили.