Chặn một máy khách OpenVPN khỏi LAN mà không dừng đường hầm
Ghim địa chỉ đường hầm của máy khách vào chứng chỉ, thả lưu lượng LAN của nó ở đầu FORWARD, rồi kiểm tra IPv6, các phiên được theo dõi và khả năng sống sót sau khi khởi động lại.
Một máy khách trên máy chủ OpenVPN của bạn phải mất quyền truy cập LAN trong khi mọi đường hầm khác vẫn hoạt động. Nếu bạn tìm kiếm điều này, câu trả lời hay nhất thường nói daemon không làm được, điều đó chỉ đúng một nửa: OpenVPN không có tường lửa cho từng máy khách, nhưng máy chủ kết thúc đường hầm đã lọc gói tin. Hai quyết định quan trọng là danh tính bạn chặn và vị trí của quy tắc. Làm đúng hai điều này và thay đổi trở thành một dòng bạn có thể kiểm tra và gỡ bỏ.
Ghim máy khách trước khi viết quy tắc
OpenVPN cho thuê địa chỉ đường hầm từ một nhóm, vì vậy 10.8.0.6 là một chỗ ngồi, không phải một người. Khi phiên kết thúc, hợp đồng thuê trở lại và có thể được cấp cho kết nối tiếp theo, nghĩa là một quy tắc viết theo địa chỉ đó đi theo chỗ ngồi, không phải người dùng. Vì vậy trước tiên hãy quyết định bạn thực sự chặn cái gì: một địa chỉ cho thử nghiệm ngắn, hay một chứng chỉ cho người bạn muốn giữ bên ngoài.
Để gắn địa chỉ với chứng chỉ, hãy tạo một tệp trong thư mục mà client-config-dir chỉ định và đặt cho tệp đúng common name của chứng chỉ. Đặt vào đó một chỉ thị, ifconfig-push 10.8.0.6 255.255.255.0, và máy khách đó giữ nguyên địa chỉ đường hầm khi kết nối lại. Hai thiết lập phải tồn tại để điều này có hiệu lực: client-config-dir phải được khai báo trong cấu hình máy chủ, và địa chỉ được đẩy phải nằm trong một mạng con mà máy chủ có thể định tuyến. Thiếu một cái là tệp bị bỏ qua mà không báo lỗi, khiến lần kiểm tra tường lửa tiếp theo gây hiểu nhầm.
Một lần chặn tạm thời có thể dùng địa chỉ trong nhóm, miễn là phiếu ghi lại phiên nào đã giữ nó vào lúc đó.
Thứ tự quyết định việc thả có chạy hay không
Trên một cổng Linux chuyển tiếp giữa đường hầm và LAN, các gói tin đi qua chuỗi FORWARD. Hãy đọc lệnh dưới đây như một câu: chèn vào đầu FORWARD, khớp lưu lượng đi vào từ tun0, từ đúng máy chủ đó, hướng tới mạng con LAN, và thả nó.
iptables -I FORWARD -i tun0 -s 10.8.0.6/32 -d 192.168.1.0/24 -j DROP-I là thứ làm cho quy tắc chạy. Thêm bằng -A, nó nằm dưới mọi chấp nhận rộng cho mạng con đường hầm và không bao giờ thấy gói tin. Kiểm tra vị trí bằng iptables -vnL FORWARD --line-numbers, và đọc cả bộ đếm: một lần thả ở trên cùng mà không đếm gì nghĩa là lưu lượng đang đến bằng đường khác.
Địa chỉ LAN của chính cổng là một đường khác. Các gói tin gửi tới chính hộp đi vào INPUT, không phải FORWARD, nên một máy khách có thể mất một máy chủ LAN mà vẫn mở được trang quản trị của router. Hãy thêm quy tắc INPUT tương ứng khi điều đó quan trọng.
Những gì bộ lọc không thấy
Việc lọc xảy ra khi gói tin được đánh giá, nên một phiên TCP đã thiết lập có thể tiếp tục cho đến khi đóng hoặc bị đặt lại. Nếu việc chặn phải có hiệu lực ngay, hãy xóa các luồng được theo dõi của nguồn đó bằng conntrack -D -s 10.8.0.6 sau khi đặt quy tắc. Nếu chấp nhận được vài giây chồng lấn, hãy ghi lại lựa chọn đó thay vì để nó ngầm hiểu. Dù thế nào, người tiếp theo cần biết quy tắc dừng lưu lượng đang sống hay chỉ các kết nối mới.
Lưu lượng giữa các máy ngang hàng không bao giờ chạm tường lửa của máy chủ. Khi bật client-to-client, OpenVPN chuyển các gói đó bên trong daemon, nên cả FORWARD lẫn INPUT đều không thấy chúng. Cách duy nhất là tắt client-to-client hoặc chấp nhận rằng các máy ngang hàng có thể đến được nhau; quy tắc iptables sẽ không thấy lưu lượng đó.
IPv6, firmware và khả năng sống sót sau khởi động lại
Một quy tắc IPv4 không nói gì về IPv6. Nếu đường hầm và LAN mang cả hai họ, quy tắc tương đương phải tồn tại trong ip6tables, hoặc trong bộ quy tắc nftables sở hữu chính sách trên máy chủ đó. Firmware của router thường giấu netfilter sau lớp trừu tượng của riêng nó, nên cú pháp và tên bảng sao chép từ diễn đàn có thể không áp dụng.
Trên OpenWrt, con đường được ghi nhận là một mục cấu hình tường lửa chứ không phải dòng iptables viết tay, và một dòng viết tay có thể biến mất khi tường lửa tải lại. Các bản phân phối khác khôi phục quy tắc qua netfilter-persistent, một đơn vị khởi động hoặc kho của nhà cung cấp, và các cơ chế đó không thể thay thế cho nhau. Hãy chứng minh lựa chọn của bạn bằng một lần khởi động lại, vì việc tải lại chỉ luyện một con đường khác.
Kiểm tra theo từng đường, rồi quay lui sạch sẽ
Kiểm tra từng đường riêng biệt, vì một lần kiểm tra thành công che giấu những lần khác. Máy khách bị chặn vẫn phải đến được internet qua đường hầm nhưng thất bại với một máy chủ LAN, máy khách thứ hai phải đến được cùng máy chủ đó, và địa chỉ cổng cùng đường ngang hàng mỗi cái cần quan sát riêng. Hãy ghi kết quả bên cạnh quy tắc để thay đổi tiếp theo có đường cơ sở. Bảng dưới đây là tập hợp đáng giữ lại trong phiếu.
| Đường | Kỳ vọng khi có quy tắc | Khi thất bại |
|---|---|---|
| Máy khách bị chặn tới máy chủ LAN | Không có phản hồi | Quy tắc nằm dưới một chấp nhận, hoặc nguồn không khớp |
| Máy khách bị chặn tới internet | Hoạt động qua tun0 | Quy tắc quá rộng, không khớp đích |
| Máy khách thứ hai tới cùng máy chủ LAN | Hoạt động | Quy tắc khớp nhiều hơn máy chủ dự định |
| Máy khách bị chặn tới địa chỉ LAN của cổng | Chỉ bị chặn khi có quy tắc INPUT khớp | Thiếu quy tắc INPUT |
| Máy khách bị chặn tới địa chỉ đường hầm của máy ngang hàng | Vẫn hoạt động | client-to-client đang bật và nằm ngoài phạm vi tường lửa |
Quay lui là xóa theo đặc tả, không phải flush: iptables -D FORWARD -i tun0 -s 10.8.0.6/32 -d 192.168.1.0/24 -j DROP xóa đúng mục đó và để phần còn lại của chuỗi nguyên vẹn. Xóa cùng dòng đó khỏi bất kỳ tệp nào khôi phục quy tắc khi khởi động, tải lại nó, và xác nhận máy khách lại đến được máy chủ LAN. Flush FORWARD cũng sẽ hủy các quy tắc bạn không viết, biến việc quay lui thành sự cố thứ hai.
Trước khi đóng phiếu, hãy xác nhận ba điều: địa chỉ được ghim khớp với chứng chỉ, quy tắc nằm trên các chấp nhận với bộ đếm khác không, và tệp lưu trữ chứa đúng quy tắc bạn đã kiểm tra. Nếu thiếu bất kỳ điều nào, việc chặn chỉ là ảo ảnh trong một phiên shell.