Sửa DNS của khách libvirt bị tường lửa VPN dựa trên dấu chặn
Tường lửa VPN dựa trên dấu bỏ DNS của khách trước khi một chuỗi lọc nhìn thấy nó. Một quy tắc ưu tiên mangle đánh dấu truy vấn và câu trả lời, mà không mở LAN của bạn.
Khách trên mạng libvirt mặc định phân giải tên hoàn hảo cho đến khi giao diện WireGuard xuất hiện, và sau đó mọi lần tra cứu đều dừng ở cùng một chỗ. dnsmasq vẫn đang lắng nghe trên 192.168.122.1:53, khách vẫn dùng địa chỉ đó làm trình phân giải, và truy vấn vẫn đến. Điều đã thay đổi là truy vấn thượng nguồn của chính máy chủ, hoặc câu trả lời cho nó, giờ bị một quy tắc đánh giá trước bất kỳ chuỗi lọc nào bạn nghĩ mình sẽ sửa bỏ đi. Lối ra là một dấu được gắn đủ sớm, trên một kết nối mà câu trả lời thừa hưởng.
Khách mất DNS ngay khi đường hầm hoạt động
Xác nhận hình dạng trước khi thay đổi bất cứ thứ gì. Hạ đường hầm xuống, chạy dig @192.168.122.1 example.com từ một khách và xem nó trả lời. Dựng đường hầm lên, lặp lại, và xem nó hết thời gian. Cặp kết quả đó loại bỏ mạng libvirt hỏng, địa chỉ trình phân giải sai và dnsmasq đã chết trong một bước.
Sau đó xem phía máy chủ. Nếu dnsmasq ghi lại truy vấn và việc chuyển tiếp thượng nguồn của nó, gói đã đến và lỗi nằm ở chiều ra. Nếu dnsmasq không bao giờ ghi gì, truy vấn của khách đang bị bỏ ở chiều vào và ngoại lệ thuộc về một hook khác với hook mà bài viết này đánh dấu.
Vì sao một quy tắc accept trong chuỗi sau không bao giờ kích hoạt
Tường lửa VPN dựa trên dấu quyết định bằng cách nhìn vào dấu gói hoặc dấu kết nối, chứ không nhìn địa chỉ nguồn của bạn. Bất cứ thứ gì đến giao diện vật lý mà không có dấu mong đợi đều bị từ chối, và sự từ chối đó xảy ra trong tập quy tắc sở hữu phép thử dấu. ip saddr 192.168.122.0/24 accept dòng được thêm vào bất kỳ chuỗi nào sau đó đơn giản là không bao giờ được xem xét cho gói đó, nên quy tắc hiển nhiên trông có vẻ đúng mà không thay đổi gì.
Mở rộng nó cho đến khi có gì đó hoạt động là cái bẫy thứ hai. Chấp nhận toàn bộ mạng con libvirt trong đường vào của máy chủ sẽ mở mọi dịch vụ của máy chủ cho khách, trong khi nhu cầu thực tế chỉ là một cổng.
Cơ chế khiến một ngoại lệ hẹp trở nên khả thi là theo dõi kết nối. Khi bạn đặt ct mark trên một gói, giá trị được lưu trên mục conntrack chứ không chỉ trên gói, nên mọi gói trong kết nối đó mang nó về sau, kể cả câu trả lời từ máy chủ về lại khách. Đó là toàn bộ mẹo: đánh dấu yêu cầu một lần, và đường quay về đã được đánh dấu sẵn.
Đánh dấu truy vấn trước khi bảng VPN nhìn thấy nó
Đặt ngoại lệ vào bảng riêng của nó để người đọc sau này tìm thấy mà không phải phân tích các quy tắc VPN:
table inet allowedLocal {
chain guest_dns {
type filter hook input priority mangle; policy accept;
ip saddr 192.168.122.0/24 meta l4proto { tcp, udp } \
th dport 53 ct mark set 0x00000f41
}
}
priority mangle là âm, điều này đặt chuỗi này trước các chuỗi lọc thông thường mà gói VPN cài ở mức ưu tiên không. Thứ tự hook chính là thứ làm quy tắc có hiệu lực; cùng quy tắc đó trong một chuỗi xếp sau chuỗi VPN chỉ là đồ trang trí.
Bản thân con số dấu không di động được. Lấy giá trị mà các quy tắc VPN đã cài chấp nhận cho lưu lượng của chính chúng, đọc nó từ bộ quy tắc đang chạy, và dùng giá trị đó. Một dấu sai tạo ra quy tắc nạp sạch, khớp với mọi truy vấn và không cho gì vào.
Giữ cái lỗ rộng đúng bằng cổng 53
Như đã viết, điều này cho phép DNS từ mạng con libvirt đến máy chủ qua TCP hoặc UDP cổng 53 và không gì khác. Nó không cho khách ra internet ngoài đường hầm, và không cho máy chủ mở kết nối về phía khách. Nếu sau này một khách cần dịch vụ khác của máy chủ, hãy thêm một quy tắc riêng nêu tên cổng đích đó thay vì nới lỏng quy tắc này.
Hãy trung thực về thứ bạn đang đánh đổi. Một khách có thể đến được trình phân giải cũng có thể tuynen dữ liệu tùy ý qua các truy vấn DNS, và ngoại lệ này là một lỗ cố ý trong ranh giới VPN chứ không phải tuyên bố rằng mạng cục bộ đáng tin. Giới hạn nguồn ở 192.168.122.0/24 giữ cái lỗ đó tránh xa mọi mạng con cục bộ khác, và việc đếm truy vấn theo nguồn đó là rẻ nếu mối đe dọa quan trọng với bạn.
Làm cho nó tồn tại qua lần khởi động lại và chứng minh cả hai nửa
Một quy tắc gõ ở dấu nhắc shell sẽ biến mất ở lần khởi động sau, và một quy tắc được nạp sau khi giao diện VPN đã truyền lưu lượng sẽ thua cuộc đua ở kết nối đầu tiên. Đặt bảng vào cấu hình nftables lâu dài của máy chủ, hoặc vào một unit được sắp trước dịch vụ VPN, và kiểm tra thứ tự thay vì giả định.
Việc xác minh cần ba câu trả lời riêng biệt. Xác nhận chuỗi đã được nạp và xếp đầu tiên, xác nhận mục conntrack hiển thị dấu theo cả hai chiều, và xác nhận một lần tra cứu từ khách trả về một địa chỉ. Sau đó xác nhận nửa còn lại: lưu lượng web thông thường của khách đến một máy chủ công cộng vẫn thất bại khi đường hầm hạ xuống hoặc đang chặn. Nếu DNS hoạt động mà mọi thứ khác rò rỉ, quy tắc của bạn rộng hơn quy tắc trên.
Nếu tra cứu vẫn thất bại sau khi đã đặt dấu, hãy kìm lại mong muốn mở rộng nguồn. Kiểm tra dnsmasq chuyển tiếp đến đâu, trình phân giải của khách trỏ vào 192.168.122.1 hay vào một địa chỉ công cộng ai đó đã gõ, và liệu truy vấn có đến được máy chủ hay không. Đánh dấu cho gói vào và không gì khác, nên một thượng nguồn tồi hay một mạng ảo hỏng vẫn hỏng dù bạn thêm bao nhiêu quy tắc.