WireGuard DNS DNAT: giữ đường phản hồi hoạt động
DNAT ghi lại đích, không ghi lại nguồn. Hãy quyết định cách resolver thượng nguồn có thể trả lời trước khi thêm quy tắc, và giữ mỗi kết quả khớp thật hẹp.
Việc trỏ truy vấn DNS của một máy khách WireGuard sang resolver khác trông giống một quy tắc nhưng hành xử như ba quyết định. Đích phải được ghi lại, gói tin phải được chuyển tiếp, và câu trả lời phải tìm được đường quay về qua trạng thái dịch mà gateway đã tạo. Bỏ qua bước thứ ba thì truy vấn rời đi gọn ghẽ trong khi máy khách chờ mãi.
Hãy lấy ví dụ các máy khách được cấp phép trong 10.77.0.0/24 đến qua wg0, hỏi địa chỉ được quảng bá 10.77.0.1 và cần một resolver tại 203.0.113.53. Địa chỉ thượng nguồn là chỗ giữ chỗ cho tài liệu, không phải dịch vụ đang chạy.
Chuyển hướng truy vấn chỉ thay đổi đích của nó
Một quy tắc NAT đích trong PREROUTING ghi lại địa chỉ trước khi quyết định định tuyến được đưa ra, nên gói tin sau đó được định tuyến tới đích mới thay vì đích cũ. Địa chỉ nguồn của máy khách không bị thao tác đó chạm tới. Đó là lý do một quy tắc trông hoàn chỉnh vẫn có thể tạo ra sự im lặng: yêu cầu giờ đi tới một resolver chưa từng nghe về dải riêng của máy khách. Gateway đã dịch một trường và thừa hưởng vấn đề thứ hai.
Cả hai giao thức vận chuyển DNS đều cần quy tắc khớp, vì máy khách quay lại TCP khi câu trả lời bị cắt.
Các quy tắc dưới đây chọn một giao diện vào, một dải máy khách và một địa chỉ đích gốc. Không có gì khác trên gateway bị ảnh hưởng, và truy vấn của chính gateway hoàn toàn không khớp.
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A PREROUTING -i wg0 -s 10.77.0.0/24 -d 10.77.0.1 -p udp --dport 53 -j DNAT --to-destination 203.0.113.53:53
iptables -t nat -A PREROUTING -i wg0 -s 10.77.0.0/24 -d 10.77.0.1 -p tcp --dport 53 -j DNAT --to-destination 203.0.113.53:53
Đường phản hồi là một quyết định riêng
Hai cách sắp xếp cho phép câu trả lời quay về, và chọn sớm một cách sẽ tiết kiệm một phiên gỡ lỗi. Hoặc resolver thượng nguồn có tuyến quay về 10.77.0.0/24 qua gateway này, hoặc gateway dịch nguồn ở đầu ra để câu trả lời đến một địa chỉ mà phía thượng nguồn đã biết. Cả hai đều hoạt động; chỉ một cách khớp với mức kiểm soát bạn có đối với phía thượng nguồn.
Định tuyến đáng để thử trước, vì nó giữ địa chỉ của máy khách hiển thị với resolver và tránh lớp dịch thứ hai. Khi phía thượng nguồn nằm ngoài tầm kiểm soát của bạn, dịch nguồn trên giao diện đầu ra cụ thể là lựa chọn thực tế.
Hãy giới hạn việc dịch đó chặt như việc chuyển hướng, nếu không quy tắc sẽ trở thành NAT dùng chung cho bất cứ thứ gì tình cờ khớp với nó:
iptables -t nat -A POSTROUTING -s 10.77.0.0/24 -d 203.0.113.53 -o eth0 -p udp --dport 53 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 10.77.0.0/24 -d 203.0.113.53 -o eth0 -p tcp --dport 53 -j MASQUERADE
Theo dõi kết nối giữ ánh xạ theo cặp, nên câu trả lời được ghi lại về tuple gốc của máy khách trên đường quay về. Không có quy tắc đầu ra, resolver gửi câu trả lời tới một địa chỉ riêng mà nó không thể với tới, và máy khách thấy hết thời gian chờ thay vì lỗi.
Viết quy tắc hẹp hơn vẻ ngoài của công việc
Quyền chuyển tiếp thuộc cùng phạm vi. Hãy cho phép luồng từ máy khách tới resolver và lưu lượng quay về mà conntrack đã nhận ra, thay vì chấp nhận mọi kết nối DNAT trên máy. Việc chấp nhận toàn bộ cũng cho phép chuyển tiếp cổng không liên quan gì đến DNS.
Resolver của chính gateway là một đường mã khác. Truy vấn phát ra cục bộ đi qua OUTPUT, nên kiểm thử từ shell của gateway không rèn luyện quy tắc PREROUTING lẫn chính sách chuyển tiếp. Đó là lý do một bài kiểm tra cục bộ có thể đạt trong khi mọi máy khách đều thất bại, và điều ngược lại cũng phổ biến như vậy.
Không có gì ở đây bao gồm DNS qua HTTPS trên cổng 443 hay DNS qua TLS trên cổng 853, và không có gì bao gồm IPv6. Một máy khách có resolver IPv6 được cấu hình sẽ vui vẻ bỏ qua toàn bộ cách sắp xếp.
Một truy vấn mới chứng minh điều gì
Theo dõi kết nối nhớ các ánh xạ trước đó, nên một truy vấn gửi trước khi đổi quy tắc có thể được trả lời từ trạng thái cũ và làm quy tắc mới trông như hỏng. Hãy bắt đầu với một cổng nguồn mới và, ở nơi máy khách lưu đệm câu trả lời, với một tên mới.
dig @10.77.0.1 example.com A +short
conntrack -L -p udp --dport 53 | head
Lệnh đầu tiên cho thấy đường của máy khách có phân giải được hay không, lệnh thứ hai cho thấy bản dịch mà gateway thực sự đã cài, gồm cả hai chiều của tuple. Một ánh xạ trỏ đúng resolver nhưng bộ đếm phản hồi kẹt ở số không là vấn đề đường về chứ không phải vấn đề lọc.
Hãy xác nhận resolver biết những tên bạn mong đợi trước khi chuyển hướng bất cứ thứ gì. Một phương án thay thế trả lời tên công cộng nhưng không trả lời vùng riêng của bạn biến một lần tra cứu đang chạy thành NXDOMAIN trông như đường hầm hỏng. Hãy kiểm tra resolver trực tiếp, từ gateway, trước khi đường của máy khách được đưa vào. Và tài liệu tham chiếu phần mở rộng iptables ghi lại ngữ nghĩa DNAT và masquerade mà các quy tắc này dựa vào.