PPTP в Docker се удостоверява, но не пренася трафик
PPTP изисква TCP 1723 за управление и GRE за данните. В контейнер помощникът за conntrack често липсва, затова входът работи, а другото — не.
Клиентът се удостоверява, PPP договаря адрес и след това нищо не се движи. Ping се проваля, браузърът се проваля, а контейнерът изглежда свързан през цялото време. Този модел не е проблем с таблицата за маршрутизиране, защото проблемите с маршрутизирането обикновено чупят и управляващата връзка. Това е пътят на данните, а в PPTP данните са различен протокол от този, който току-що успя.
Пет проверки, в реда, който спестява най-много време.
Проверка 1: отделете управляващия канал от данните
PPTP се удостоверява през TCP 1723 и след това носи PPP данните вътре в GRE, IP протокол 47. GRE не е нито TCP, нито UDP, така че всяко правило, което пропуска управляващия порт, не казва нищо за него. NAT или защитна стена, която пропуска 1723, може да изхвърли протокол 47 без оплакване и сесията остава наполовина изградена по начин, който изглежда като успех.
Ако входът работи и нито един пакет не се връща, първо приемете GRE и после го докажете.
Проверка 2: потвърдете помощника в ядрото на хоста
Проследяването на връзки не може да свърже управляваща връзка TCP с поток GRE без помощник. Модулът е nf_conntrack_pptp, живее в ядрото на хоста и зареждането му в образа на контейнера не постига нищо, защото модулите са общи за целия хост. lsmod | grep nf_conntrack_pptp на хоста с Docker е проверката. Ако липсва, modprobe nf_conntrack_pptp го зарежда за текущото ядро и не казва нищо за следващото стартиране, затова го добавете и в конфигурацията на хоста.
Модул, който изчезва при рестарт, става същият билет следващия месец.
Проверка 3: прочетете политиката на ядрото, която го изключва
Дори при наличен модул ядрата от 4.7 насам задават net.netfilter.nf_conntrack_helper по подразбиране на 0, което изключва автоматичното назначаване на помощник за всеки протокол. Заради това подразбиране правилно инсталиран модул пак не прави нищо: кодът е налице, а политиката казва да не се използва. sysctl net.netfilter.nf_conntrack_helper показва текущата стойност и задаването ѝ на 1 по време на работа отново прави помощника достъпен. Запазете стойността чрез конфигурацията на sysctl на хоста, ако дизайнът позволява.
Автоматичното назначаване позволява на трафика да създава очаквания неявно и точно затова подразбирането се промени. Ограничете го до доверения хост или използвайте явно правило, насочено към помощника.
Проверка 4: погледнете пътя на контейнера отделно
Зареденият помощник не създава маршрут. Контейнерът се нуждае от път до PPTP сървъра, а препращането на хоста трябва да разрешава GRE в двете посоки: iptables -L FORWARD -v -n показва дали протокол 47 се приема и дали броячите се движат. Правилата masquerade на Docker преобразуват TCP и UDP, не протокол 47, затова контейнер в мостов режим може да се нуждае от явно разрешение за forward и на някои хостове от собствено правило за преобразуване. Уверете се също, че контейнерът има поддръжка на PPP устройства, каквато образът му очаква.
Четете броячите, а не текста на правилото. Правило, което съществува и не съвпада с нищо, е украшение.
Проверка 5: докажете, че GRE се проследява, после решете за PPTP
Докато клиентът работи, прочетете таблицата за проследяване. Установен запис за управление на PPTP плюс свързан запис GRE означава, че помощникът свързва потоците и оставащата повреда е другаде. Запис за управление без запис GRE означава, че данните се изхвърлят или не се проследяват, което ви връща към проверки 2 и 3.
Самият PPTP е остарял, а MS-CHAPv2 е слаб. Ако сървърът предлага също L2TP/IPsec, IKEv2 или WireGuard, преминаването към един от тях премахва целия този клас проблеми.
Където PPTP трябва да остане, стартирането на клиента на хоста вместо в контейнер премахва един слой NAT и филтриране, което често е по-евтиното решение.