Kill switch chặn máy chủ VPN trước khi bất kỳ lưu lượng nào chảy
Kill switch chặn ở giai đoạn nào: phân giải điểm cuối, tuyến ngoài, đường về và các ngoại lệ peer đã cũ — bằng bộ đếm thay vì phỏng đoán.
Kill switch thất bại theo hướng người ta không ngờ: chúng được tạo ra để chặn lưu lượng khi đường hầm đang xuống, mà những gói tin dựng nên đường hầm lại chính là lưu lượng. Đó là toàn bộ lỗi. Một bộ quy tắc loại bỏ mọi thứ không đi ra qua đường hầm cũng loại bỏ luôn cái bắt tay lẽ ra phải dựng nó lên, nên máy khách thử lại trong vòng lặp và lỗi bị gán cho giai đoạn được kiểm tra trước. Trước khi mở rộng tường lửa, hãy xác định giai đoạn nào trong ba bị từ chối: phân giải tên, gói tin bên ngoài tới peer, hay phản hồi quay về.
Đường hầm và chính vận chuyển của nó phụ thuộc nhau thế nào
Hãy đọc máy khách VPN như hai trạng thái mạng dùng chung một đường socket. Trước khi đường hầm tồn tại, máy khách mở socket trên card mạng vật lý và gửi khung đã mã hóa tới địa chỉ và cổng của peer. Chỉ sau khi trao đổi đó thành công, nó mới tạo thiết bị đường hầm và cài đặt tuyến. Kill switch là chính sách về trạng thái thứ hai, được viết rộng đến mức áp dụng cho cả hai.
Quy tắc dựa trên giao diện là dạng thông thường: chấp nhận thứ đi ra qua tun0 hoặc wg0, loại bỏ phần còn lại của tuyến ra. Cách viết đó không thể miễn trừ chính kết nối của máy khách tới máy chủ, nên một cài đặt đúng sẽ thêm ngoại lệ đó một cách tường minh, và bạn cũng vậy khi viết quy tắc bằng tay. Quy tắc theo ứng dụng trên Windows và macOS tránh được một phần bằng cách khớp tiến trình thay vì giao diện, nhưng tiến trình vẫn phải ra ngoài trước khi đường hầm tồn tại.
Ba giai đoạn, theo thứ tự xảy ra
Giai đoạn đầu là phân giải. Khi hồ sơ lưu tên máy chủ thay vì địa chỉ cụ thể, máy khách cần một câu trả lời DNS trước khi gửi được gì. Một hồ sơ trỏ DNS tới bộ phân giải của đường hầm sẽ tạo bế tắc: bộ phân giải chỉ tới được qua đường hầm mà truy vấn lẽ ra phải mở ra. Phân giải bên ngoài đường hầm, hoặc ghim điểm cuối vào một địa chỉ, sẽ xóa bỏ sự mập mờ này.
Giai đoạn thứ hai là gói tin bên ngoài, nó phải vượt qua định tuyến trước rồi mới tới tường lửa, đúng thứ tự đó. wireguard-tools đảm nhận nửa định tuyến của việc này cho WireGuard bằng cách đánh dấu các gói tin của mình và thêm một quy tắc chính sách để chúng bỏ qua tuyến mặc định vừa cài; trang hướng dẫn của wg-quick mô tả quy tắc đó và bảng mà nó dùng. Hãy dựng lại định tuyến đó bằng tay, hoặc để một công cụ thứ hai viết lại quy tắc, và các gói tin được đánh dấu có thể bị gửi trả lại vào đúng đường hầm mà chúng phải dựng nên.
Giai đoạn thứ ba là đường về. Một cái bắt tay không có phản hồi không phải bằng chứng của việc bị loại ở chiều ra; nó cũng phù hợp với một quy tắc vào của máy chủ hoặc một thiết bị NAT đã quên ánh xạ. Hãy tách hai khả năng đó trước khi chạm vào máy khách.
| What you see | Stage | Where to look |
|---|---|---|
| The client log repeats a resolve step and no packets appear on the wire | 1, name lookup | Resolver path while the tunnel is down |
| The send counter on the physical adapter stays flat | 2, routing | Peer route and policy rules |
| The send counter rises and a firewall drop counter rises | 2, firewall | Rule order, mark, and interface match |
| Packets leave and nothing comes back | 3, return path | Server input rules, NAT, listening port |
Máy khách ghi lại triệu chứng chúng phát hiện, không ghi giai đoạn đã hỏng, nên bảng thường nhanh hơn nhật ký.
Bộ đếm quyết định nhanh hơn nhật ký
Trên Linux, nft list ruleset hoặc iptables -vnL OUTPUT in ra bộ đếm gói tin theo từng quy tắc. Kết nối một lần, để nó thất bại, rồi đọc lại các bộ đếm. Quy tắc có bộ đếm nhích lên chính là quy tắc mà cái bắt tay đã đụng vào; nếu không chỗ nào nhích cả, gói tin chưa bao giờ tới tường lửa. Tôi đã từng thấy một bộ quy tắc loại bỏ chính cái bắt tay của nó, và chỉ có bộ đếm nói ra điều đó.
Để phân biệt chưa bao giờ tới tường lửa với chưa bao giờ rời khỏi máy chủ, hãy quan sát chính giao diện. ip -s link show dev wlan0 báo cáo số gói đã gửi, và tcpdump -ni wlan0 udp port 51820 hiển thị các khung. Nếu nó vẫn phẳng trong khi máy khách thử lại, lỗi nằm phía trên netfilter: thiếu tuyến tới peer, một quy tắc chính sách trỏ vào thiết bị chưa tồn tại, hoặc một lỗi socket mà máy khách nuốt mất.
Hãy thử các ngoại lệ trên địa chỉ tài liệu như 203.0.113.10, để một sơ suất không thể dò máy chủ của người khác.
Một ngoại lệ điểm cuối đã cũ đọc như thể máy chủ gặp sự cố
Phiên bản gây hiểu nhầm nhất xuất hiện sau khi địa chỉ của peer thay đổi: một dịch vụ địa chỉ động đã chuyển nó đi, máy chủ được dựng lại, hoặc địa chỉ ra của mạng bạn khác đi. Ngoại lệ vẫn nêu địa chỉ cũ, nên gói tin tới địa chỉ mới rơi vào quy tắc loại bỏ. Cùng một cấu hình vẫn chạy được hôm qua, và đó là lý do người ta bắt đầu chẩn đoán máy chủ.
Một tên máy chủ nằm trong quy tắc tường lửa không cứu bạn. Trong nftables, tên được phân giải khi nạp bộ quy tắc, nên nó ghim đúng địa chỉ tồn tại ở thời điểm đó và cũ đi như một địa chỉ cụ thể. Cách bền vững là cập nhật ngoại lệ khi điểm cuối thay đổi và giữ nó hẹp: một địa chỉ peer, một cổng vận chuyển. Một dải đủ rộng để chịu được thay đổi địa chỉ cũng đủ rộng để cho lưu lượng không liên quan đi ra.
Khi kill switch chạy trên máy chủ
Cùng sự phụ thuộc đó tồn tại ở đầu bên kia, và ở đó dễ bỏ sót hơn. Nếu chiếc máy đóng vai máy chủ VPN của bạn cũng chạy một máy khách để bàn có kill switch, hoặc một hồ sơ tường lửa sao chép từ laptop, các quy tắc loại bỏ của nó áp lên dịch vụ kết thúc đường hầm. Phản hồi cho cái bắt tay của máy khách bị loại bỏ, nên mọi máy khách đều không kết nối được trong khi máy chủ trông vẫn khỏe và giao diện đường hầm của nó ngồi không.
Máy chủ đó cần ba chấp nhận hẹp trước khi loại bỏ: cổng lắng nghe trên giao diện vật lý, giao diện đường hầm cho lưu lượng đã giải mã, và chuyển tiếp từ đường hầm tới nơi mà máy khách cần tới. Hãy đọc bộ đã cài bằng nft list ruleset, iptables -S, hoặc pfctl -sr trước khi thay đổi bất cứ thứ gì, và nhớ rằng một bộ quy tắc đã lưu sẽ sống qua lần khởi động lại, nên một lỗi ở đó sống lâu hơn tiến trình đã tạo ra nó.
Trình tự khôi phục giữ cho máy vẫn đóng
Hãy làm việc từ hồ sơ ra ngoài. Đọc địa chỉ và cổng của peer mà máy khách dùng, xác nhận tên máy chủ phân giải được mà không cần đường hầm, rồi thêm một ngoại lệ cho địa chỉ và cổng đó chỉ trên card mạng vật lý. Kết nối lại và quan sát bộ đếm gửi; một cái bắt tay hoàn tất là dấu hiệu giai đoạn hai đã được sửa.
Hãy để phần còn lại của chính sách loại bỏ tại chỗ trong lúc thử. Một kiểm tra vô hại là thử kết nối tới một địa chỉ tài liệu không liên quan và xác nhận nó vẫn hết thời gian, điều này cho thấy kill switch đang chạy chứ không phải đã tắt. Siết ngoại lệ lại khi đường hầm đã ổn định, và đừng để lại một quy tắc cho phép tất cả vĩnh viễn cho tệp nhị phân của máy khách chỉ vì nó tiện.
Nếu đường hầm lên mà ứng dụng vẫn hỏng, các giai đoạn còn lại không phải cái này: DNS chia tách, MTU và định tuyến theo ứng dụng mỗi thứ đều tạo ra đường hầm đã kết nối với lưu lượng hỏng, và mỗi thứ có bước kiểm tra đầu tiên khác nhau.