如何在NGINX上将HTTPS重定向到HTTP?

dvtswwa3  于 2023-10-17  发布在  Nginx
关注(0)|答案(9)|浏览(165)

有没有一种方法可以通过在域的vhost文件中添加规则来将HTTPS请求重定向到HTTP?

c6ubokkw

c6ubokkw1#

为什么这样的东西有用?起初,我不确定这是否可以做到。但它提出了一个有趣的问题。
您可以尝试在配置文件中放置重定向语句,然后重新启动服务器。可能会发生两种情况:
1.服务器将发出重定向-你似乎想要什么。
1.服务器将首先进行https交换,然后发出重定向,在这种情况下,有什么意义?
如果我能想出更具体的东西,会增加更多。

更新:(几个小时后) 你可以试试这个。你需要把它放在你的nginx.conf**文件中-

server {
       listen 443;
       server_name _ *;
       rewrite ^(.*) http://$host$1 permanent;
 }

向客户端发送永久重定向。我假设你正在使用端口443(默认)的https。

server {
    listen      80;
    server_name _ *;
    ...
}

添加此内容,以便端口80上的正常http请求不受干扰。

*更新: 2016年12月18日 * -server_name _应该在nginx版本> 0.6.25中使用,而不是server_name _ *(感谢@Luca Steeb)

fcipmucu

fcipmucu2#

rewriteif应该避免使用Nginx。有一句名言是“Nginx不是Apache”:换句话说,Nginx有比重写更好的方法来处理URL。从技术上讲,return仍然是重写模块的一部分,但它不携带rewrite的开销,也不像if那样充满警告。
Nginx在why if is "evil"上有一个完整的页面。它还提供了一个建设性的页面,解释why rewrite and if are bad,以及如何解决它。以下是页面关于rewriteif的说明:
这是一种错误的、繁琐的、无效的方式。
你可以使用return来解决这个问题:

server {
    listen 443 ssl;

    # You will need a wildcard certificate if you want to specify multiple
    # hostnames here.
    server_name domain.example www.domain.example;

    # If you have a certificate that is shared among several servers, you
    # can move these outside the `server` block.
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/cert.key;

    # 301          indicates a permanent redirect.  If your redirect is
    #              temporary, you can change it to 302 or omit the number
    #              altogether.
    # $http_host   is the hostname and, if applicable, port--unlike $host,
    #              which will break on non-standard ports
    # $request_uri is the raw URI requested by the client, including any
    #              querystring
    return 301 http://$http_host$request_uri;
}

如果你预计会有很多机器人不发送Host报头,你可以使用$host而不是$http_host,只要你坚持使用端口80和443。否则,您需要动态填充$http_host替代。这段代码只要出现在server的根目录中(而不是location块中),即使使用了if,也是高效和安全的。但是,您需要使用默认服务器才能使其适用,这应该避免使用https。

set $request_host $server_name:$server_port;
if ($http_host) {
    set $request_host $http_host;
}

如果您想对特定路径强制SSL/TLS,但在其他情况下禁止它:

server {
    listen 443 ssl;
    server_name domain.example;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/cert.key;

    location / {
        return 301 http://$host$request_uri;
    }

    location /secure/ {
        try_files $uri =404;
    }
}

server {
    listen 80;
    server_name domain.example;

    location / {
        try_files $uri =404;
    }

    location /secure/ {
        return 301 https://$http_host$request_uri;
    }
}

如果您的服务器没有与客户端直接通信-例如,如果您使用CloudFlare-事情会变得有点复杂。您需要确保与客户端直接通信的任何服务器都将适当的X-Forwarded-Proto头添加到请求中。
使用这个是一个混乱的命题;有关完整的解释,请参见IfIsEvil。为了使其有用,if块不能在location块内,原因很复杂。这迫使使用rewrite进行URI测试。如果您需要在生产服务器上使用此功能,则...别这样。你这样想:如果您已经超越了Apache,那么您已经超越了这个解决方案。
/secure、/secure/和/secure/中的任何内容都将强制使用https,而所有其他URI都将强制使用http。(?! ) PCRE结构是negative lookahead assertion(?: )non-capturing group

server {
    # If you're using https between servers, you'll need to modify the listen
    # block and ensure that proper ssl_* statements are either present or
    # inherited.
    listen 80;
    server_name domain.example;

    if ($http_x_forwarded_proto = https) {
        rewrite ^(?!/secure)/ http://$http_host$request_uri? permanent;
    }
    if ($http_x_forwarded_proto != https) {
        rewrite ^/secure(?:/|$) https://$http_host$request_uri? permanent;
    }
}
xmq68pz9

xmq68pz93#

location / {
    if ($scheme = https) {
        rewrite ^(.*)? http://$http_host$1 permanent;
    }
}
ztyzrc3y

ztyzrc3y4#

这个问题更适合于serverfault.com网站。
一个更好的重定向到http的方法:

server {
   listen 443;
   return 301 http://$host$request_uri;
}

这避免了重写中的“if”子句和正则表达式,这是迄今为止其他解决方案的特征。两者都有性能方面的影响,尽管在实践中,您必须有相当多的流量才能发挥作用。
根据您的设置,您可能还希望在listen子句中指定ip,或者在上面的servername子句中指定。它将适用于所有域名的所有端口443请求。您通常希望每个域的IP与https,所以大多数情况下,将上述内容绑定到IP比将其绑定到域名更重要,但也有一些变化,例如,所有域都是一个域的子域。
编辑:TLS现在已经接近通用了,它的服务器名称标识(SNI)允许多个域上的HTTPS站点共享一个IP。写得很好here

bwntbbo3

bwntbbo35#

这帮助了我:

server {
    listen 443;
    server_name server.org www.server.org;
    rewrite ^ http://$server_name$request_uri? permanent;
}
ktca8awb

ktca8awb6#

打开您的域的Nginx配置文件。此文件通常位于Linux系统上的/etc/nginx/sites-available/目录中。比在HTTPS(SSL)配置的服务器块中,添加以下行来执行重定向:

server {
    listen 443 ssl;
    server_name your-domain.com;
    ssl_certificate /path/to/your/ssl/certificate.crt;
    ssl_certificate_key /path/to/your/ssl/private-key.key;

    # Perform the HTTPS to HTTP redirect
    location / {
        return 301 http://$host$request_uri;
    }

    # Additional SSL configuration settings go here
    }

保存并退出文本编辑器,然后测试你的nginx配置:
sudo nginx -t
如果temrinal显示“ok”和“valid”,那么你可以使用以下命令重新加载nginx配置:
sudo systemctl reload nginx
此配置将使用301(永久)重定向将所有HTTPS请求重定向到HTTP

9o685dep

9o685dep7#

不是一个合适的解决方案,但我能够通过使用Cloudflare解决我的用例,它为我透明地处理SSL。

2ic8powd

2ic8powd8#

唯一简单的规则已经在我上面的帖子中解释过了:

server {
    listen ip:443;
    server_name www.example.com;
    rewrite ^(.*) http://$host$1 permanent;
}
sd2nnvve

sd2nnvve9#

server{
  listen 80;
  listen [::]:80;

  server_name mywebsite.com ;
  return 301 https://$host$request_uri;
}

插入此代码后,HTTP默认服务器的所有流量都会重定向到HTTPS。

相关问题