Tường lửa VPS: chỉ mở cổng VPN, rồi chứng minh điều đó
Một cổng phải giữ công khai, nếu không sẽ chẳng có máy khách nào kết nối được. Từ chối phần còn lại, tách phần chuyển tiếp khỏi phần đầu vào, và để lại một đường khôi phục mà bạn đã thử trước.
Một tường lửa chỉ cho phép cổng VPN không phải là một quy tắc. Đó là ba quyết định riêng biệt cùng liên quan đến một số cổng: chuỗi đầu vào quyết định cái gì có thể tới một tiến trình cục bộ, chuỗi chuyển tiếp quyết định cái gì có thể đi qua máy chủ thay cho các máy khách của đường hầm, và bảng NAT viết lại địa chỉ nguồn khi đi ra. Sai một trong số đó thì kết quả hiếm khi là một sự cố sạch sẽ. Bạn nhận được một máy chủ chấp nhận máy khách nhưng không tải được gì, hoặc một máy chủ trông như đã đóng cho tới khi ai đó đọc thứ tự các chuỗi.
Cổng duy nhất không thể đóng
Trình lắng nghe VPN phải chấp nhận kết nối từ những địa chỉ bạn không thể đoán trước, nên nó là dịch vụ công khai theo định nghĩa. Đây là ngoại lệ duy nhất mà thiết kế dựa vào: một cổng UDP cho OpenVPN, một cổng UDP cho WireGuard, một cổng TCP cho VPN SSL. Mọi thứ khác thuộc về phía sau đường hầm, nghĩa là các dịch vụ ứng dụng nên gắn với địa chỉ đường hầm hoặc loopback chứ không phải mọi giao diện.
Tuy nhiên gắn vào không phải là thực thi. Một tiến trình gắn với 0.0.0.0 chỉ tiếp cận được nếu một quy tắc cho phép, và chính sách mặc định là phương án dự phòng cho lưu lượng không khớp quy tắc nào, không phải quy tắc điều khiển cổng. Một lệnh cho phép đặt trên lệnh từ chối của bạn vẫn là cho phép, và việc chuyển một dịch vụ ra khỏi địa chỉ công khai là một cải tiến độc lập, không phải thứ thay thế cho chuỗi.
Đầu vào, chuyển tiếp và NAT trả lời những câu hỏi khác nhau
Lưu lượng đầu vào hướng tới chính máy chủ, nên trình lắng nghe VPN và đường quản trị sống ở đó. Lưu lượng chuyển tiếp đi qua máy chủ, và máy khách đường hầm cần nó cùng với net.ipv4.ip_forward=1. Cấu hình cổ điển hỏng một nửa cho phép luồng đi ra và quên chiều quay về, nên máy khách hoàn tất bắt tay rồi không tải được gì; một quy tắc conntrack cho lưu lượng đã thiết lập và liên quan bao phủ chiều đó.
NAT là câu hỏi thứ ba. Không có việc viết lại trong postrouting, các gói được chuyển tiếp đi ra với nguồn riêng của đường hầm và bị bỏ ở phía trên, vì không mạng nào ngoài máy chủ biết cách định tuyến nhóm địa chỉ trở lại. Tiền tố nguồn trong quy tắc đó phải khớp với nhóm VPN, không phải địa chỉ của chính máy chủ, và điều tương tự đúng với quy tắc chuyển tiếp nêu tên mạng con của máy khách.
IPv6 là chính sách thứ hai, không phải suy nghĩ sau. Một máy chủ có chuỗi IPv4 nghiêm ngặt và chính sách mở trên ip6tables chưa đóng được gì; các dịch vụ vẫn tiếp cận được qua họ địa chỉ còn lại. Hoặc phản chiếu bộ quy tắc bằng ip6tables, hoặc cố ý tắt IPv6 trên giao diện công khai, và ghi lại bạn đã chọn cách nào.
Một nền tảng đọc được trong một lượt
Hãy bắt đầu bằng việc từ chối, rồi chỉ thêm những gì máy chủ cần. Trước hết loopback và các phản hồi, sau đó đường quản trị, sau đó trình lắng nghe đường hầm, sau đó chính sách chuyển tiếp cho máy khách:
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
iptables -A INPUT -p udp --dport 1194 -m conntrack --ctstate NEW -j ACCEPT
sysctl -w net.ipv4.ip_forward=1
iptables -A FORWARD -i tun0 -o eth0 -s 10.8.0.0/24 -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADETên giao diện, cổng và nhóm địa chỉ là chỗ giữ chỗ; hãy đọc chúng từ máy chủ thay vì sao chép. Lưu kết quả quan trọng như viết ra, vì một bộ quy tắc chỉ sống trong bộ nhớ sẽ biến mất ở lần khởi động lại tiếp theo và lặng lẽ mở lại máy chủ. Hãy làm cho nó bền vững bằng cơ chế của bản phân phối, và giữ một bản sao ngoài máy cho ngày chiếc máy không khởi động.
Đóng cổng cuối cùng mà không mất máy chủ
Có một cái bẫy trong thiết kế. Nếu SSH chỉ tồn tại qua đường hầm, một dịch vụ VPN hỏng sẽ mang SSH đi theo, và đường trở về duy nhất có thể là một bảng điều khiển mà bạn chưa bao giờ mở. Trước khi đóng cổng công khai cuối cùng, hãy xác nhận bảng điều khiển đó tồn tại và bạn thực sự dùng được, hoặc giữ lại một đường quản trị hẹp không phụ thuộc đường hầm: SSH từ một địa chỉ cố định, chỉ dùng khóa, xác thực bằng mật khẩu đã tắt.
Hãy áp dụng thay đổi từ một phiên đã thiết lập, không phải qua kết nối mà bạn sắp lọc. Lên lịch quay lui để một sai sót hết hạn thay vì trở thành vĩnh viễn, ví dụ một tác vụ systemd-run --on-active=10min khôi phục bộ quy tắc trước đó, và giữ phiên SSH thứ hai mở trong khi thử cái đầu. Sau đó xác nhận tác vụ quay lui thực sự kích hoạt, vì khôi phục chưa thử cũng như không có khôi phục.
Kiểm chứng đường đi, không phải kịch bản
Hãy đọc các quy tắc đã nạp, không phải tệp lẽ ra phải nạp chúng. Từ một máy chủ bên ngoài được cấp phép, xác nhận rằng chỉ những cổng dự định mới trả lời; từ bên trong đường hầm, xác nhận rằng những dịch vụ bạn định công bố vẫn tiếp cận được. Một chính sách từ chối mặc định mà cũng chặn lưu lượng đường hầm trông giống hệt một sự khóa kín đang hoạt động cho tới khi ai đó thử dùng nó.
iptables -S
iptables -t nat -S
ss -lntup
ip -4 addr showGhi lại cổng được phép, nhóm máy khách, giao diện đường hầm, nguồn quản trị và quy trình bảng điều khiển bên cạnh cấu hình. Thay đổi tiếp theo về nhóm địa chỉ hoặc tên giao diện phải được khớp ở cả bộ lọc và quy tắc NAT, nếu không máy chủ quay về trạng thái nửa mở mà không ai nhận ra.
Một thói quen đáng giá hơn cả bộ quy tắc: sau mỗi thay đổi, hãy chứng minh đường chuyển tiếp bằng một yêu cầu từ máy khách và đường khôi phục bằng phiên thứ hai. Một sự khóa kín mà bạn chưa dùng chỉ là giả thuyết.