Bật một máy khách OpenVPN toàn đường hầm trên máy bạn truy cập qua SSH có thể cắt phiên trong vòng một giây, và máy không hề làm gì sai. Đường hầm không đổi cách gói tin đến máy chủ; nó đổi cách các phản hồi đi ra. Ngay khi tuyến mặc định trỏ tới tun0, phản hồi cho máy khách SSH của bạn đi vào mạng của nhà cung cấp, mạng này không có tuyến quay về địa chỉ của bạn. Kết nối bị treo, lần thử tiếp theo hết thời gian, và tiến trình nền vẫn lắng nghe trên cổng 22 suốt thời gian đó.

Đọc bảng định tuyến trước khi đọc nhật ký VPN. Nhật ký sẽ nói đường hầm đã lên, và nó đúng. Câu hỏi là mỗi phản hồi được giao cho giao diện nào, và đó là một lần tra cứu cho từng gói trong bảng mà đường hầm vừa ghi lại.

Vì sao phản hồi đi ra sai cửa

Các gói vào vẫn đến trên giao diện vật lý, vì máy khách VPN không thể đổi cách internet đến địa chỉ công khai của máy chủ bạn. Phản hồi là một quyết định riêng: với mỗi gói, nhân hệ điều hành tra đích, và sau --redirect-gateway mục mặc định nói đường hầm. Cửa ra của nhà cung cấp thấy một đích mà nó không phục vụ và bỏ gói đó.

Lớp bảo vệ của chính OpenVPN chỉ phủ đúng một đích. Sổ tay 2.6 mô tả --redirect-gateway như một chuỗi: thêm tuyến tới máy chủ cho peer VPN qua cổng đã dùng trước đường hầm, để lưu lượng mã hóa không thể vòng lại vào chính nó, rồi thay thế tuyến mặc định. Tuyến tới máy chủ đó chỉ dành cho peer. Máy khách SSH của bạn chỉ là một địa chỉ internet khác và không nhận ngoại lệ nào.

Đáng loại trừ sớm một lỗi tiền tố. ip route add -net 0.0.0.0 gw 10.8.0.1 dev tun0 không có độ dài chỉ khớp với địa chỉ đơn 0.0.0.0, không khớp với internet; phải là 0.0.0.0/0. Và nếu việc lấy tuyến mặc định phá vỡ chính đường truyền của đường hầm, hãy thêm điểm cuối như một tuyến tới máy chủ qua giao diện vật lý, dùng địa chỉ thật của nhà cung cấp.

Ghim địa chỉ máy khách SSH để sửa ngay

Cách sửa nhanh nhất là một tuyến tới máy chủ cho địa chỉ máy khách của bạn qua cổng mà máy chủ dùng trước khi có đường hầm. Về phía bạn, hãy tìm địa chỉ mà máy chủ sẽ thấy, rồi đọc bảng của máy chủ để biết cổng cũ:

curl -s https://ifconfig.co
ip route

Trên máy chủ, thêm ngoại lệ trước khi máy khách khởi động. Các địa chỉ ở đây là chỗ giữ chỗ; hình dạng mới là điều quan trọng:

sudo ip route add 80.128.240.55 via 192.168.178.1

Đây là cách sửa được dùng trong ca được báo cáo, và nó có hiệu lực ngay. Nó cũng mong manh theo hai cách dễ đoán: tuyến biến mất khi khởi động lại, và nó sai ngay khi ISP cấp cho bạn địa chỉ khác. Hãy coi đó là biện pháp khẩn cấp và cố ý làm cho nó bền, qua một đơn vị mạng hoặc móc dispatcher, hoặc chấp nhận rằng nó tạm thời và ghi lại đường khôi phục.

Đừng để máy khách lấy tuyến mặc định

Lựa chọn sạch hơn là không để đường hầm thay thế tuyến mặc định. route-nopull, dùng với --client hoặc --pull, chấp nhận các tùy chọn được đẩy trừ tuyến, block-outside-dns và các tùy chọn kiểu DHCP như máy chủ DNS, nên bạn chỉ thêm những tiền tố cần thiết. Công cụ hẹp hơn là bộ lọc kéo, nó bỏ một chỉ thị có vấn đề và giữ phần còn lại:

