Ai đó chuyển tiếp 1723, máy khách đến được máy chủ, quá trình xác thực bắt đầu, rồi mọi thứ dừng lại mà không có lỗi. Kết luận tự nhiên là sai mật khẩu, nên mật khẩu được gõ lại ba lần. Việc chuyển tiếp vẫn ổn và thông tin đăng nhập vẫn ổn. Thứ hỏng là một giao thức thứ hai mà việc chuyển tiếp chưa bao giờ bao phủ, và một giá trị mặc định của nhân đã lặng lẽ thôi hỗ trợ nó.

Việc chuyển tiếp chưa bao giờ là vấn đề

Một quy tắc chuyển tiếp cổng mô tả lưu lượng TCP hoặc UDP. Nó không thể mô tả tải trọng chuyển sang giao thức IP khác giữa phiên, và PPTP làm đúng như vậy.

Đó là lý do kết nối trông khỏe mạnh cho đến đúng khoảnh khắc nó treo. Phần mà quy tắc cổng có thể quản lý đã thành công, và phần nó không thể quản lý chính là phần đã thất bại.

TCP cho điều khiển, GRE cho dữ liệu

Cuộc gọi được thương lượng qua TCP 1723. Khi đã lên, tải trọng chuyển vào GRE, giao thức IP 47, thứ không mang bất kỳ số cổng nào. Một quy tắc dựa trên cổng không có gì để so khớp.

Thứ GRE mang theo là một định danh cuộc gọi trong phần đầu của nó, và bộ dịch NAT phải viết lại trường đó một cách nhất quán ở cả hai chiều, nếu không hai nửa của phiên thôi thống nhất với nhau. Viết lại một chiều mà chiều kia không thì tạo ra phiên xác thực được rồi vứt bỏ mọi gói dữ liệu. Đó chính xác là hình dạng của triệu chứng: thành công, rồi im lặng.

GRE trần không có PPTP không cần việc viết lại như vậy, nên một đường hầm GRE thông thường có thể hoạt động qua bộ định tuyến vốn thất bại với máy khách PPTP trên cùng đường đi.

Bốn mô-đun và một sysctl đã tắt chúng

Hai mô-đun xử lý việc đóng khung, nf_conntrack_proto_gre và nf_nat_proto_gre. Hai mô-đun nữa xử lý định danh cuộc gọi, nf_conntrack_pptp và nf_nat_pptp. Nạp mô-đun cuối sẽ kéo các mô-đun còn lại qua phụ thuộc, nên danh sách mô-đun phải hiển thị cả bốn.

Hướng dẫn cũ dùng tiền tố ip_ từ thời 2.6. Những lệnh đó có thể trông như đang chạy mà không nạp gì, nên hãy kiểm tra danh sách đã nạp thay vì mã thoát.

Đã nạp chúng là không còn đủ. Từ Linux 4.7 sysctl net.netfilter.nf_conntrack_helper mặc định là 0, điều này tắt việc gán helper tự động cho các luồng mới. Một bộ định tuyến có thể có đủ mọi mô-đun mà vẫn không dịch gì. Kiểm tra giá trị hiệu lực trước khi xem lại danh sách mô-đun.

Hoặc bật lại việc gán tự động trên toàn cục, hoặc gắn helper vào những luồng cần nó và để yên mọi thứ khác:

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

Lựa chọn thứ hai đáng ưu tiên hơn. Nó giới hạn hành vi cho lưu lượng PPTP thay vì bật lại việc gán tự động trên toàn bộ bộ định tuyến.

Mở một giao thức không có cổng

Một quy tắc tường lửa cho phép 1723 không nói gì về giao thức 47. Trên firewalld, cho phép giao thức ở vùng hướng về máy khách. Trên iptables thường, chấp nhận giao thức gre trong chuỗi đầu vào.

Sau đó bắt gói ở cả hai phía. Các gói rời máy khách mà không có phản hồi nào đến nghĩa là đường quay về đang bị lọc, và đó là lỗi khác với thông tin đăng nhập bị từ chối.

Sau khi kết nối, giới hạn kích thước

GRE chèn một phần đầu, và PPP bên trong thêm nữa, nên một liên kết hoạt động báo MTU thấp hơn 1500 khá nhiều. Các phản hồi nhỏ tải được còn phản hồi lớn thì khựng, trông như một vấn đề thứ hai không liên quan xuất hiện đúng lúc vấn đề đầu tiên được giải quyết.

Đọc MTU trên bộ điều hợp PPP của máy khách và đối chiếu nó với phép tính của chính bộ định tuyến thay vì hạ các con số cho đến khi có gì đó chạy. Các gói kích thước đầy đủ đi ra mà không có gì quay lại chỉ vào giới hạn đó chứ không phải việc dịch địa chỉ.

Sửa lại đường đi giúp người dùng làm việc trở lại, và điều đó không làm PPTP thành lựa chọn tốt. MS-CHAPv2 và RC4 đã lỗi thời từ lâu, nên hãy coi việc nạp mô-đun là bản vá tạm thời và lên kế hoạch chuyển sang một giao thức được duy trì.

Bài viết liên quan