Nginx:在一条路径上强制使用SSL,在另一条路径上强制使用非SSL


27

如何设置Nginx conf文件以仅在站点中的一个路径上强制使用SSL,而在其余所有路径上强制使用非SSL?

例如,我希望/ user下的所有URL为https,但其余所有URL为http。

对于第一部分,我有:

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

我不想使用“如果”。我认为它将利用操作顺序的优势,但我不想陷入循环。

Answers:


38

在您的nginx配置中,您应该有两个“服务器”区域。一个用于端口80,另一个用于端口443(非SSL和SSL)。只需在非SSL网站上添加一个位置即可重定向到您的SSL页面。

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

它将所有以/ user结尾的流量转发到您的https://服务器。

然后,在443服务器中,执行相反的操作。

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

2
这种方法是好的,但是它会陷入一些常见的陷阱中,特别是“ Root inside location block”和“ Taxing
rewrites

1
我编辑了。看起来还好吗?我还拿出了listen 80,并添加了http_host。
pbreitenbach

使用此配置,当用户浏览站点上的页面时,连接从/切换到ssl / non-ssl,ssl表示以url开头的URL /user,non-ssl表示所有其他url。结果,即使用户明确https://www.example.com/输入浏览器的地址栏,结果页面也为http://www.example.com/。有没有一种方法可以通过此答案中所述的设置在ssl / non-ssl之间实现自动url重写,但是如果用户在地址栏中明确键入了ssl请求,仍然可以遵循该请求?谢谢!
goodbyeera 2015年

@goodbyeera是的。如果要强制用户在某些区域使用SSL,则可以从那里覆盖他们的协议,但只要从443服务器配置中删除重写命令,就可以在其他地方使用它们。当然,现在当他们进入安全部件时,当他们去其他地方时仍会使用SSL进行浏览,但是它允许人们从一开始就选择使用SSL。
Chuck Dries

13

Nginx允许在同server一块中同时处理HTTP和HTTPS 。因此,您不必为两者都重复指令,并且可以重定向要保护的路径

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 ...
}

确保不要ssl on此处放置行,因为它将破坏普通的HTTP。

(可选)您可以使用以下方法将所有其他请求从HTTPS重定向回HTTP:

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

更新:正如Alexey Ten在评论部分所指出的那样,检查scheme每个请求并不是一个非常明智的主意。您应该按照声明性的方式配置nginx。在这种情况下,用重定向声明两个服务器块location,将公共逻辑移动到一个单独的文件中,include并在这两个文件中。因此,GruffTech的答案更好。


2
为每个请求制定nginx检查方案是无效的。
阿列克谢2014年

1
我知道这个问题在3年前就已经回答了,但是我在努力做自己逐渐做的事情的同时发现了它,只是想与将跟随我步伐的人们分享我的结果。
纳特(Hnatt)2014年

1
好吧,您应该阅读wiki.nginx.org/IfIsEvil
Alexey

1
@AlexeyTen是不是“无法避免使用if的情况”?还有其他方法可以在不重复指令的情况下为HTTP和HTTPS进行相同的配置吗?
纳纳特(Hnatt)2014年

2
使用include指令作为通用指令。重复一些就可以了。
阿列克谢2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.