route-nopull
pull-filter ignore "redirect-gateway"

Hãy dùng một trong hai, không dùng cả hai, và hiểu rõ điều gì thay đổi. Không có tuyến mặc định qua đường hầm, máy chủ không còn duyệt internet qua nhà cung cấp nữa; nó chỉ đến những gì bạn định tuyến rõ ràng. Nếu toàn đường hầm chính là toàn bộ mục đích của cấu hình, thì đây là công tắc sai và tuyến tới máy chủ ở trên mới đúng.

Tách đường trả về theo nguồn hoặc theo kết nối

Khi địa chỉ vào ổn định, một quy tắc nguồn giữ phản hồi ở cục bộ mà không chạm vào các tuyến của chính đường hầm. Gán cho địa chỉ giao diện vật lý một bảng riêng chứa tiền tố LAN và tuyến mặc định vật lý, rồi chọn bảng đó cho lưu lượng xuất phát từ nó:

ip rule add from 192.168.1.11 table 128
ip route add table 128 to 192.168.1.0/24 dev eth0
ip route add table 128 default via 192.168.1.1

Điều này hiệu quả vì phản hồi cho một kết nối SSH vào xuất phát từ địa chỉ mà máy khách đã kết nối. Ca được báo cáo, nơi mọi dịch vụ vào đều phải tiếp tục chạy, đã dùng đúng hình dạng này. Khi địa chỉ vào thay đổi hoặc đường đi động, hãy đánh dấu kết nối thay vào đó: đặt dấu conntrack lên gói đầu tiên đến từ giao diện vật lý, sao chép nó sang các gói phản hồi trong OUTPUT, và định tuyến các gói đã đánh dấu qua một bảng trỏ tới cổng vật lý.

iptables -t mangle -A PREROUTING -i eth0 -m conntrack --ctstate NEW -j CONNMARK --set-mark 1234
iptables -t mangle -A OUTPUT -m connmark --mark 1234 -j MARK --set-mark 4321
ip route add default via 192.168.1.1 dev eth0 table 3412
ip rule add fwmark 4321 table 3412

Giữ riêng dấu kết nối, dấu tường lửa và số bảng khi thử nghiệm. Dùng lại một số cho hai vai trò tạo ra một quy tắc trông đúng mà lại khớp với các gói sai. Mục mặc định của bảng cũng cần via cùng cổng LAN trên một liên kết Ethernet thường; dev eth0 trần chỉ chạy khi giao diện là điểm-điểm hoặc bước nhảy kế tiếp được giải theo cách khác. Máy chủ Jessie được báo cáo tình cờ nằm trên một liên kết nơi dạng trần chạy được, và đó không phải quy tắc phân phối để sao chép.

Kiểm chứng mà không tự khóa mình ra ngoài

Đừng thử bằng cách ngắt kết nối. Giữ phiên đầu tiên mở, dựng đường hầm lên, và hỏi nhân hệ điều hành xem địa chỉ của chính bạn sẽ đi đường nào:

ip route get 80.128.240.55

Câu trả lời phải nêu giao diện vật lý và cổng cũ, không phải đường hầm. Rồi mở kết nối SSH thứ hai; đó mới là phép thử thật, vì phiên cũ có thể sống sót trên trạng thái mà kết nối mới không tái tạo được. Nếu cái thứ hai treo trong khi cái thứ nhất vẫn trả lời, quy tắc chưa từng khớp với lưu lượng quan trọng, và dấu hoặc địa chỉ nguồn là chỗ cần xem.

Giữ một bảng điều khiển ngoài băng trong suốt bài tập. Một máy chủ mà đường truy cập duy nhất là đường hầm bạn vừa làm đứt thì không thể sửa qua chính đường hầm đó, và việc quay lui dễ hơn khi bạn đã ghi lại số bảng và tiền tố đã thêm.

Bài viết liên quan