Hai khách hàng có thể cùng mở máy chủ nhảy và vẫn không có việc gì phải mở nhau. Chạm tới một dịch vụ là quyết định chuyển tiếp, còn chạm tới một peer là quyết định chính sách, và hầu hết các ngăn xếp VPN giữ hai thứ đó trong các đối tượng riêng. Không gì bạn cấu hình cho cái đầu tiên thực thi cái thứ hai. Vì vậy công việc không phải là thêm một quy tắc, mà là tìm đối tượng quyết định lưu lượng giữa các peer trên máy chủ này, viết lệnh từ chối ở đó và chứng minh nó từ một khách hàng.

Tuyến đường tới dịch vụ dùng chung không phải là sự cho phép giữa các peer

Quảng bá subnet của khách hàng cho một peer biết cách đặt gói tin lên dây về phía địa chỉ của một khách hàng khác. Gói tin đó có được giao hay không được quyết định sau đó, bởi thứ chuyển tiếp nó. Trên một cổng Linux đó là chuỗi FORWARD; bên trong một daemon trong không gian người dùng đó là bảng phiên của chính đường hầm. Một tuyến đường trả lời về khả năng chạm tới và để quyền cho phép nguyên vẹn.

Vì thế một kiểm tra cách ly chỉ đọc tuyến đường không chứng minh gì. Một /24 có thể được đẩy tới mọi khách hàng trong khi mọi gói tin giữa các peer bị bỏ tại móc chuyển tiếp. Trường hợp nguy hiểm là ngược lại: không có quy tắc rõ ràng, mặc định dễ dãi và cách ly chỉ tồn tại vì chưa ai kiểm tra nó.

Viết yêu cầu trên một dòng trước khi mở terminal. Chạm tới khối dịch vụ và máy chủ nhảy, không chạm tới gì khác bên trong khối khách hàng.

Tìm ra ai thực sự chuyển tiếp gói tin của peer

Hai hành vi của máy chủ trông giống nhau từ phía khách hàng và cần các quy tắc khác nhau. Hoặc nhân chuyển tiếp gói tin ra khỏi giao diện đường hầm lần nữa, hoặc daemon sao chép nó giữa các phiên và nhân không bao giờ thấy nó.

WireGuard thuộc nhóm thứ nhất: nó không có công tắc giữa các peer, nên một gói tin từ 10.8.0.4 tới 10.8.0.5 đến trên wg0, chạm móc chuyển tiếp và được định tuyến ra khỏi wg0 lần nữa khi AllowedIPs bao cả hai địa chỉ. OpenVPN là nhóm thứ hai khi client-to-client được đặt trong cấu hình máy chủ, vì chỉ thị đó trao gói tin giữa các phiên trong không gian người dùng. Kiểm tra cấu hình đã nạp cho chỉ thị đó trước khi viết bất cứ điều gì. Một quy tắc nhân không bao giờ thấy lưu lượng thì không thể phân biệt với một quy tắc đang hoạt động, và đó là cách một triển khai kết thúc mà không có chút cách ly nào.

Đọc cấu hình hiệu lực thay vì tệp bạn cho là đã nạp, vì các gói của bản phân phối mang theo phần bao gồm riêng của chúng. Nếu daemon chuyển tiếp, lệnh từ chối thuộc về các điều khiển theo từng khách hàng của nó, và tường lửa máy chủ chỉ lọc lưu lượng hướng tới máy chủ. Nếu nhân chuyển tiếp, móc chuyển tiếp là nơi duy nhất quan trọng.

Các triển khai định tuyến và dịch địa chỉ cần thêm một kiểm tra: nguồn mà một khách hàng xa thấy có thể không phải là nguồn bạn mong đợi. Khi đó một quy tắc khớp với subnet khách hàng không khớp với gì cả. Ghi lại địa chỉ sống sót sau phép dịch trước khi viết điều kiện khớp, và ưu tiên khớp cặp giao diện hơn là đoán địa chỉ NAT.

Cho mỗi địa chỉ một danh tính có thể thu hồi riêng

