PPTP підключається і потім зависає за Linux NAT: помічник GRE
TCP 1723 підключається, а шлях даних помирає: PPTP їде в GRE, який не має портів. Завантажте помічники, підключіть їх явно і відкрийте протокол 47.
Хтось пробрасує 1723, клієнт доходить до сервера, починається автентифікація, і потім усе зупиняється без помилки. Природний висновок — неправильний пароль, тому пароль вводять ще тричі. Проброс був гаразд, і облікові дані були гаразд. Зламався другий протокол, який проброс ніколи не покривав, і типове значення ядра, яке тихо перестало допомагати з ним.
Проброс ніколи не був проблемою
Правило пробросу порту описує трафік TCP або UDP. Воно не може описати корисне навантаження, яке посеред сесії переходить на інший протокол IP, а PPTP робить саме це.
Тому з'єднання виглядає здоровим аж до моменту зависання. Частина, якою правило порту може керувати, спрацювала, а частина, якою воно не може керувати, — це та частина, що відмовила.
TCP для керування, GRE для даних
Виклик узгоджується через TCP 1723. Щойно він піднятий, корисне навантаження переходить у GRE, протокол IP 47, який узагалі не несе номерів портів. Правилу, що спирається на порти, нема з чим зіставляти.
GRE несе в своєму заголовку ідентифікатор виклику, і транслятор NAT має переписувати це поле узгоджено в обох напрямках, інакше дві половини сесії перестають домовлятися. Переписаний один напрямок і не переписаний другий дають сесію, яка проходить автентифікацію і потім відкидає кожен пакет даних. Саме така форма симптому: успіх, потім тиша.
Голий GRE без PPTP не потребує такого переписування, тому звичайний тунель GRE може працювати через маршрутизатор, який відмовляє клієнту PPTP на тому самому шляху.
Чотири модулі та sysctl, який їх вимкнув
Два модулі відповідають за кадрування, nf_conntrack_proto_gre і nf_nat_proto_gre. Ще два відповідають за ідентифікатор виклику, nf_conntrack_pptp і nf_nat_pptp. Завантаження останнього підтягує решту через залежності, тому список модулів має показувати всі чотири.
Старі інструкції використовують префікс ip_ з епохи 2.6. Ці команди можуть виглядати працюючими, нічого не завантажуючи, тому перевіряйте завантажений список, а не код виходу.
Завантаженості вже недостатньо. Починаючи з Linux 4.7 sysctl net.netfilter.nf_conntrack_helper за замовчуванням дорівнює 0, що вимикає автоматичне призначення помічника для нових потоків. У маршрутизатора можуть бути всі модулі, і він усе одно нічого не транслює. Перевірте чинне значення, перш ніж знову дивитися на список модулів.
Або знову ввімкніть автоматичне призначення глобально, або прив'яжіть помічник до потоків, яким він потрібен, і залиште все інше в спокої:
iptables -t raw -A PREROUTING -p tcp --dport 1723 -j CT --helper pptpДругий варіант кращий. Він обмежує поведінку трафіком PPTP, замість того щоб знову вмикати автоматичне призначення на всьому маршрутизаторі.
Відкриття протоколу, який не має портів
Правило брандмауера, що дозволяє 1723, нічого не каже про протокол 47. У firewalld дозвольте протокол у зоні, повернутій до клієнта. У звичайному iptables прийміть протокол gre у вхідному ланцюжку.
Потім знімайте з обох боків. Пакети, що йдуть від клієнта без відповідей, означають, що зворотний шлях фільтрується, і це інша несправність, ніж відхилені облікові дані.
Після підключення — обмеження розміру
GRE вставляє заголовок, а PPP усередині додає ще, тому робоче з'єднання повідомляє MTU помітно нижче 1500. Малі відповіді завантажуються, а великі завмирають, що виглядає як друга, не пов'язана проблема, яка з'являється в момент вирішення першої.
Прочитайте MTU на PPP-адаптері клієнта і узгодьте його з власним розрахунком маршрутизатора замість того щоб знижувати числа, поки щось не запрацює. Пакети повного розміру, що йдуть без повернення, вказують на цю межу, а не на трансляцію.
Ремонт шляху повертає користувача до роботи, і це не робить PPTP добрим вибором. MS-CHAPv2 і RC4 давно застаріли, тому ставтеся до завантаження модулів як до тимчасового виправлення і плануйте перехід на підтримуваний протокол.