Sáu bước kiểm tra, thực hiện theo thứ tự, quyết định liệu một VM có thể làm cổng VPN cho chính máy chủ của nó hay không. Hypervisor không làm bất kỳ điều nào trong số này thay bạn: khách sở hữu đường hầm, máy chủ sở hữu một tuyến, và mạng giữa chúng là định tuyến thông thường. Tôi giữ danh sách này vì bỏ qua một bước luôn cho cùng một triệu chứng, sự im lặng, khi máy chủ ping khách vui vẻ mà không chạm tới được gì bên trong.

Hãy bắt đầu từ lý do. Hoặc ứng dụng khách của công ty chỉ cài được bên trong khách, hoặc chính sách giữ nó ở đó, và bạn vẫn cần máy chủ build nội bộ từ máy chủ. Nếu máy chủ được phép dùng ứng dụng khách riêng, hãy làm vậy thay thế: một đường hầm trên máy chủ luôn thắng hai mạng cộng một NAT.

Kiểm tra 1: máy chủ cần một liên kết có thể gán địa chỉ

Máy chủ phải có một giao diện nằm trong cùng tiền tố với bộ điều hợp thứ hai của khách. Host-only trong VirtualBox, host-only hoặc VMnet tùy chỉnh trong VMware Workstation, cầu nội bộ hoặc thiết bị tap trong QEMU/KVM, và switch Internal trong Hyper-V đều đáp ứng. Khách 192.168.56.2, máy chủ 192.168.56.1, tiền tố 192.168.56.0/24 là cách bố trí tôi dùng trong phòng lab.

Mạng chế độ người dùng của QEMU (-netdev user, backend SLIRP mặc định) và NAT của VirtualBox thất bại hoàn toàn ở bước kiểm tra này. Gói của khách chỉ tới một tiến trình proxy trên máy chủ, nên máy chủ không bao giờ thấy thiết bị mang địa chỉ của khách và không có gì để trỏ tuyến tới. Default Switch của Hyper-V cũng vậy. Nếu ping 192.168.56.2 từ máy chủ thất bại, hãy dừng: không tuyến nào thêm sau đó sửa được điều này.

Kiểm tra 2: khách chuyển tiếp và chuyển đổi

Gói từ máy chủ đến với địa chỉ nguồn host-only và đích nội bộ, nên khách phải chuyển tiếp chúng rồi giấu sau địa chỉ đường hầm của mình. Trên khách Linux, điều đó nghĩa là chuyển tiếp, một cặp FORWARD accept, và source NAT về phía đường hầm:

sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -A FORWARD -i eth1 -o tun0 -j ACCEPT
sudo iptables -A FORWARD -i tun0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -t nat -A POSTROUTING -s 192.168.56.0/24 -o tun0 -j MASQUERADE

Quy tắc MASQUERADE là phần mà mọi người bỏ sót. Router doanh nghiệp hiếm khi biết rằng 192.168.56.0/24 tồn tại; với quy tắc này, máy chủ nội bộ thấy địa chỉ đường hầm của khách và trả lời nó, và câu trả lời tìm được đường về khách.

Khách Windows vụng về hơn. IPEnableRouter=1 dưới SYSTEM\CurrentControlSet\Services\Tcpip\Parameters bật chuyển tiếp mà không chuyển đổi, nên nó chỉ hoạt động ở nơi định tuyến doanh nghiệp đã trỏ ngược về tiền tố host-only của bạn. Internet Connection Sharing có chuyển đổi, nhưng nó đánh số lại bộ điều hợp chia sẻ thành 192.168.137.1, nên hãy đọc địa chỉ mà nó thực sự nhận trước khi viết tuyến trên máy chủ.

Kiểm tra 3: tuyến của máy chủ gọi tên khách, không phải đường hầm

Chỉ đưa qua khách những tiền tố mà máy chủ cần. Trên Linux, một tuyến cho mỗi tiền tố là đủ và nó đảo lại gọn gàng:

sudo ip route add 10.20.0.0/16 via 192.168.56.2
ip route get 10.20.30.40

Trên Windows, tương đương là route add 10.20.0.0 mask 255.255.0.0 192.168.56.2. Hãy bỏ -p ra trong khi còn thử nghiệm, để một tuyến xấu chết khi khởi động lại, và thêm nó vào khi đường đi hoạt động. Đừng xóa tuyến mặc định của máy chủ trừ khi mọi ứng dụng trên máy chủ phải dùng đường hầm; nếu thực sự cần đường hầm đầy đủ, hãy thêm hai tuyến /1 và giữ tuyến trực tiếp tới mạng của hypervisor:

sudo ip route add 0.0.0.0/1 via 192.168.56.2
sudo ip route add 128.0.0.0/1 via 192.168.56.2

