Chặn một dải đích cho mỗi nhóm khách hàng VPN
Một quy tắc nftables duy nhất có thể từ chối tiền tố đích cho một nhóm VPN đã được chấp nhận mà không động đến lưu lượng của chính cổng. Khớp đúng hook và vị trí.
Một quy tắc có thể giữ một nhóm VPN đã được chấp nhận tránh xa một dải đích mà không làm xáo trộn bất cứ điều gì khác mà cổng làm. Bản thân quy tắc thì ngắn; những phần quyết định nó có hoạt động hay không là hook nơi nó sống và vị trí của nó trong chuỗi. Làm sai hai điều đó sẽ cho ra một tường lửa trông có vẻ đúng nhưng hành xử không nhất quán. Hãy bắt đầu từ việc gói tin đang làm gì khi quy tắc nhìn thấy nó.
Quy tắc thực sự khớp những gì
Quy tắc khớp ba thứ cùng lúc: giao diện vào, tiền tố nguồn và tiền tố đích. Cả ba phải đúng trước khi drop được áp dụng, và đó là điều giữ nó hẹp. Đọc nó như một biểu thức dễ hơn là như ba chính sách riêng rẽ.
Việc khớp giao diện là thứ phân biệt lưu lượng khách hàng được chuyển tiếp với các kết nối của chính cổng. Không có nó, một quy tắc chỉ nêu nhóm nguồn cũng sẽ ảnh hưởng đến các gói mà chính cổng tạo ra từ địa chỉ đó, nếu điều đó từng xảy ra. Tiền tố nguồn giới hạn chính sách trong các khách hàng đã được chấp nhận, và tiền tố đích giới hạn nó trong một dải. Hãy đọc quy tắc như một giao, không phải một danh sách.
Ghi lại ba giá trị trước khi sửa bất cứ điều gì: tên giao diện đường hầm, nhóm mà máy chủ phân phát, và tiền tố bạn định từ chối. Một lỗi đánh máy ở bất kỳ giá trị nào cũng tạo ra một quy tắc được phân tích sạch sẽ mà chẳng bảo vệ gì. Giữ ba giá trị đó trong biên bản thay đổi bên cạnh quy tắc.
Hook quyết định quy tắc áp dụng cho ai
Một chuỗi netfilter được gắn vào một hook, và hook quyết định chuỗi có nhìn thấy những gói tin nào. Hook forward thấy lưu lượng được định tuyến qua cổng, và đó chính là lưu lượng từ khách hàng đến đích. Mọi thứ khác trong chuỗi đều hướng đến một đối tượng khác.
Hook input thấy lưu lượng được gửi đến chính cổng, nên một quy tắc đặt ở đó điều khiển việc truy cập các dịch vụ của nó chứ không phải lưu lượng chuyển tiếp. Hook output thấy lưu lượng do chính cổng tạo ra, tức là ngược lại với điều một chính sách nhóm khách hàng cần. Tên chuỗi là những nhãn tùy ý do người viết bộ quy tắc chọn, nên đừng suy ra hook từ tên. Hãy kiểm tra chuỗi được gắn ở đâu trước khi giả định nó có thể khớp những gì.
| Hook | Traffic it sees | Right for this policy |
|---|---|---|
| input | Addressed to the gateway | No, that is the host's own services |
| forward | Routed through the gateway | Yes, for client-to-destination traffic |
| output | Generated by the gateway | No, that is the opposite direction |
Đọc điểm gắn là một bước kiểm tra một dòng, ngăn một quy tắc rơi vào một chuỗi không bao giờ thấy gói tin.
Đặt quy tắc trước accept rộng
Các quy tắc được đánh giá theo thứ tự, và phán quyết đầu tiên thắng. Một accept rộng ở phía trước trong chuỗi kết thúc việc đánh giá đối với các gói mà nó khớp, nên một drop thêm vào sau đó sẽ không bao giờ chạy cho chúng. Chính quy tắc thứ tự đó là toàn bộ lý do một quy tắc trông đúng lại có thể không có tác dụng.
Hãy chèn quy tắc trước accept thay vì thêm nó vào cuối. Nếu chuỗi đã chứa một accept tổng quát cho giao diện đường hầm, quy tắc mới phải đứng trước nó, nếu không nó chỉ là đồ trang trí. Kiểm tra thứ tự thu được chứ không phải tệp bạn đã sửa, vì một bộ quy tắc ghép từ nhiều tệp có thể không khớp với bất kỳ tệp nào. Sau đó xác nhận bằng một gói thử từ nhóm.
sudo nft list chain inet filter forward
sudo nft insert rule inet filter forward iifname "tun0" ip saddr 10.90.0.0/24 ip daddr 198.51.100.0/24 drop
sudo nft -c -f /etc/nftables.conf
Lệnh thứ ba phân tích tệp mà không áp dụng nó, nhờ đó bắt được lỗi cú pháp trước khi chúng thành sự cố. Hãy áp dụng kèm một kế hoạch hoàn tác, vì một quy tắc sai trong chuỗi forward có thể cắt đứt đường hầm mà bạn đang làm việc qua đó.
Các luồng hiện có không quan tâm đến quy tắc mới của bạn
Một mục conntrack được tạo trước khi quy tắc tồn tại vẫn tiếp tục khớp với accept trước đó. Đó là lý do một drop mới đôi khi có vẻ hoạt động với các kết nối mới và không làm gì với kết nối đang được kiểm tra.
Đọc mục khớp trạng thái ở đầu chuỗi. Nếu nó chấp nhận lưu lượng established và related trước quy tắc của bạn, mọi luồng đang chạy sẽ tiếp tục chảy cho đến khi đóng. Thông thường đó là hành vi bạn muốn cho một quy tắc khẩn cấp, và nó gây bối rối khi bạn mong đợi cắt ngay lập tức. Hãy quyết định hiệu ứng bạn muốn trước khi triển khai. Một bài kiểm tra dùng lại kết nối đang mở sẽ kể cho bạn câu chuyện sai.
sudo conntrack -L -s 10.90.0.14 -d 198.51.100.20
sudo nft list ruleset | grep -n -A3 'ct state'
Lệnh thứ nhất cho biết có một luồng hay không, và lệnh thứ hai cho biết một quy tắc trạng thái sớm có còn chấp nhận nó hay không. Cả hai đều chỉ đọc và an toàn khi chạy trong sự cố.
Điều mà quy tắc này không phải
Quy tắc này không phải danh sách đen tên miền, không phải chính sách IPv6, cũng không phải hạn chế trên một tài khoản ứng dụng riêng lẻ.
Mỗi thứ đó cần cơ chế riêng. Chặn tên miền phải phân giải tên, điều mà bộ lọc gói không làm. Lưu lượng IPv6 cần cách khớp riêng, vì biểu thức ip không nói gì về gói ip6. Một hạn chế ở tầng ứng dụng thuộc về dịch vụ hoặc một proxy đã xác thực, không phải về khớp tiền tố. Việc tách riêng các yêu cầu đó chính là điều ngăn một quy tắc hẹp bị yêu cầu làm bốn việc.
Hợp đồng mà quy tắc này cung cấp là chính xác: lưu lượng từ một nhóm đã được chấp nhận đến một tiền tố đích bị từ chối, trong khi lưu lượng không liên quan của cổng giữ nguyên chính sách hiện có. Hãy viết câu đó bên cạnh quy tắc, và người tiếp theo sẽ biết nó dùng để làm gì.