Ai đó trỏ một máy chủ HAProxy công khai vào một ứng dụng nội bộ và hỏi tại sao trình duyệt không thể theo tiếp. Proxy tiếp cận ứng dụng qua VPN của nó, chuyển hướng trả về một header Location, và trình duyệt sau đó thử một địa chỉ chỉ tồn tại bên trong đường hầm. Từ bên ngoài, trang chỉ đơn giản là treo. Quyết định nằm ở việc bên nào mở kết nối thứ hai, và đó là điều phân biệt một chuyển hướng với một backend.

Hai con đường trông giống nhau trong cấu hình

Một chuyển hướng kết thúc trao đổi bằng một phản hồi. Máy khách đọc Location và bắt đầu một yêu cầu mới từ nơi nó đang ở, tức là mạng mà bạn chưa bao giờ kiểm soát. Proxy không còn tham gia nữa. Mọi thứ sau đó phụ thuộc vào DNS, tuyến đường và sự tin cậy của chính máy khách, nên kết quả thay đổi tùy theo nơi người dùng mở trình duyệt:

GET /app        client -> proxy
302 Location    proxy  -> client   (http://10.40.0.20:8080/)
GET /app        client -> 10.40.0.20:8080   client network, no route

Một backend của proxy giữ chặng thứ hai ở phía máy chủ. Proxy mở nó qua con đường nó đã có, và máy khách tiếp tục nói chuyện với một tên công khai duy nhất. Nếu đường hầm đứt, máy khách nhận được lỗi thay vì một URL mà nó không thể theo. Chính sự khác biệt đó cũng khiến sự cố có thể chẩn đoán được, vì lỗi xuất hiện ở nơi có nhật ký:

GET /app        client -> proxy
GET /app        proxy  -> 10.40.0.20:8080   over the VPN
response        proxy  -> client

Tài liệu chuyển hướng của HAProxy vạch đúng ranh giới này: trả lời máy khách bằng một chuyển hướng là hành động khác với chuyển tiếp yêu cầu tới một backend. Hai chỉ thị nằm cách nhau vài dòng trong một tệp cấu hình và hành xử hoàn toàn khác nhau. Một cái kết thúc yêu cầu, cái kia bắt đầu một yêu cầu thứ hai do proxy sở hữu.

Những gì trình duyệt cần mà VPN của máy chủ không cung cấp

Yêu cầu của chính trình duyệt cần bốn thứ mà nó có thể không có: một câu trả lời DNS cho tên riêng, một tuyến đường tới địa chỉ đó, quyền tiếp cận dịch vụ đang lắng nghe, và sự tin cậy đối với bất kỳ chứng chỉ nào dịch vụ đó trình ra. Máy chủ proxy có cả bốn nhờ đường hầm của nó. Không thứ nào trong số đó chuyển sang một máy khách chưa bao giờ ở trong đường hầm đó, vì đường hầm là thuộc tính của máy chủ, không phải của URL.

Khoảng trống đó giải thích triệu chứng gần như chạy được. Yêu cầu đầu tiên thành công, thanh địa chỉ thay đổi, rồi kết nối treo hoặc thất bại trong khi proxy vẫn khỏe suốt thời gian. Không có gì hỏng trong cấu hình proxy, và việc chỉnh nó không thể giúp một máy khách không có đường tới 10.40.0.20. Hoặc máy khách có được một tuyến đường, hoặc proxy phải thực hiện kết nối thay nó.

Khi chỉ proxy mới tiếp cận được ứng dụng

Hãy bỏ hành động chuyển hướng và gửi những yêu cầu đó tới một backend trỏ đến địa chỉ riêng. Frontend giữ tên công khai của nó trong khi backend quyết định yêu cầu thực sự đi đâu. Không có gì thay đổi trong đường đi của máy khách, vì proxy ngừng mô tả một đích đến và tự trở thành đích đến. Với một ứng dụng cố ý lắng nghe trên cổng nội bộ 8080, khối máy chủ rất ngắn:

backend private_app
    mode http
    option httpchk GET /health
    server app1 10.40.0.20:8080 check

Hãy đọc khối đó như một phát biểu về bảng định tuyến của proxy: 10.40.0.20 phải tiếp cận được từ chính máy chủ proxy, ở đây nghĩa là qua giao diện VPN chứ không phải qua tuyến mặc định. Từ khóa check chỉ báo cáo tuyến đó làm gì, và đường dẫn kiểm tra sức khỏe phải tồn tại trong ứng dụng, nếu không mỗi lần dò sẽ đánh dấu máy chủ là down. Một lần kiểm tra đạt không chứng minh gì về máy khách và không thay thế chính sách quyết định ai được dùng backend.

Đoạn này không phải một frontend hoàn chỉnh. Hãy giữ trình lắng nghe, xác thực, việc chọn máy chủ và đường dẫn được phép, và quy tắc quyết định ai được tiếp cận ứng dụng. Cũng phải khớp giao thức của backend, vì một backend HTTPS cần xác minh chứng chỉ và cấu hình danh tính máy chủ, và bỏ qua bước kiểm tra đó biến một kết nối riêng thành một kết nối không được xác minh.

Hãy xác nhận đường về theo cả hai chiều trước khi tuyên bố thắng lợi. Ứng dụng giờ thấy một kết nối từ proxy, nên nhật ký và mọi siêu dữ liệu về địa chỉ máy khách đều mô tả proxy trừ khi bạn sắp xếp khác. Hãy quyết định cách xử lý danh tính và các địa chỉ được chuyển tiếp, và kiểm tra quyết định đó thay vì giả định.

Các chuyển hướng của chính ứng dụng vẫn trỏ vào bên trong

Chuyển tiếp yêu cầu đầu tiên chỉ là một nửa của việc tích hợp. Ứng dụng có thể phát ra các chuyển hướng tuyệt đối, URL tài nguyên được mã hóa cứng, hoặc cookie giới hạn theo tên mà nó biết bên trong, và mỗi thứ đó đưa trình duyệt trở lại một địa chỉ nó không thể tiếp cận. Một header Location trỏ đến tên nội bộ trông giống hệt vấn đề ban đầu, đó là lý do nó bị chẩn đoán nhầm là sự cố proxy.

Hãy đặt URL bên ngoài đã được tài liệu hóa của ứng dụng và các tùy chọn proxy của nó, rồi làm cho header Host khớp với máy chủ ảo và các kỳ vọng về chứng chỉ. Một cookie giới hạn theo tên nội bộ sẽ không quay lại qua tên công khai, và vòng đăng nhập theo sau bị đọc như một lỗi xác thực. Hãy đổi URL bên ngoài trước, kiểm tra lại từ một hồ sơ trình duyệt sạch, và mong đợi rằng cấu hình được chuyển một nửa sẽ tạo ra một lần đăng nhập thành công và một phiên chết ngay.

Chỉ tin siêu dữ liệu được chuyển tiếp từ proxy được chỉ định. Một header mà bất kỳ máy khách nào cũng có thể đặt không bao giờ được trở thành giá trị ủy quyền, nếu không proxy biến thành cách để một bên gọi tự nhận danh tính của người khác. Quy tắc đó độc lập với câu hỏi chuyển hướng và tồn tại qua mọi lần thiết kế lại sau này.

Hãy quyết định bạn thực sự có thiết kế nào

Nếu mọi người dùng đã có quyền truy cập VPN được cấp phép, một chuyển hướng tới URL riêng có thể là thiết kế có chủ đích. Hãy xác nhận yêu cầu đó một cách rõ ràng thay vì giả định, vì hai thiết kế phục vụ những nhóm hoàn toàn khác nhau. Một trong hai không hoạt động chút nào từ mạng khách sạn, cái kia phơi bày ứng dụng cho bất kỳ ai có thể tải URL công khai. Sự khác biệt đó thuộc về ghi chú thiết kế.

Hãy chạy kiểm tra từ một máy trong mạng của người dùng và theo dõi mọi bước nhảy mà trình duyệt thực hiện, không chỉ phản hồi đầu tiên. Hãy để mắt đến thanh địa chỉ và mọi yêu cầu tiếp theo, vì một URL tuyệt đối trong một thẻ tài nguyên là đủ để làm hỏng một luồng mà bước nhảy đầu tiên đã vượt qua. Đăng nhập phải hoạt động qua tên công khai, và những tài nguyên nên bị từ chối phải tiếp tục bị từ chối.

Xuất bản một reverse proxy là một quyết định truy cập riêng, không phải việc mở rộng minh bạch VPN của chính proxy cho bất kỳ ai có thể tải URL công khai của nó. Hai thứ trông giống nhau trên sơ đồ, và chúng khác nhau ở việc ai được phép vào. Quyết định câu hỏi đó sau khi triển khai là cách một ứng dụng nội bộ trở thành công khai một cách vô tình.

Hãy ghi lại bạn đã xây cái nào và tại sao. Người tiếp theo chạm vào cấu hình sẽ giả định cái còn lại. Một chuyển hướng được thêm cho tiện lợi là đủ để tái tạo sự cố ban đầu, và triệu chứng sẽ trông giống hệt cái bạn vừa sửa.

Bài viết liên quan