在添加ssl_certificate之前,我的nginx.conf
非常简单:
server {
listen 80 default_server;
index index.php index.html index.htm;
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
fastcgi_pass php:9000;
include fastcgi_params;
fastcgi_read_timeout 1200s;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
然后我按照这里使用 Nginx 设置 letsencrypt([domain-name]
从头到尾进行替换),现在我的nginx.conf
样子:
server {
listen 80 default_server;
server_name [domain-name] www.[domain-name];
server_tokens off;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://[domain-name]$request_uri;
}
}
server {
listen 443 default_server ssl http2;
listen [::]:443 ssl http2;
server_name [domain-name];
ssl_certificate /etc/nginx/ssl/live/[domain-name]/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/[domain-name]/privkey.pem;
location / {
proxy_pass http://[domain-name];
}
index index.php index.html index.htm;
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
fastcgi_pass php:9000;
include fastcgi_params;
fastcgi_read_timeout 1200s;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
请参阅此处的更改 - https://www.diffchecker.com/bAfVjewE/,
我认为这非常简单、直接且合理。
但是,我的 php 网站完全崩溃了——我的 chrome 浏览器说它进入了无限重定向(“重定向次数过多”),请参阅注释 2。
可能的原因是什么?如何解决?
笔记,
- 添加 ssl_certificate 很好,但是即使我在空站点上进行测试,也会出现无限重定向。
- 当发生无限重定向时,nginx 日志只会打印
...[08/Aug/2024:15:xx:yy +0000] "GET / HTTP/1.1" 301 162 "-" "Mozilla/5.0 (X11; Linux x86_64)...
,即使我已经看到浏览器上的协议已从 更改http
为https
。
如果我使用 访问它curl
,我会得到:
$ curl -i https://my.site.name:443/
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Thu, 08 Aug 2024 15:42:45 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: https://my.site.name/
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
服务器日志为:
[08/Aug/2024:15:42:45 +0000] "GET / HTTP/1.1" 301 162 "-" "curl/8.5.0" "my.ip"
[08/Aug/2024:15:42:45 +0000] "GET / HTTP/1.1" 301 162 "-" "curl/8.5.0" "-"
错误日志为空,因为这是我的 ngix 日志配置方式:
cd /var/log/nginx/
root@5b6a9033cb31:/var/log/nginx# ls -l
total 0
lrwxrwxrwx 1 root root 11 Jul 23 07:14 access.log -> /dev/stdout
lrwxrwxrwx 1 root root 11 Jul 23 07:14 error.log -> /dev/stderr
问题是第一个服务器块监听端口 80(HTTP)并将所有流量重定向到 HTTPS(https://[domain-name]$request_uri)。
第二个服务器块监听端口 443(HTTPS)并将流量代理回同一个域(proxy_pass http://[domain-name];)。
这会形成重定向循环。
用户请求http://my.site.name
服务器重定向到https://my.site.name
HTTPS 服务器将请求代理回http://my.site.name
HTTP 服务器重定向到https://my.site.name
循环继续......
要修复此问题,您必须确保 HTTPS 服务器未代理回 HTTP 服务器。相反,它应该直接提供内容。
像这样:
因此,HTTPS 块中的 try_files $uri $uri/ /index.php?$query_string; 可确保正确提供请求,而无需代理回 HTTP。
位置 ~.php$ { ... } 块设置为直接在 HTTPS 服务器中处理 PHP 文件。
HTTP 块中的 return 301 https://$host$request_uri; 确保所有 HTTP 请求都重定向到 HTTPS。
更正代码,然后运行
nginx -s reload
,它就应该可以工作了。############### 已编辑 ################
您无需删除 Nginx 反向代理即可解决此问题。通过确保代理在同一协议(即 HTTPS)内进行,您仍然可以从反向代理中受益。
一种方法是调整 HTTPS 服务器块中的 proxy_pass 指令以使用 https:// 而不是 http://。这可确保一旦流量重定向到 HTTPS,它就会停留在 HTTPS 上下文中,从而防止出现循环:
这样,您仍然可以利用 Nginx 反向代理的优势,同时解决重定向循环问题。如果您需要有关此设置的任何进一步帮助,请随时联系我们!