如何在 NGINX 上将 HTTPS 重定向到 HTTP?
有没有办法通过在域的 vhost 文件中添加规则来将 HTTPS 请求重定向到 HTTP?
Is there a way to redirect HTTPS requests to HTTP by adding a rule in the domain's vhost file?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
为什么这样的东西有用?乍一看,我不确定是否可以做到。但这提出了一个有趣的问题。
您可以尝试在配置文件中添加重定向语句并重新启动服务器。可能会发生两种可能性:
如果我想出更具体的东西,我会添加更多内容。
更新: (几个小时后)
你可以试试这个。您需要将其放入 nginx.conf 文件中 -
向客户端发送永久重定向。我假设您使用 https 端口 443(默认)。
添加此项,以便您在端口 80 上的正常 http 请求不会受到干扰。
更新: 2016 年 12 月 18 日
- 在 nginx 版本 > 中应使用
server_name _
代替server_name _ *
0.6.25(感谢@Luca Steeb)Why is something like that useful? At first look I wasn't sure if it could be done. But it presented an interesting question.
You might try putting a redirect statement in your config file and restarting your server. Two possibilities might happen:
Will add more if I come up with something more concrete.
UPDATE: (couple of hours later)
You could try this. You need to put this in your nginx.conf file -
Sends a permanent redirect to the client. I am assuming you are using port 443 (default) for https.
Add this so that your normal http requests on port 80 are undisturbed.
UPDATE: 18th Dec 2016
-
server_name _
should be used instead ofserver_name _ *
in nginx versions > 0.6.25 (thanks to @Luca Steeb)Nginx 应避免使用
rewrite
和if
。著名的一句话是,“Nginx 不是 Apache”:换句话说,Nginx 有比重写更好的方法来处理 URL。从技术上讲,return
仍然是重写模块的一部分,但它不承担rewrite
的开销,并且不像if
那样充满警告。代码>.Nginx 有一个完整的页面来解释 为什么
if
是“邪恶的”。它还提供了一个建设性的页面,解释为什么rewrite
和if
是不好,以及如何解决它。以下是该页面关于rewrite
和if
的内容:您可以使用
return
正确解决此问题:如果您预计很多机器人不会发送
Host
标头,您可以使用$host
而不是$http_host
,只要您坚持使用端口 80 和 443。否则,您需要动态填充$http_host
替代品。尽管使用了if
,但只要该代码出现在server
的根目录中(而不是在location
块中),它就是高效且安全的。但是,您需要使用默认服务器才能适用,而使用 https 时应避免这种情况。如果您想对特定路径强制实施 SSL/TLS,但又禁止这样做:
如果您的服务器未与客户端直接通信(例如,如果您使用的是 CloudFlare),那么事情会变得更加复杂。您需要确保与客户端直接通信的任何服务器都会向请求添加适当的
X-Forwarded-Proto
标头。使用这个是一个混乱的提议;有关完整说明,请参阅 IfIsEvil。为了使其有用,出于各种复杂的原因,
if
块不能位于location
块内。这强制使用rewrite
进行 URI 测试。 简而言之,如果您必须在生产服务器上使用它……不要这样做。可以这样想:如果您已经无法满足 Apache 的需求,那么您就已经无法满足此解决方案的需求。/secure、/secure/ 以及 /secure/ 中的任何内容都将强制执行 https,而所有其他 URI 将强制执行 http。
(?! )
PCRE 构造是一个否定先行断言。(?: )
是一个非捕获组。rewrite
andif
should be avoided with Nginx. The famous line is, "Nginx is not Apache": in other words, Nginx has better ways to handle URLs than rewriting.return
is still technically part of the rewrite module, but it doesn't carry the overhead ofrewrite
, and isn't as caveat-ridden asif
.Nginx has an entire page on why
if
is "evil". It also provides a constructive page explaining whyrewrite
andif
are bad, and how you can work around it. Here's what the page has to say regardingrewrite
andif
:You can solve this problem properly using
return
:If you expect a lot of bots that don't send a
Host
header, you can use$host
instead of$http_host
as long as you stick to ports 80 and 443. Otherwise, you'll need to dynamically populate an$http_host
substitute. This code is efficient and safe as long as it appears in the root ofserver
(rather than in alocation
block), despite usingif
. However, you'd need to be using a default server for this to be applicable, which should be avoided with https.If you want to enforce SSL/TLS for specific paths, but forbid it otherwise:
If your server isn't in direct communication with the client--for example, if you're using CloudFlare--things get a bit more complicated. You'll need to ensure that any server in direct communication with the client adds an appropriate
X-Forwarded-Proto
header to the request.Using this is a messy proposition; for a full explanation, see IfIsEvil. In order for this to be useful, the
if
block cannot be inside alocation
block, for a variety of complex reasons. This forces the use ofrewrite
for URI testing. In short, if you have to use this on a production server... don't. Think of it this way: if you've outgrown Apache, you've outgrown this solution./secure, /secure/, and anything in /secure/ will enforce https, while all other URIs will enforce http. The
(?! )
PCRE construct is a negative lookahead assertion.(?: )
is a non-capturing group.这个问题更适合 serverfault.com 网站。
重定向到 http 的更好方法:
这避免了重写中的“if”子句和正则表达式,这是迄今为止其他解决方案的功能。两者都会对性能产生影响,但实际上,您必须拥有相当多的流量才能发挥作用。
根据您的设置,您可能还想在listen 子句中指定一个ip,并且可能在上面指定一个servername 子句。按原样,它将适用于所有域名的所有端口 443 请求。您通常希望每个域都有一个带 https 的 IP,因此将上述内容与 IP 绑定比将其与域名绑定更切中要害,但也有一些变化,例如,所有域都是一个域的子域。
编辑:TLS 现在已经接近通用,并且有了服务器名称识别 (SNI),它允许多个域上的 HTTPS 站点共享单个 IP。 这里有一篇很好的文章
this question would have been better suited to the serverfault.com site.
A better way to do the redirect to http:
This avoid both the 'if' clause and the regex in the rewrite that are features of the other solutions to date. Both have performance implications, though in practice you'd have to have quite a lot of traffic before it would matter.
Depending on your setup, you are likely to also want to specify an ip in the listen clause, and perhaps a servername clause in the above. As is, it will apply to all port 443 requests for all domain names. You generally want an IP per domain with https, so mostly tying the above to an IP is more to the point than tying it to a domain name, but there's variations on that, eg where all domains are subdomains of one domain.
EDIT: TLS is close to universal now, and with it Server Name Identification (SNI) which allows for HTTPS sites on multiple domains sharing a single IP. There's a good write-up here
这帮助了我:
This helped me:
打开您的域的 Nginx 配置文件。该文件通常位于 Linux 系统上的 /etc/nginx/sites-available/ 目录中。
比在 HTTPS(SSL) 配置的服务器块内添加以下行来执行重定向:
保存并退出文本编辑器,然后使用以下命令测试您的 nginx 配置:
sudo nginx -t
if temrinal 显示“ok” " 和 "valid" 那么你可以使用以下命令重新加载 nginx 配置:
sudo systemctl reload nginx
此配置将使用 301(永久)重定向将所有 HTTPS 请求重定向到 HTTP
Open the Nginx configuration file for your domain. This file is typically located in the /etc/nginx/sites-available/ directory on Linux systems.
than inside your server block for the HTTPS(SSL) configuration, add the folowing lines to perform the redirection:
save and exit text editor than test your nginx config with :
sudo nginx -t
if temrinal showed "ok" and "valid" then you can reload nginx config using :
sudo systemctl reload nginx
This configuration will redirect all HTTPS requests to HTTP with a 301 (permanent) redirect
唯一简单的规则已经在我上面的帖子中解释过:
The only simple rule is already explained on the post above me:
插入此代码后,HTTP 默认服务器的所有流量都会重定向到 HTTPS。
After inserting this code, all traffic for the HTTP default server redirects to HTTPS.