Trên máy chủ Windows, cũng kiểm tra chỉ số giao diện. Một tuyến được thêm vào khi bộ điều hợp host-only bị tắt vẫn nằm trong bảng nhưng không bao giờ mang lưu lượng, và bộ điều hợp thứ hai có chỉ số thấp hơn có thể thắng việc tra cứu cho cùng tiền tố.

Kiểm tra 4: DNS đi theo tuyến, không theo mặc định của đường hầm

Tuyến di chuyển gói; trình phân giải quyết định tên nào tạo ra gói. Hãy giới hạn trình phân giải doanh nghiệp vào vùng doanh nghiệp thay vì thay thế trình phân giải của máy chủ, và trỏ nó tới một máy chủ DNS mà tuyến mới đã chạm tới. Với systemd-resolved trên máy chủ:

resolvectl dns eth1 10.20.0.53
resolvectl domain eth1 '~corp.example.com'

Trên Windows, một mục trong bảng chính sách phân giải tên làm việc tương tự: Add-DnsClientNrptRule -Namespace ".corp.example.com" -NameServers 10.20.0.53. Nếu khách chạy trình phân giải riêng trên địa chỉ host-only, hãy dùng địa chỉ đó, nhưng chỉ sau khi xác nhận rằng nó trả lời trên 192.168.56.2 chứ không phải trên loopback.

Sau đó kiểm tra MTU trước khi đổ lỗi cho DNS vì trang chậm. Giao diện đường hầm nhỏ hơn giao diện 1500 byte của máy chủ, nên máy chủ gửi các đoạn kích thước đầy đủ với bit DF được bật sẽ thấy chúng bị bỏ ở đâu đó bên trong khách. Triệu chứng kinh điển là ping hoạt động và một ứng dụng web nội bộ đứng sau bắt tay TLS. Siết MSS trên đường chuyển tiếp của khách:

sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

Kiểm tra 5: xác minh từ cả hai đầu

Từ máy chủ, traceroute hoặc tracert tới một địa chỉ nội bộ phải hiển thị 192.168.56.2 là chặng đầu, không phải cổng vật lý. Trong khách, hãy xem cùng nỗ lực đó đi ra: tcpdump -ni any host 10.20.30.40 hiển thị yêu cầu đã chuyển tiếp ở phía host-only và yêu cầu đã chuyển đổi trên đường hầm. Một yêu cầu đi ra, quay về mà vẫn để máy chủ im lặng là dấu hiệu của đường về.

Hai lỗi giải thích phần lớn điều đó. Hoặc đường hầm của khách không mang tuyến quay về cho tiền tố host-only vì thiếu quy tắc NAT, hoặc tuyến của máy chủ trỏ tới địa chỉ mà khách không còn giữ sau khi khởi động lại. Hãy đọc lại địa chỉ bằng ip -br addr và ip route get thay vì tin ghi chú của phiên trước.

Kiểm tra 6: làm cho nó sống sót qua khởi động lại và nâng cấp hypervisor

Hãy lưu bền cả hai nửa: cấu hình tuyến netplan hoặc NetworkManager trên máy chủ, route add ... -p trên Windows, và net.ipv4.ip_forward=1 trong /etc/sysctl.d/ cùng một bộ quy tắc tường lửa được nạp lại trong khách. Chụp snapshot của khách ngay khi cấu hình được xác minh, trước khi bản cập nhật ứng dụng khách doanh nghiệp tiếp theo đến.

Mạng host-only được đánh số lại khi hypervisor tạo lại các bộ điều hợp của nó, điều này âm thầm vô hiệu hóa mọi tuyến và quy tắc NAT được xây trên 192.168.56.0/24. Sau khi nâng cấp, hãy chạy lại ba bước kiểm tra đầu theo thứ tự; việc đó mất một phút và bắt được trường hợp máy chủ vẫn còn tuyến của nó trong khi khách đã chuyển sang một mạng con mới.

IPv6 cần một lượt riêng. Các quy tắc ip6tables, bản ghi AAAA và họ tuyến thứ hai của máy chủ không đi theo thiết lập IPv4, và một dịch vụ doanh nghiệp truy cập được qua IPv6 sẽ trông hỏng vĩnh viễn trong khi IPv4 vẫn chạy.

Đạt hay không, theo thứ tự: máy chủ ping được địa chỉ host-only của khách; khách chuyển tiếp và làm MASQUERADE về phía đường hầm; ip route get trả lại khách làm cổng cho tiền tố nội bộ; tên doanh nghiệp được phân giải qua trình phân giải giới hạn; traceroute hiển thị khách trước; và sáu câu trả lời đó vẫn còn sau khi khởi động lại.

Bài viết liên quan