2013-07-03 29 views
11

Vì vậy, tôi có một ngăn xếp máy chủ tương đối thẳng về phía trước sử dụng tính năng tải xuống SSL và cân bằng tải HTTP. Thiết lập trông giống như sau:Thuyết phục Apache của giao thức máy khách gốc

(client) -> (SSL offload - stud) -> (balancer - haproxy) -> (http server - apache) 

Câu hỏi của tôi không phải là về việc cắm tất cả điều này lên. Nó hoạt động tuyệt vời, và tôi thành thật thổi bay đi ngay lập tức nó đã được thiết lập như thế nào. Tôi cũng sẽ thêm rằng các máy khách HTTP kết nối trực tiếp với haproxy, do đó bỏ qua SSL được tải xuống. Và đối với hồ sơ, có các đối tác dự phòng cho từng phần trên.

Sự cố hơi trừu tượng. Tôi sẽ bắt đầu với một cuộc biểu tình. Các khách hàng có yêu cầu thông qua các thiết lập để https://myserver.tld/scp (một số tiêu đề loại bỏ để giữ cho mọi thứ rõ ràng)

GET /scp HTTP/1.1 
Host: myserver.tld 
(headers added by haproxy) 
X-Forwarded-For: [original::client:ip] 
X-Forwarded-Proto: https 

Và server trả lời với

HTTP/1.1 301 Moved Permanently 
Date: Wed, 03 Jul 2013 03:16:25 GMT 
Server: Apache/2.2.15 (CentOS) 
Location: http://myserver.tld/scp/ 
Content-Length: 344 
Content-Type: text/html; charset=iso-8859-1 

Vì vậy, Apache mod_dir đang gửi một chuyển hướng đến cùng một URL với dấu gạch chéo. Đó là thích hợp để làm như vậy. Đó không phải là vấn đề. Vấn đề là giao thức HTTPS đã bị mất. Một lần nữa, tôi nghĩ Apache là đúng để chuyển hướng đến một URL HTTP, sau khi tất cả, kết nối nó nhận được từ ngăn xếp nói trên là một kết nối HTTP thường xuyên.

Vì vậy, từ quan điểm của Apache, máy khách đã yêu cầu kết nối HTTP thông thường. Cờ HTTPS bị tắt, cùng với tất cả các thông tin SSL khác, bởi vì phần SSL của phiên được xử lý bởi stud.

Mặc dù (bên trong Apache) Tôi có tiêu đề X-Forwarded-Proto hợp lệ, tôi không thể tìm cách báo cho Apache biết rằng kết nối máy khách gốc là HTTPS và thư mục cắt giảm chuyển hướng bằng mod_dir nên sử dụng giao thức https://. Tôi đang thiếu gì?

Điều duy nhất tôi đưa ra là viết lại tiêu đề Location bên trong haproxy cho các kết nối chuyển tiếp HTTPS để thay thế http:// với https://, nhưng tôi thực sự không nghĩ rằng cách tiếp cận đó rất thanh lịch. Tôi thích cho Apache (và (không làm tổn thương tôi) PHP tiếp tục xuống chuỗi) để được thông báo và xử lý kết nối như kết nối HTTPS bình thường.

Vui lòng trợ giúp!

PS - Tôi đã nghe nó nói trước đây nếu bạn phải hỏi, sau đó bạn đang làm sai. Có lẽ đó là vấn đề gốc ở đây, nhưng điều này có vẻ giống như một tình thế tiến thoái lưỡng nan đơn giản và tôi cảm thấy như là người duy nhất từng đến đây.

Trả lời

8
  1. Chuyển hướng thư mục cắt giảm: Nội dung bạn muốn là mod_rewrite.

    RewriteEngine On 
    RewriteCond %{HTTP:X-Forwarded-Proto} =https 
    RewriteCond %{REQUEST_FILENAME} -d 
    RewriteRule ^(.+[^/])$   https://www.example.com/$1/ [R=301,L,QSA] 
    

    Nếu header được thiết lập để https và tên tập tin được yêu cầu là một thư mục (-d), sau đó viết lại đó (thay thế example.com với tên miền riêng của bạn).

  2. Như để làm PHP đối xử với các kết nối như một kết nối HTTPS thông thường, thiết lập các biến môi trường HTTPS để on:

    SetEnvIf X-Forwarded-Proto https HTTPS=on 
    
+0

# 2 phù hợp với tôi. Cảm ơn – jontro

+0

Tôi đã phải điều chỉnh đề xuất 1 để làm cho nó hoạt động đúng cách để tôi sử dụng. Trước tiên, tôi chuyển sang RewriteCond thứ hai để: 'RewriteCond% {LA-U: REQUEST_FILENAME} -d' Để có được phù hợp với hoạt động bình thường (dựa trên [tài liệu của Apache] (http: //httpd.apache. org/docs/current/mod/mod_rewrite.html), đặc biệt là ghi chú về "nhìn về phía trước URL" Tôi cũng đã điều chỉnh lại tự động để bao gồm tên máy chủ và tránh trùng lặp '/': 'RewriteRule^(. + [^ /]) $ Https: //% {HTTP_HOST} $ 1/[R = 301, L, QSA]' '$ 1' var tự cung cấp dấu gạch chéo ban đầu, vì vậy không cần thiết trong URL viết lại –

+0

RewriteOptions AllowNoSlash là cần thiết với apache 2.4. –

10

Bạn có thể làm điều này bằng cách bao gồm các giao thức trong file hướng dẫn ServerName:

ServerName https://my-server-name 

Theo Apache docs:

Đôi khi, máy chủ chạy phía sau thiết bị xử lý SSL, chẳng hạn như proxy ngược, trình cân bằng tải hoặc thiết bị tải SSL. Trong trường hợp này, hãy xác định lược đồ https: // và số cổng mà khách hàng kết nối trong chỉ thị ServerName để đảm bảo rằng máy chủ tạo các URL tự tham chiếu chính xác.

+0

Điều này không hoạt động nếu bạn muốn có nhiều điểm vào ứng dụng, trong đó một là https: // và một là http: //. mod_dir sẽ * luôn * sử dụng lược đồ được chỉ định trong chỉ thị ServerName. Có các trường hợp URL sản xuất sẽ có https: // nhưng url nội bộ (để thử nghiệm, v.v.) có thể có http, đặc biệt trong các tình huống tải trọng SSL/TLS mà bạn muốn trực tiếp kiểm tra/giám sát các cá thể Apache. Bây giờ, có thể không quan trọng nếu URL 'không chính tắc' không tạo chuyển hướng chính xác, nhưng nó lộn xộn:/ – Tom17

+0

@ Tom17 Trong trường hợp đó, bạn có thể tạo VirtualHost riêng biệt cho các trang http và https, với cài đặt giống nhau ngoại trừ cho cổng và Tên máy chủ. –