nginx - (http / https) 非 www 到 www 重定向
nginx - (http / https) non-www to www redirection
我在 laravel 5 框架上有一个网站 运行,并通过 laravel forge 托管在 DigitalOcean 上。为了试用证书,我刚刚从 Namecheap 购买了一个简单的 SSL 证书。在安装证书之前一切都很好,我能够正确加载我的网站。在我通过 Laravel Forge 安装证书后,我的站点不再可加载(http 或 https)。我不知道发生了什么,也不知道从哪里开始调试。希望有人能够为我提供一些帮助。
我会在下面为您提供尽可能多的信息。
Nginx.conf 通过 Laravel 伪造
server {
listen 80;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 80;
server_name www.example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
return 301 $scheme://www.example.com$request_uri;
}
server {
listen 443 ssl;
server_name www.example.com;
root /home/forge/www.example.com/public;
# FORGE SSL (DO NOT REMOVE!)
ssl_certificate /etc/nginx/ssl/www.example.com/10772/server.crt;
ssl_certificate_key /etc/nginx/ssl/www.example.com/10772/server.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
client_max_body_size 128M;
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log off;
error_log /var/log/nginx/www.example.com-error.log error;
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
服务器详细信息
VPS 提供商:DigitalOcean
部署:Laravel锻造
平台:Ubuntu 14.04 x64 vmlinuz-3.13.0-57-generic
框架:Laravel 5
域名注册:Namecheap
DNS 服务器:ns1,ns2,ns3.digitalocean.com
CA:Comodo PositiveSSL
更新一:根据楼下小伙伴的建议检查iptables,我是这样的
Chain ufw-user-input (1 references)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
ACCEPT udp -- anywhere anywhere udp dpt:ssh
ACCEPT tcp -- anywhere anywhere tcp dpt:http
ACCEPT udp -- anywhere anywhere udp dpt:http
ACCEPT tcp -- anywhere anywhere tcp dpt:https
ACCEPT udp -- anywhere anywhere udp dpt:https
更新 2:curl -i 测试确实显示站点现在已被重定向到 https:// 连接。但是浏览器显示 ERR_CONNECTION_CLOSED
root@Apocalypse:/etc/nginx/ssl/www.example.com/10784# curl -i http://example.com
HTTP/1.1 301 Moved Permanently
Server: nginx/1.8.0
Date: Sat, 01 Aug 2015 09:52:53 GMT
Content-Type: text/html
Content-Length: 184
Connection: keep-alive
Location: https://www.example.com/
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.8.0</center>
</body>
</html>
root@Apocalypse:/etc/nginx/ssl/www.example.com/10784# curl -i http://www.example.com
HTTP/1.1 301 Moved Permanently
Server: nginx/1.8.0
Date: Sat, 01 Aug 2015 09:53:24 GMT
Content-Type: text/html
Content-Length: 184
Connection: keep-alive
Location: https://www.example.com/
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.8.0</center>
</body>
</html>
更新 3:openssl s_client return 出现此错误
openssl s_client -connect www.example.com:443
CONNECTED(00000003)
140000289871520:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 295 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---
更新 4:我发现了问题..显然是这一行
server {
listen 443 ssl;
server_name example.com;
return 301 $scheme://www.example.com$request_uri;
}
导致了这个问题。一旦我删除它然后一切都像魅力一样......但现在我的问题是我应该如何将https://example.com
重新路由到https://www.example.com
?假设上面的代码是执行那个动作。
你能访问80端口或443端口吗?试试 运行
curl -i http://example.com/
在你的命令行上,错误是什么?
你能查看nginx日志吗?
nginx 甚至运行,也许重新启动它?
service nginx restart
防火墙怎么样,是否对端口 443 开放?
检查 iptables 是否安装?
iptables -L
好的,我已经解决了这个问题。现在我从哪里开始呢。
第一
澄清一下,证书、Laravel forge和nginx配置文件都没有问题。一切都很好设置和配置。
第二
就像我在上面的问题中所做的那样,像这样配置你的nginx.conf:
server {
listen 80;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 80;
server_name www.example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
# FORGE SSL (DO NOT REMOVE!)
ssl_certificate /etc/nginx/ssl/www.example.com/10772/server.crt;
ssl_certificate_key /etc/nginx/ssl/www.example.com/10772/server.key;
return 301 $scheme://www.example.com$request_uri;
}
server {
listen 443 ssl;
server_name www.example.com;
root /home/forge/www.example.com/public;
# FORGE SSL (DO NOT REMOVE!)
ssl_certificate /etc/nginx/ssl/www.example.com/10772/server.crt;
ssl_certificate_key /etc/nginx/ssl/www.example.com/10772/server.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
client_max_body_size 128M;
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log off;
error_log /var/log/nginx/www.example.com-error.log error;
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
请注意,我希望您在本节中注意一件事。当您重定向 https 连接(端口 433 到端口 433)时,您需要再次指定要使用的证书和密钥。当服务器执行重定向时,自然会建立新的连接,因此需要新的握手序列。这就是为什么在我的 https://example.com
重定向中
server {
listen 443 ssl;
server_name example.com;
# FORGE SSL (DO NOT REMOVE!)
ssl_certificate /etc/nginx/ssl/www.example.com/10772/server.crt;
ssl_certificate_key /etc/nginx/ssl/www.example.com/10772/server.key;
return 301 $scheme://www.example.com$request_uri;
}
我必须重新指定证书,否则服务器将断开连接,因为没有可用于验证的凭据。完成此操作后,您应该完成了一半。
第三
为了获得正确的重定向,您需要检查一些事项并确保其配置正确。
- 要在您的 DNS 提供商和您的主机中配置的域名
提供者必须包括 www 和非 www A(主机)注册表和
指向同一个ip。
- 确保您的名称服务器能够将非 www 地址(带或不带 https)解析为您想要的地址。在我的例子中,所有
http://example.com
、http://www.example.com
、https://example.com
变成 https://www.example.com
。执行此检查,您可以使用@Wizzard 的建议 curl -i http://example.com/
终于
正确配置所有内容后,您应该可以进行安全连接浏览了。
我在 laravel 5 框架上有一个网站 运行,并通过 laravel forge 托管在 DigitalOcean 上。为了试用证书,我刚刚从 Namecheap 购买了一个简单的 SSL 证书。在安装证书之前一切都很好,我能够正确加载我的网站。在我通过 Laravel Forge 安装证书后,我的站点不再可加载(http 或 https)。我不知道发生了什么,也不知道从哪里开始调试。希望有人能够为我提供一些帮助。
我会在下面为您提供尽可能多的信息。
Nginx.conf 通过 Laravel 伪造
server {
listen 80;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 80;
server_name www.example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
return 301 $scheme://www.example.com$request_uri;
}
server {
listen 443 ssl;
server_name www.example.com;
root /home/forge/www.example.com/public;
# FORGE SSL (DO NOT REMOVE!)
ssl_certificate /etc/nginx/ssl/www.example.com/10772/server.crt;
ssl_certificate_key /etc/nginx/ssl/www.example.com/10772/server.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
client_max_body_size 128M;
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log off;
error_log /var/log/nginx/www.example.com-error.log error;
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
服务器详细信息 VPS 提供商:DigitalOcean
部署:Laravel锻造
平台:Ubuntu 14.04 x64 vmlinuz-3.13.0-57-generic
框架:Laravel 5
域名注册:Namecheap
DNS 服务器:ns1,ns2,ns3.digitalocean.com
CA:Comodo PositiveSSL
更新一:根据楼下小伙伴的建议检查iptables,我是这样的
Chain ufw-user-input (1 references)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
ACCEPT udp -- anywhere anywhere udp dpt:ssh
ACCEPT tcp -- anywhere anywhere tcp dpt:http
ACCEPT udp -- anywhere anywhere udp dpt:http
ACCEPT tcp -- anywhere anywhere tcp dpt:https
ACCEPT udp -- anywhere anywhere udp dpt:https
更新 2:curl -i 测试确实显示站点现在已被重定向到 https:// 连接。但是浏览器显示 ERR_CONNECTION_CLOSED
root@Apocalypse:/etc/nginx/ssl/www.example.com/10784# curl -i http://example.com
HTTP/1.1 301 Moved Permanently
Server: nginx/1.8.0
Date: Sat, 01 Aug 2015 09:52:53 GMT
Content-Type: text/html
Content-Length: 184
Connection: keep-alive
Location: https://www.example.com/
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.8.0</center>
</body>
</html>
root@Apocalypse:/etc/nginx/ssl/www.example.com/10784# curl -i http://www.example.com
HTTP/1.1 301 Moved Permanently
Server: nginx/1.8.0
Date: Sat, 01 Aug 2015 09:53:24 GMT
Content-Type: text/html
Content-Length: 184
Connection: keep-alive
Location: https://www.example.com/
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.8.0</center>
</body>
</html>
更新 3:openssl s_client return 出现此错误
openssl s_client -connect www.example.com:443
CONNECTED(00000003)
140000289871520:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 295 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---
更新 4:我发现了问题..显然是这一行
server {
listen 443 ssl;
server_name example.com;
return 301 $scheme://www.example.com$request_uri;
}
导致了这个问题。一旦我删除它然后一切都像魅力一样......但现在我的问题是我应该如何将https://example.com
重新路由到https://www.example.com
?假设上面的代码是执行那个动作。
你能访问80端口或443端口吗?试试 运行
curl -i http://example.com/
在你的命令行上,错误是什么?
你能查看nginx日志吗? nginx 甚至运行,也许重新启动它?
service nginx restart
防火墙怎么样,是否对端口 443 开放?
检查 iptables 是否安装?
iptables -L
好的,我已经解决了这个问题。现在我从哪里开始呢。
第一
澄清一下,证书、Laravel forge和nginx配置文件都没有问题。一切都很好设置和配置。
第二
就像我在上面的问题中所做的那样,像这样配置你的nginx.conf:
server {
listen 80;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 80;
server_name www.example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
# FORGE SSL (DO NOT REMOVE!)
ssl_certificate /etc/nginx/ssl/www.example.com/10772/server.crt;
ssl_certificate_key /etc/nginx/ssl/www.example.com/10772/server.key;
return 301 $scheme://www.example.com$request_uri;
}
server {
listen 443 ssl;
server_name www.example.com;
root /home/forge/www.example.com/public;
# FORGE SSL (DO NOT REMOVE!)
ssl_certificate /etc/nginx/ssl/www.example.com/10772/server.crt;
ssl_certificate_key /etc/nginx/ssl/www.example.com/10772/server.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
client_max_body_size 128M;
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log off;
error_log /var/log/nginx/www.example.com-error.log error;
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
请注意,我希望您在本节中注意一件事。当您重定向 https 连接(端口 433 到端口 433)时,您需要再次指定要使用的证书和密钥。当服务器执行重定向时,自然会建立新的连接,因此需要新的握手序列。这就是为什么在我的 https://example.com
重定向中
server {
listen 443 ssl;
server_name example.com;
# FORGE SSL (DO NOT REMOVE!)
ssl_certificate /etc/nginx/ssl/www.example.com/10772/server.crt;
ssl_certificate_key /etc/nginx/ssl/www.example.com/10772/server.key;
return 301 $scheme://www.example.com$request_uri;
}
我必须重新指定证书,否则服务器将断开连接,因为没有可用于验证的凭据。完成此操作后,您应该完成了一半。
第三
为了获得正确的重定向,您需要检查一些事项并确保其配置正确。
- 要在您的 DNS 提供商和您的主机中配置的域名 提供者必须包括 www 和非 www A(主机)注册表和 指向同一个ip。
- 确保您的名称服务器能够将非 www 地址(带或不带 https)解析为您想要的地址。在我的例子中,所有
http://example.com
、http://www.example.com
、https://example.com
变成https://www.example.com
。执行此检查,您可以使用@Wizzard 的建议curl -i http://example.com/
终于
正确配置所有内容后,您应该可以进行安全连接浏览了。