Điểm:2

Apache đằng sau proxy ngược nginx, đặt tiêu đề Máy chủ chính xác

lá cờ nl

Tôi đang chạy ứng dụng của mình bằng Apache trong bộ chứa Docker. Tôi có nginx hoạt động như một proxy ngược chạy trong một bộ chứa Docker khác có Apache làm thượng nguồn. tôi đang sử dụng proxy_pass chỉ thị cho việc này.

Apache chạy trong URL https://example-8gnm1aqrns-lz.a.run.app Nginx chạy trong URL http://example.com

Toàn bộ điều đang chạy trên Google Cloud Run và vấn đề là Google Cloud Run gán cho mọi dịch vụ một URL và nó sử dụng URL Chủ nhà tiêu đề để phân biệt giữa các ứng dụng nên tôi buộc phải gửi tiêu đề Máy chủ: example-8gnm1aqrns-lz.a.run.app khi kết nối với thượng nguồn bằng nginx để yêu cầu định tuyến chính xác.

Điều này gây ra sự cố với ứng dụng của tôi vì ứng dụng cho rằng nó đang chạy trong URL https://example-8gnm1aqrns-lz.a.run.app và không http://example.com.

Có thể sử dụng một số cấu hình .htaccess của Apache để ghi đè lên Chủ nhà tiêu đề dựa trên Máy chủ chuyển tiếp X được gửi bởi nginx?

Điểm:2
lá cờ co

Thay vì để Apache thực hiện công việc đó, hãy yêu cầu NGINX thực hiện trước khi nó chuyển dữ liệu cho Apache bằng cách đặt tiêu đề Máy chủ lưu trữ mà Apache đang mong đợi như một phần của quá trình chuyển giao proxy_pass với tùy chọn cấu hình bổ sung.

NGINX có biến sau cho proxy_set_header để tăng thêm những gì được chuyển tới proxy trong phần phụ trợ. Vì vậy, bạn sẽ có một cái gì đó như thế này:

...

địa điểm / {
    proxy_pass http://10.20.30.40;
    proxy_set_header Máy chủ ví dụ.com;
}
...

trong cấu hình NGINX của bạn cho proxy ngược. Khi đó, Apache sẽ không quan tâm đến X-Forwarded-Host vì bạn đã đặt tiêu đề Host thay vì Apache Nên ưu tiên phục vụ.

Cái này Nên sửa chữa mọi thứ - Tôi sử dụng nhiều hệ thống NGINX theo cách này khi miền mà Trình duyệt truy cập khác với máy chủ phản hồi của chương trình phụ trợ - và cho đến nay nó hoạt động với các chương trình phụ trợ Django, chương trình phụ trợ PHP, Apache, thậm chí cả máy chủ Python HTTP mà tôi sử dụng để thử nghiệm mọi thứ . Và sự hiểu biết của tôi về Apache là nó sẽ ưu tiên tiêu đề Máy chủ hơn X-Forwarded-Host.

