Đặt một dịch vụ trên máy tính xách tay sau NAT cấp nhà mạng, trỏ máy đó tới VPS qua VPN, và không ai bên ngoài tiếp cận được. Bạn thêm một quy tắc NAT đích trên VPS và nhận được thứ tệ hơn sự im lặng: kết nối mở ra rồi khựng lại. Phản hồi không hề mất, nó đang đi ra theo tuyến mặc định của chính máy khách, nghĩa là máy chủ không bao giờ thấy nó. Hãy làm năm bước kiểm tra này theo thứ tự và dừng ở bước đầu tiên không đứng vững.

Xác nhận máy chủ có chuyển tiếp hay không

Đánh dấu ô này trước khi viết dù chỉ một bản dịch. Quy tắc DNAT cho gói tin mà nhân từ chối chuyển tiếp được bộ phân tích quy tắc chấp nhận rồi bị đường chuyển tiếp bỏ đi, tạo ra một thời gian chờ trông như sự cố tường lửa.

sysctl net.ipv4.ip_forward
sysctl -w net.ipv4.ip_forward=1

Đặt nó trong nhân đang chạy không giống với đặt nó qua một lần khởi động lại. Ghi net.ipv4.ip_forward=1 vào một tệp dưới /etc/sysctl.d/, chạy sysctl --system, rồi đọc lại giá trị thay vì tin rằng tệp đã được nạp. Một container tự quản lý không gian tên mạng của nó cần cùng giá trị đó bên trong không gian ấy, không chỉ trên máy chủ.

Nếu đọc lại vẫn là không, hãy dừng ở đây. Không gì bên dưới sẽ hoạt động.

Ghim địa chỉ đường hầm trước khi bất kỳ quy tắc nào tham chiếu tới nó

Bể địa chỉ cấp phát theo thứ tự kết nối, nên một quy tắc viết cho phiên thuê hôm nay có thể lặng lẽ trỏ sang máy khách khác vào tuần sau. Hãy gắn địa chỉ với danh tính chứng chỉ thay vì với thứ tự đến.

client-config-dir /etc/openvpn/ccd
ifconfig-push 10.77.0.14 10.77.0.13

Cặp đó là đầu máy khách và đầu đối tác của một đường hầm điểm-điểm, với máy chủ được khóa theo tên chung của chứng chỉ. Trong cấu trúc mạng con, giá trị thứ hai được đọc như mặt nạ mạng, nên hãy viết dạng khớp với cấu trúc đang dùng. Sau đó kết nối lại máy khách và đọc địa chỉ trên chính máy khách, vì góc nhìn của máy chủ về bể địa chỉ không chứng minh điều máy khách đã cấu hình.

Nếu địa chỉ thay đổi sau khi kết nối lại, hãy dừng. Một quy tắc NAT bám theo mục tiêu di động sẽ hỏng từng lúc và không dạy cho bạn điều gì.

Dịch theo cả hai chiều

Dịch đích gửi gói tin đi vào tới máy khách. Dịch nguồn chính là thứ khiến máy khách trả lời máy chủ thay vì người gửi ban đầu, và đó là quy tắc mà mọi người bỏ sót.

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 29443 -j DNAT --to-destination 10.77.0.14:29443
iptables -t nat -A POSTROUTING -d 10.77.0.14 -p tcp --dport 29443 -j SNAT --to-source 10.77.0.13

Không có quy tắc thứ hai, máy khách trả lời qua đường lên của nhà cung cấp dịch vụ, nên đối tác ở xa thấy một địa chỉ nguồn mà nó chưa từng nói chuyện, trong khi máy chủ không giữ mục theo dõi nào cho phản hồi. Người quan sát bên ngoài thấy một cái bắt tay hoàn tất một nửa, và đó chính là triệu chứng khiến người ta đi tìm một lỗi tường lửa không hề tồn tại.

Đọc lại cả hai quy tắc bằng iptables -t nat -S và xác nhận tên giao diện là cái mang địa chỉ công cộng. Trên máy chủ đã lọc bằng nftables, hãy viết bản dịch vào một chuỗi NAT của nftables thuộc họ địa chỉ tương ứng thay vì trộn lẫn công cụ.

Cho bảng lọc đi qua

Các bảng NAT viết lại phần tiêu đề; chúng không cấp quyền. Với chính sách DROP mặc định, luồng được chuyển tiếp cần sự chấp nhận riêng, cộng với chiều quay về mà hầu hết chính sách đã phủ bằng quy tắc established,related.

iptables -A FORWARD -i eth0 -o tun0 -p tcp --dport 29443 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Kiểm tra chính sách của chuỗi FORWARD trước khi thêm bất cứ điều gì, vì thứ tự của một DROP sớm quyết định quy tắc của bạn có bao giờ được xét hay không. Trên máy chủ có việc lọc nằm trong nftables, hãy thêm quy tắc tương đương vào móc forward của bảng inet và xác nhận chuỗi cơ sở thực sự thấy lưu lượng được chuyển tiếp chứ không chỉ đầu vào cục bộ. Nếu bộ đếm gói tin trên quy tắc mới vẫn bằng không trong khi bộ đếm NAT tăng, gói tin đang bị bỏ trước quy tắc của bạn. Đó là dấu hiệu để đọc thứ tự chuỗi, không phải để thêm bản sao thứ hai của cùng quy tắc.

Chứng minh điều đó từ một mạng bên ngoài

Hãy thử từ một mạng không liên quan. Một phép dò từ máy khác trong cùng LAN có thể đi qua hỗ trợ NAT kẹp tóc và không bao giờ thực hành đường đi mà máy khách ở xa dùng, nên một kết quả xanh ở đó chứng minh điều sai.

tcpdump -ni any port 29443
conntrack -L | grep 29443

Chạy bắt gói trên máy chủ và trên máy khách cùng lúc. Bản bắt trên máy chủ cho thấy gói tin đã dịch có đi ra phía đường hầm không; bản bắt trên máy khách cho thấy yêu cầu có đến và phản hồi được gửi tới đâu. Một mục dịch trong conntrack -L chứng minh quy tắc đã khớp, và sự vắng mặt của nó chứng minh gói tin chưa bao giờ tới chuỗi NAT.

Máy quét cổng là bằng chứng yếu. Chúng báo cổng đóng cho tới khi ứng dụng được gắn và lắng nghe, nên hãy dùng một kết nối thật tới dịch vụ thật. Khi nó cuối cùng hoạt động, hãy giữ phơi nhiễm ở đúng cổng đó: chuyển tiếp SSH hay bảng quản trị vì quy tắc đầu tiên có vẻ khó xử là một quyết định lớn hơn nhiều so với việc công bố một dịch vụ.

Bài viết liên quan