Lưu lượng container Docker vượt qua VPN của máy chủ: cách kiểm tra
VPN của máy chủ chỉ bao phủ không gian tên mạng của máy chủ. Dùng các kiểm tra này để biết lưu lượng container trên cầu đi vào đường hầm hay đi thẳng ra ngoài.
Trình duyệt trên máy chủ hiển thị địa chỉ thoát của VPN, container báo cáo kết nối tại nhà của bạn, và ai đó gọi đó là rò rỉ. Không có gì rò rỉ. Đường hầm của máy chủ là một tập hợp giao diện, tuyến và quy tắc thuộc không gian tên mạng của máy chủ, còn container trên cầu là một không gian tên khác với tuyến mặc định riêng. Tôi đã ngồi trên một ngăn xếp Compose nơi ứng dụng khách VPN đã kết nối hàng tuần mà không một gói tin container nào từng đi vào đó.
Kiểm tra không gian tên trước biểu tượng khay
Không gian tên là toàn bộ lập luận. Khi Docker khởi động một container trên mạng cầu, nó tạo một không gian tên mạng, gắn một đầu của cặp veth vào bên trong và cấp cho không gian tên đó một địa chỉ cùng tuyến mặc định. Giao diện đường hầm, dù được gọi là gì, sống trong không gian tên của máy chủ. Lưu lượng bên trong container không thể thấy nó, và không cấu hình ứng dụng khách nào thay đổi điều đó từ bên ngoài.
Hai bước được hỗ trợ đưa bạn ra khỏi sự cô lập. --network host đặt container vào không gian tên của máy chủ, nên nó thừa hưởng các tuyến của máy chủ và do đó là đường hầm. --network container:vpn chia sẻ không gian tên của container khác, và đó là cách hầu hết thiết kế sidecar gửi khối lượng công việc qua container VPN. Cả hai đều là lựa chọn rõ ràng; thường chỉ một trong hai là điều người triển khai muốn nói.
Chế độ máy chủ không phải là nâng cấp miễn phí. Container không còn địa chỉ riêng, việc công bố cổng không còn áp dụng, và một tiến trình giữ NET_ADMIN ở đó có thể ghi lại định tuyến của máy chủ. Chấp nhận điều đó có thể là quyết định đúng. Cho rằng nó đã bật sẵn là cách người ta dành cả buổi tối để gỡ lỗi một đường hầm chưa bao giờ nằm trên đường đi.
Theo dõi gói tin ra khỏi cầu
Container trên cầu gửi gói tin đến cổng mặc định của nó, tức giao diện cầu trên máy chủ. Máy chủ sau đó chuyển tiếp gói tin và trong cấu hình mặc định sẽ dịch địa chỉ nguồn thành địa chỉ của mình trước khi gói tin đi ra. Chính bước dịch đó đánh bại chính sách một cách âm thầm.
Khi gói tin đến điểm cuối của đường hầm, nó mang địa chỉ của máy chủ. Bất kỳ quy tắc, tuyến chính sách hay quyết định chia tách đường hầm nào dựa trên địa chỉ gốc của container đều không còn khớp, và hai container dự định đi ra qua các lối khác nhau không thể phân biệt chỉ bằng nguồn. Nếu bạn cần định tuyến theo từng container, quyết định phải diễn ra trước khi dịch hoặc bên trong không gian tên mà bạn kiểm soát.
Docker tự duy trì các quy tắc này, thông qua bất kỳ phần phụ trợ tường lửa nào mà daemon được cấu hình. Các quy tắc viết tay nằm ngoài móc được hỗ trợ cho lưu lượng chuyển tiếp, DOCKER-USER, có thể bị sắp xếp lại hoặc bị bỏ khi daemon khởi động lại hoặc máy chủ được nâng cấp. Tài liệu của Docker về lọc gói tin cho thấy thứ tự các chuỗi; điểm thực tế là mỗi quy tắc cần một chủ sở hữu và một đường tải lại mà bạn thực sự đã kiểm tra.
Kiểm tra hai hệ thống riêng rẽ
Bằng chứng từ một không gian tên không nói gì về không gian kia. Một yêu cầu chạy bên trong container VPN chứng minh đường hầm hoạt động cho container đó. Đó không phải bằng chứng về máy chủ, và cùng lệnh đó chạy từ container --network host cũng không phải bằng chứng về cầu.
# host namespace
ip route get 1.1.1.1
ip -brief addr show
# a fresh container on the same bridge network
docker run --rm --network appnet alpine sh -c 'ip route; cat /etc/resolv.conf; ip -6 route'
Sau đó lặp lại bài kiểm tra bên trong container ứng dụng thật thay vì một image tương tự. Ứng dụng có thể mang thêm tuyến, biến môi trường proxy hoặc một bộ phân giải khác, và mỗi thứ đó đều thay đổi câu trả lời. Kiểm tra phân giải tên và họ địa chỉ thứ hai mỗi lần: các container trên cầu do người dùng định nghĩa được phân giải qua bộ phân giải tích hợp của Docker tại 127.0.0.11, và tuyến mặc định IPv6 trên cầu có thể mang lưu lượng ra ngoài trong khi bạn đang bận kiểm tra một đường hầm chỉ IPv4.
Đọc mẫu trước khi chạm vào thông tin đăng nhập
Khi máy chủ hoạt động còn container thì không, nguyên nhân gần như luôn mang tính cấu trúc, và việc xoay khóa hoặc cài lại ứng dụng khách lãng phí cả buổi chiều. Hãy phân loại triệu chứng trước và cách khắc phục thường tự gọi tên.
| What you see | Usual cause | First check |
|---|---|---|
| Host exits through the VPN, container shows the ISP address | The container never entered the tunnel | Default route inside the container |
| Container works until the daemon restarts, then stops | Rules outside the supported hook, or a changed backend | Daemon's reported firewall backend and DOCKER-USER |
| Container loses internal hosts after the tunnel comes up | VPN prefix overlaps the Docker bridge subnet | ip route on the host, then docker network inspect |
| Small replies arrive, large ones hang | Tunnel MTU or missing MSS clamping | Link MTU on both ends of the tunnel |
| Container falls back to the ISP address when the tunnel drops | Nothing enforces the kill switch for forwarded traffic | Stop the tunnel with a request in flight |
Hàng về chồng lấn xứng đáng có câu riêng. Một hồ sơ VPN đẩy tuyến cho 172.17.0.0/16, hoặc cho một 10.0.0.0/8 tình cờ chứa tiền tố cầu của bạn, khiến đường hầm đòi lấy subnet của container, và các phản hồi tới địa chỉ đã dịch sẽ đi sai hướng hoặc biến mất. Đánh số lại mạng Docker thường sạch hơn là tích lũy ngoại lệ.
Làm cho phạm vi bao phủ trở nên rõ ràng, rồi cố ý phá vỡ nó
Hai thiết kế trụ được qua đánh giá. Chia sẻ không gian tên của container VPN và mọi khối lượng công việc được bao phủ dùng một đường hầm với một ranh giới khởi động lại, điều này đơn giản cho đến khi một dịch vụ cần lối ra khác hoặc đường DNS riêng. Hoặc định tuyến mạng container tới một cổng VPN trên máy chủ: bật chuyển tiếp, tiền tố cầu hướng vào đường hầm, lưu lượng quay về được xử lý rõ ràng. Điều đó mua quyền kiểm soát theo từng mạng và khiến bạn tốn một bộ quy tắc phải duy trì qua các lần nâng cấp daemon và ứng dụng khách.
Dù thế nào, bài kiểm tra quan trọng là trường hợp thất bại. Dừng đường hầm khi một yêu cầu container đang bay và xem gói tin đi đâu. Nếu nó quay lại đường trực tiếp, phạm vi bao phủ chưa bao giờ được thực thi, vì kill switch của ứng dụng khách điều khiển lưu lượng của chính ứng dụng khách chứ không phải các gói tin được chuyển tiếp từ cầu. Sau đó khởi động lại daemon và máy chủ và xác nhận kết quả lần thứ hai; đó là thời điểm các quy tắc viết tay biến mất.
Trước khi nói đã xong, hãy xác nhận bốn điều: giao diện đường hầm nằm trong cùng không gian tên với lưu lượng, bài kiểm tra container chạy bên trong container thật, phân giải tên và cả hai họ địa chỉ đã được kiểm tra, và bài kiểm tra thất bại đường hầm vẫn thất bại theo hướng đóng. Sau đó ghi lại phần phụ trợ tường lửa, phiên bản ứng dụng khách và chủ sở hữu của từng quy tắc. Bản ghi đó chính là thứ ngăn lần nâng cấp tiếp theo để lại một mớ giả định cũ không được ghi chép.