Någon vidarebefordrar 1723, klienten når servern, autentiseringen börjar och sedan stannar allt utan fel. Den naturliga slutsatsen är ett felaktigt lösenord, så lösenordet skrivs in tre gånger. Vidarebefordran var i sin ordning och inloggningsuppgifterna var i sin ordning. Det som gick sönder är ett andra protokoll som vidarebefordran aldrig täckte, och en kärnstandard som tyst slutade hjälpa till med det.

Vidarebefordran var aldrig problemet

En portvidarebefordringsregel beskriver TCP- eller UDP-trafik. Den kan inte beskriva en nyttolast som byter till ett annat IP-protokoll mitt i en session, och PPTP gör precis det.

Därför ser anslutningen frisk ut ända till ögonblicket då den hänger sig. Den del en portregel kan styra lyckades, och den del den inte kan styra är den del som misslyckades.

TCP för kontroll, GRE för data

Anropet förhandlas över TCP 1723. När det är uppe flyttar nyttolasten in i GRE, IP-protokoll 47, som inte bär några portnummer alls. En regel som bygger på portar har inget att matcha.

Det GRE bär är en anropsidentifierare i sin header, och en NAT-översättare måste skriva om det fältet konsekvent i båda riktningarna, annars slutar de två halvorna av sessionen att vara överens. En riktning omskriven och den andra inte ger en session som autentiserar och sedan kastar varje datapaket. Det är exakt symptombilden: framgång, sedan tystnad.

Bara GRE utan PPTP behöver ingen sådan omskrivning, därför kan en vanlig GRE-tunnel fungera genom en router som misslyckas för en PPTP-klient på samma väg.

Fyra moduler och en sysctl som stängde av dem

Två moduler hanterar inframningen, nf_conntrack_proto_gre och nf_nat_proto_gre. Två till hanterar anropsidentifieraren, nf_conntrack_pptp och nf_nat_pptp. Att ladda den sista drar in de andra via beroenden, så en modullista bör visa alla fyra.

Äldre instruktioner använder ett ip_-prefix från 2.6-eran. Dessa kommandon kan se ut att köras utan att ladda något, så kontrollera den laddade listan i stället för slutstatusen.

Att ha dem laddade räcker inte längre. Sedan Linux 4.7 har sysctl net.netfilter.nf_conntrack_helper standardvärdet 0, vilket stänger av automatisk tilldelning av hjälpare för nya flöden. En router kan ha alla moduler och ändå inte översätta något. Kontrollera det effektiva värdet innan du tittar på modullistan igen.

Slå antingen på automatisk tilldelning igen globalt, eller koppla hjälparen till de flöden som behöver den och låt allt annat vara:

iptables -t raw -A PREROUTING -p tcp --dport 1723 -j CT --helper pptp

Det andra alternativet är att föredra. Det begränsar beteendet till PPTP-trafik i stället för att återaktivera automatisk tilldelning på hela routern.

Att öppna ett protokoll som inte har några portar

En brandväggsregel som tillåter 1723 säger ingenting om protokoll 47. På firewalld tillåter du protokollet i zonen som vetter mot klienten. På vanlig iptables accepterar du protokoll gre i indata-kedjan.

Fånga sedan på båda sidor. Paket som lämnar klienten utan att svar kommer in betyder att returvägen filtreras, och det är ett annat fel än avvisade inloggningsuppgifter.

Efter att den anslutit, storleksgränsen

GRE infogar en header, och PPP inuti lägger till mer, så en fungerande länk rapporterar en MTU en bra bit under 1500. Små svar laddas och stora fastnar, vilket ser ut som ett andra, orelaterat problem som dyker upp i samma ögonblick som det första är löst.

Läs MTU:n på klientens PPP-adapter och stäm av den mot routerns egen beräkning i stället för att sänka talen tills något fungerar. Paket i full storlek som går ut utan att något kommer tillbaka pekar på den gränsen och inte på översättningen.

Att reparera vägen får användaren att fungera, och det gör inte PPTP till ett bra val. MS-CHAPv2 och RC4 är sedan länge utdaterade, så behandla modulladdningen som en tillfällig rättelse och planera ett byte till ett underhållet protokoll.

Relaterade artiklar