Nginx: buộc SSL trên một đường dẫn, không SSL trên các đường dẫn khác


27

Làm cách nào để thiết lập tệp conf Nginx để buộc SSL chỉ trên một trong các đường dẫn trong trang web của tôi và không phải SSL trên tất cả các phần còn lại?

Ví dụ: tôi muốn tất cả các URL bên dưới / người dùng là https nhưng tất cả các URL còn lại sẽ là http.

Đối với phần đầu tiên tôi có:

rewrite ^/user(.*) https://$http_host$request_uri?;

Tôi không muốn sử dụng "nếu". Tôi cho rằng nó sẽ tận dụng trật tự hoạt động nhưng tôi không muốn kết thúc trong một vòng lặp.

Câu trả lời:


38

Trong cấu hình nginx của bạn, bạn nên có hai khu vực "máy chủ". Một cho cổng 80 và một cho cổng 443 (không phải SSL và SSL). Chỉ cần thêm một vị trí trong trang web không phải SSL của bạn để chuyển hướng đến trang SSL của bạn.

server {
    root /var/www/
    location / {
    }
    location /user {
        rewrite ^ https://$host$request_uri? permanent;
    }
}

nó sẽ chuyển tiếp tất cả lưu lượng truy cập kết thúc tại / user đến máy chủ https: // của bạn.

Sau đó, trong máy chủ 443 của bạn, bạn làm ngược lại.

server {
    listen 443;
    root /var/www/
    location / {
        rewrite ^ http://$host$request_uri? permanent;
    }
    location /user {
    }
}

2
Cách tiếp cận này là tốt, nhưng nó rơi vào một vài Cạm bẫy phổ biến , cụ thể là "Root bên trong khối vị trí" và "Viết lại thuế"
kolbyjack

1
Tôi đã chỉnh sửa. Trông nó có ổn không? Tôi cũng lấy ra nghe 80 và thêm http_host.
poustitenbach

Với cấu hình này, kết nối chuyển từ / sang ssl / non-ssl khi người dùng điều hướng các trang trên trang web, ssl cho các url bắt đầu bằng /uservà không ssl cho tất cả các url khác. Kết quả là, ngay cả người dùng gõ rõ ràng https://www.example.com/vào thanh địa chỉ của trình duyệt, trang kết quả là http://www.example.com/. Có cách nào để thực hiện tự động viết lại url giữa ssl / non-ssl như đã đạt được bằng các cài đặt được mô tả trong câu trả lời này, nhưng vẫn tôn trọng yêu cầu ssl rõ ràng nếu nó được người dùng gõ rõ ràng vào thanh địa chỉ? Cảm ơn!
tạm biệt

@goodbyeera vâng. Nếu ý tưởng là buộc người dùng sử dụng SSL ở một số khu vực nhất định, chúng ta có thể ghi đè các giao thức của họ ở đó nhưng tôn trọng chúng ở mọi nơi khác bằng cách xóa các lệnh viết lại khỏi cấu hình máy chủ 443. Tất nhiên, bây giờ khi họ đi đến một phần được bảo mật, họ vẫn sẽ duyệt bằng SSL khi họ đi đến một nơi khác, nhưng nó cho phép mọi người chọn sử dụng SSL ngay từ đầu.
Chuck Dries

13

Nginx cho phép xử lý cả HTTP và HTTPS trong cùng một serverkhối. Do đó, bạn không phải lặp lại các chỉ thị cho cả hai và có thể chuyển hướng đường dẫn bạn muốn bảo mật

server {
  listen 80 default_server;
  listen 443 ssl;
  ... ssl certificate and other configs ...

  location /user {
    if ($scheme = 'http') {
      rewrite ^ https://$http_host$request_uri? permanent;
    }
  }

  ... your basic configuration ...
}

Hãy chắc chắn không đặt ssl ondòng ở đó vì nó sẽ phá vỡ HTTP đơn giản.

Theo tùy chọn, bạn có thể chuyển hướng tất cả các yêu cầu khác từ HTTPS trở lại HTTP theo cùng một cách:

if ($scheme = 'https') {
  rewrite ^ http://$http_host$request_uri? permanent;
}

CẬP NHẬT : như Alexey Ten vui lòng chỉ ra trong phần bình luận, kiểm tra schemetừng yêu cầu không phải là một ý tưởng rất sáng sủa. Bạn nên làm theo cách khai báo cấu hình nginx của bạn. Trong trường hợp này, khai báo hai khối máy chủ với các chuyển hướng bằng cách locationdi chuyển logic chung sang một tệp riêng và includenó ở cả hai. Vì vậy, câu trả lời của GruffTech là tốt hơn.


2
Không hiệu quả để thực hiện kế hoạch kiểm tra nginx cho mọi yêu cầu.
Alexey Mười

1
Tôi biết câu hỏi đã được trả lời 3 năm trước, nhưng tôi đã tìm thấy nó trong khi đang cố gắng làm những gì tôi dần dần làm và chỉ muốn chia sẻ kết quả của mình với những người sẽ theo dõi các bước của tôi.
Hnatt

1
Chà, bạn nên đọc wiki.nginx.org/ IfIsEvil
Alexey Ten

1
@AlexeyTen không phải là trường hợp "khi bạn không thể tránh sử dụng if"? Có cách nào khác để có cùng cấu hình cho HTTP và HTTPS mà không cần sao chép các chỉ thị không?
Hnatt

2
Sử dụng includechỉ thị cho các chỉ thị chung. Một số trùng lặp là OK.
Alexey Ten
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.