Dựng thêm một OpenVPN máy chủ thứ hai chỉ cho bạn thêm một nơi để máy khách kết nối, và không hơn thế. Nó không đưa những máy khách đó vào mạng của máy chủ đầu tiên, và tùy chọn có tên client-to-client chỉ thay đổi việc chuyển tiếp bên trong một tiến trình máy chủ. Hai nhóm trở thành một mạng khi bạn định tuyến giữa chúng một cách có chủ đích, với một chủ sở hữu cho mỗi hướng. Mọi thứ bên dưới giả định chế độ TUN trong không gian người dùng với việc chuyển tiếp nội bộ đó bị tắt, nên nhân hệ điều hành đưa ra quyết định.

Huyền thoại: một danh sách tài khoản, một mạng

Xác thực và khả năng tiếp cận bị lẫn với nhau vì cả hai đều nằm trong cấu hình máy chủ. Một người dùng đăng nhập được vào bất kỳ cổng nào trong hai cổng, từ bên ngoài, trông như người dùng trên một hệ thống có hai cửa. Bên trong, mỗi máy chủ cấp địa chỉ từ nhóm của chính nó và chỉ cài tuyến đường cho những máy khách mà nó kết thúc. Vì vậy một máy khách ở cổng A gửi gói tin tới một máy khách ở cổng B đang yêu cầu một đích mà máy chủ của chính nó chưa từng nghe đến. Gói tin đi theo tuyến mặc định của A, rời khỏi đường hầm và đến một tường lửa chưa từng được yêu cầu cho phép nó.

Do đó thêm một máy chủ thứ hai không thêm dự phòng, khám phá hay miền quảng bá chung. Nó thêm một mạng được định tuyến cần một kế hoạch, và kế hoạch bắt đầu bằng việc đánh địa chỉ.

Cho mỗi cổng một nhóm và địa chỉ trung chuyển riêng

Hai dải không được chồng lên bất cứ thứ gì khác, cộng một liên kết trung chuyển nhỏ giữa các máy chủ, là toàn bộ kế hoạch địa chỉ. Giữ trung chuyển trên một phân đoạn riêng mà bạn kiểm soát, và ghi các con số ra trước khi bất kỳ máy chủ nào cấp một hợp đồng thuê.

GatewayClient poolTransit address
gateway-a10.64.10.0/24172.28.44.1/30
gateway-b10.64.20.0/24172.28.44.2/30

Hãy chống lại cám dỗ cấp cho cả hai máy chủ cùng một nhóm để hồ sơ giữ nguyên. Tuyến đường của nhân không thể nói máy chủ nào trong hai đang sở hữu một địa chỉ tùy ý trong một dải chung, nên bảng định tuyến sẽ trỏ tới một cổng và máy khách có thể đang gắn với cổng kia. Tên giao diện là quy ước cục bộ, không phải trạng thái chung. Hai máy chủ ở đây gọi thiết bị đường hầm là tun0 và liên kết trung chuyển là transit0, điều đó không sao vì không gói tin nào mang những tên đó.

Cài tuyến đường ở cả hai phía

Mỗi cổng cần một tuyến tới nhóm của bên kia qua địa chỉ trung chuyển, và việc chuyển tiếp phải được bật để bên nào cũng có thể làm một chặng. Trước tiên hãy xác nhận bảng hiện tại, sau đó thêm mục và làm cho nó bền vững qua trình quản lý mạng của máy chủ thay vì một móc kết nối lại.

sysctl net.ipv4.ip_forward
ip route add 10.64.20.0/24 via 172.28.44.2 dev transit0
ip route get 10.64.20.37

Phản chiếu điều đó trên máy chủ kia với các nhóm đã hoán đổi. Việc thêm lặp lại cùng một tuyến từ một script không liên quan là cách một máy chủ có vài bản sao và một thay đổi bí ẩn vào lần tới khi ai đó đọc bảng. Nếu liên kết trung chuyển tự nó là một đường hầm, tuyến trỏ tới cấu trúc liên kết của đường hầm đó và chặng phải sống sót qua lần kết nối lại. Một địa chỉ trung chuyển biến mất trong ba mươi giây sẽ mang theo con đường giữa các nhóm, đó là một thuộc tính thiết kế đáng được nói ra hơn là phát hiện.

Đẩy tuyến của máy khách mà không giả vờ sở hữu

Máy khách cần một tuyến tới nhóm từ xa, nếu không hệ điều hành của họ sẽ gửi gói tin tới cổng mặc định và đường hầm không bao giờ thấy nó. Cấu hình máy chủ là nơi tự nhiên để cung cấp nó.

push "route 10.64.20.0 255.255.255.0"

Đặt dòng phản chiếu vào cấu hình của máy chủ kia, sau đó kết nối lại một máy khách thử và đọc bảng của nó. Một máy khách bỏ qua các tuyến được đẩy cần cấu hình đã được phê duyệt của riêng nó, và một tuyến không bao giờ đến thì không phải là kiểm soát truy cập. Đừng trao cho máy khách iroute cho toàn bộ nhóm của cổng kia. Chỉ thị đó tồn tại cho một subnet nằm sau một máy khách đã kết nối, và dùng nó để che một tuyến thiếu giữa các cổng sẽ tạo ra một máy chủ tin rằng nó sở hữu những địa chỉ nó không thể đến.

Chứng minh một yêu cầu và từ chối một yêu cầu khác

Chọn một thao tác thực, ví dụ HTTPS từ một máy khách tại 10.64.10.21 tới một dịch vụ tại 10.64.20.37, và cho phép đúng điều đó trên cả hai máy chủ. Mỗi tường lửa chấp nhận yêu cầu ở phía vào và phản hồi được theo dõi ở phía về; chính sách dịch vụ của đích vẫn phải chấp nhận nó.

iptables -A FORWARD -i tun0 -o transit0 -s 10.64.10.21 -d 10.64.20.37 -p tcp --dport 443 -j ACCEPT
iptables -A FORWARD -i transit0 -o tun0 -d 10.64.10.21 -s 10.64.20.37 -p tcp --sport 443 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Khi có các tuyến hai chiều, NAT nguồn là không cần thiết và ở đây thực sự có hại: dịch địa chỉ nguồn giấu việc máy khách nào đã gửi yêu cầu và phá hỏng chính sách dựa trên nguồn ở phía đích. Kiểm tra xem quy tắc masquerade hiện có cho lưu lượng ra internet có bắt cả đường này không. Sau đó kiểm tra việc từ chối. Một dịch vụ cần ở lại cục bộ trong nhóm B phải vẫn không thể đến được từ nhóm A, và các cặp máy khách trên cùng một cổng cũng cần được kiểm tra, vì chính sách chuyển tiếp bạn vừa thay đổi cũng áp dụng cho họ.

Một chỉnh sửa nữa cho mô hình tinh thần: liên kết trung chuyển mang các gói tin nội bộ đã giải mã, nên nó là ranh giới tin cậy chứ không phải bảo đảm riêng tư. Nếu nó đi qua một mạng bạn không kiểm soát, hãy bảo vệ chặng đó bằng một đường hầm mã hóa đã được phê duyệt và định tuyến qua cấu trúc liên kết thực của nó. TLS đầu-cuối vẫn tự xác thực ứng dụng, đó là lý do dịch vụ bên trong nên tiếp tục dùng nó.

Bài viết liên quan