John Hanley avatar
lá cờ cn
Tôi có thể sai. Nếu bạn gửi yêu cầu từ một dịch vụ Cloud Run sang một dịch vụ khác, thì tiêu đề Máy chủ lưu trữ phải khớp với dịch vụ được gọi, nếu không, bạn sẽ nhận được lỗi 404. Đây là một ví dụ trong đó Miền tùy chỉnh Cloud Run cùng với giải pháp của bạn có thể giải quyết vấn đề.
lá cờ co
@JohnHanley À, vâng, có thể bạn đúng, tuy nhiên nếu OP đang mong đợi điểm cuối phân phát example.com và nhận các URL khác thì họ cần một trình nghe chung phù hợp với tất cả các miền tiềm năng ở đây. Cloud Run Custom Domains tôi nghĩ sẽ hoạt động tốt hơn cho OP (có vẻ như đó phải là một câu trả lời duy nhất)
John Hanley avatar
lá cờ cn
Tôi nghĩ rằng giải pháp của bạn là một nửa chính xác để bắt đầu. Sau đó, OP có thể xem xét Miền tùy chỉnh chạy trên đám mây, v.v. để logic miền của anh ấy hoạt động. Tôi không hiểu sự phụ thuộc của anh ấy vào tên miền cho phần phụ trợ.
lá cờ co
@JohnHanley tốt nếu máy chủ $BACKEND đang chạy 50 tên miền riêng biệt và phục vụ nội dung dựa trên tiêu đề Máy chủ (whcih là cách VirtualHost hoạt động và các trường ServerName / ServerAlias ​​của chúng trong Apache), thì tiêu đề Máy chủ là cần thiết để chỉ định cách kết nối và với cái gì Máy chủ vượt qua để nội dung được phục vụ chính xác. Ngẫu nhiên, đó cũng là cách NGINX xác định vùng nào sẽ phục vụ - trường server_name (regex, ký tự đại diện, v.v.) khớp với nhau xác định cấu hình máy chủ/trang web nào sẽ phục vụ cho một yêu cầu nhất định.
John Hanley avatar
lá cờ cn
Tuy nhiên, đó không phải là cách Cloud Run hoạt động. Tiêu đề Máy chủ xác định dịch vụ nào mà Google Cloud GFE định tuyến yêu cầu. Nếu chương trình phụ trợ xử lý 50 miền, thì dịch vụ Cloud Run sẽ cần 50 Miền tùy chỉnh.Vì mỗi miền tùy chỉnh sẽ yêu cầu ánh xạ miền, tôi không chắc điều đó thậm chí còn được hỗ trợ (giới hạn hạn ngạch). Chương trình phụ trợ sẽ cần một phương pháp khác để hỗ trợ loại nhận dạng đó. Một tiêu đề tùy chỉnh có thể sẽ hoạt động. Tuy nhiên, đây là một ví dụ về việc biến một thiết kế thành một dịch vụ có thể không phù hợp với kiến ​​trúc.
lá cờ co
@JohnHanley Tôi nghĩ tất cả những gì tôi phải biết là NGINX nằm ở đâu. Nếu tôi đang đọc đúng OP, example.com -> NGINX -> Google Cloud Run. Vì vậy, tiêu đề Máy chủ cho khối vị trí và proxy_pass chỉ cần đặt Máy chủ thành URL duy nhất của GCR cho yêu cầu. Giả sử rằng NGINX thực sự nằm ở example.com.
fairport avatar
lá cờ nl
Rất tiếc, câu trả lời này không hoạt động vì tôi không thể kết nối với bộ chứa Apache bằng địa chỉ IP, tôi phải sử dụng miền có tiêu đề Máy chủ để Google biết cách định tuyến yêu cầu đến đúng máy chủ. Tôi muốn sửa tiêu đề Máy chủ lưu trữ trong Apache để ứng dụng xây dựng các tuyến của nó một cách chính xác. Tiêu đề Máy chủ chính xác nằm trong X-Forwarded-Host hoặc tôi cũng có thể sử dụng một biến môi trường để xác định nó.
lá cờ co
@fairport Tôi không chắc có chức năng nào trong Apache để viết lại tiêu đề X-Forwarded-Host. Tôi đã tìm kiếm nhưng không thấy chức năng như vậy. Tôi nghĩ rằng nếu ứng dụng của bạn không hoạt động theo cách mà Google mong đợi, thì bạn cần phải xây dựng lại/cơ cấu lại ứng dụng của mình có tính đến các yêu cầu của Google, thay vì cố gắng đưa nó vào đúng vị trí. Điều này có ý nghĩa đối với GCR vì họ đang cấu trúc nó theo một cách rất cụ thể. (Tôi có thể xóa câu trả lời của mình tại một số điểm sau khi bạn đọc nhận xét này)
fairport avatar
lá cờ nl
Vâng, tôi hiện đang xem tài liệu về chỉ thị RequestHeader của Apache và xem liệu tôi có thể thay thế tiêu đề Máy chủ bằng một biến môi trường hay không. Một cách khác để khắc phục điều này có thể là thiết lập mạng VPC, theo cách này, dịch vụ Cloud Run sẽ có địa chỉ IP tĩnh mà tôi có thể sử dụng thay vì URL. Cách cuối cùng tôi có thể nghĩ nếu đang sửa đổi chính ứng dụng để nó thay thế tiêu đề Máy chủ bằng X-Forwarded-Host hoặc một biến môi trường nhưng điều này có vẻ khó khăn.Tôi sẽ trả lời câu hỏi của riêng mình nếu tôi tìm ra cách tốt để giải quyết vấn đề này.
Điểm:1
lá cờ nl

Tôi đã giải quyết vấn đề này bằng cách xác định một biến môi trường mới gọi là APP_HOST trong bảng điều khiển Google Cloud Run và đặt thành ví dụ.com.

Sau đó, tôi đã thêm cấu hình sau vào .htaccess tập tin trong thư mục gốc:

<IfModule mod_env.c>
    PassEnv APP_HOST
</IfModule>

<IfModule mod_headers.c>
    RequestHeader set Host %{APP_HOST}e env=APP_HOST
</IfModule>

Điều này cho phép tôi ghi đè lên Chủ nhà tiêu đề từ ví dụ-8gnm1aqrns-lz.a.run.app đến ví dụ.com dựa trên biến môi trường APP_HOST.

Tất nhiên tôi có thể mã hóa cứng tên máy chủ nhưng tôi nghĩ rằng việc sử dụng biến môi trường sẽ giúp bạn linh hoạt hơn nếu bạn muốn sử dụng cùng một biến .htaccess tệp trong các ngữ cảnh khác nhau, chẳng hạn như trên máy chủ dàn dựng.

Chỉnh sửa

Đây là cách bạn có thể giải quyết vấn đề này bằng cách sử dụng Máy chủ chuyển tiếp X, ví dụ: nếu bạn chạy máy chủ ảo và bạn cần truy cập trang web từ nhiều miền

<IfModule mod_setenvif.c>
    SetEnvIf X-Forwarded-Host (.*) REAL_HOST_HEADER=$1
    <IfModule mod_headers.c>
        RequestHeader set Host "%{REAL_HOST_HEADER}e"
    </IfModule>
</IfModule>

Điều này sẽ lấy tiêu đề từ Máy chủ chuyển tiếp X và đặt Chủ nhà tiêu đề dựa trên giá trị.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.