Cách ly sụp đổ ngay khi hai thiết bị chia sẻ một thông tin xác thực. Một quy tắc gắn với danh tính đó không thể tách chúng, và việc thu hồi một máy tính xách tay bị mất sẽ thu hồi cả nhóm. Chứng chỉ theo thiết bị hoặc khóa theo peer giữ việc thu hồi cục bộ và chính sách dễ đọc, vì mỗi địa chỉ tương ứng đúng một người hoặc máy. Ở đâu thiết kế không làm được điều đó, hãy nói trong sổ tay vận hành thay vì mô tả quy tắc là chi tiết.

Việc cấp phát địa chỉ phải đồng ý với chính sách. Dành một khối cho dịch vụ, một khối cho khách hàng, và cấp địa chỉ khách hàng từ một nhóm bạn kiểm soát chứ không phải từ dải ai đến trước. Nếu máy chủ dịch hoặc bắc cầu, hãy giữ bảng ánh xạ bên cạnh cấu hình, vì chính bảng đó là thứ người đọc tiếp theo cần để suy ra lại quy tắc.

Đặt lệnh từ chối ở nơi gói tin đi qua đường hầm

Trên một cổng chuyển tiếp lưu lượng WireGuard, hai quy tắc bao trường hợp này: cho phép khối dịch vụ, rồi bỏ phần còn lại của khối khách hàng. Cặp giao diện quan trọng như địa chỉ, vì khớp chỉ theo đích cũng bắt lưu lượng đến từ LAN. Nạp chúng theo thứ tự đó để quyền được đánh giá trước.

Với nftables, cặp này đi vào một bảng inet filter sẵn có, cho phép trước và bỏ sau. Cả hai điều kiện khớp đều ghim cặp giao diện cùng các địa chỉ.

nft add rule inet filter forward iifname "wg0" oifname "wg0" ip saddr 10.8.0.0/24 ip daddr 10.8.2.0/24 accept
nft add rule inet filter forward iifname "wg0" oifname "wg0" ip saddr 10.8.0.0/24 ip daddr 10.8.0.0/24 drop

Đọc lại chuỗi sau khi nạp thay vì tin trạng thái thoát, và xác nhận cả hai quy tắc nằm đúng thứ tự bạn định. Thêm các quy tắc ip6 khớp cho nhóm IPv6, nếu không cặp v4 chỉ là đồ trang trí trên một đường hầm hai ngăn xếp. Nếu máy chủ đã có chính sách chuyển tiếp dễ dãi, hãy thêm lệnh bỏ thay vì thay cả chuỗi.

Khi client-to-client được bật trên OpenVPN, các quy tắc chuyển tiếp này không bao giờ khớp lưu lượng giữa các peer và lệnh từ chối phải sống trong các điều khiển riêng của daemon. Giữ các quy tắc nhân cho lưu lượng hướng tới máy chủ, nhưng đừng tính chúng là điều khiển cách ly.

Chứng minh lệnh từ chối từ một khách hàng, không phải từ máy chủ

Kiểm tra từ cổng không chứng minh gì, vì lưu lượng sinh ra cục bộ đi theo đường ra và không bao giờ đi qua móc chuyển tiếp. Dùng hai khách hàng thật: một phải chạm tới dịch vụ, một phải bị từ chối. Chạy trường hợp cho phép trước, để một đường hầm hỏng không bị nhầm là chính sách đang hoạt động.

Từ khách hàng được phép, xác nhận dịch vụ trả lời trên cổng của nó. Từ cùng khách hàng, thử địa chỉ của peer và chờ một lần bỏ im lặng thay vì từ chối:

ping -c 3 -W 2 10.8.0.5
nc -z -w 2 10.8.0.5 22
nft list chain inet filter forward
iptables -vnL FORWARD
ping -6 -c 3 -W 2 fd00:8::5

Một gói tin bị bỏ và một peer ngoại tuyến đều trông như hết thời gian, nên hãy kiểm tra bộ đếm trước khi kết luận bất cứ điều gì. Xác nhận bộ đếm của quy tắc bỏ tăng lên trong khi peer rõ ràng đang hoạt động. Lặp lại trên IPv6, nơi thiếu quy tắc ip6 khiến lệnh từ chối v4 trông như có hiệu lực. Ghi lại các kết quả được chấp nhận và bị từ chối trong sổ tay kèm ngày, vì lần di chuyển tiếp theo sẽ suy ra lại quy tắc.

Bài viết liên quan