前言
近一段时间由于看到v*云服务厂商有活动,就注册并开了台云服务器,试一下区别。
(“充10美元送30天内有效的250美元的免费额度,意思是30天内在 你加起来 不超出250美元的 服务随便开,但是注意的是30天后这就不免费了,记得及时关闭。只支持paypal,而阿里alipay一般是充值没活动的”)
于是开始各种尝试,偶尔一次搭建服务下载镜像等文件,由于443端口并发较高,流量大,下载时间长,导致xx把443端口给封闭了,其他国外地区访问正常。(后来前面加个免费的cxxx cdn就可以解决)
正好总结一下http跳转https的各种方式,实际上是一种重复造轮子的文章,但是最起码证明到现在这个时间点它仍是这样配置
Nginx http跳转https(443端口)
方法一
rewrite强制将http的URL重写成https
server {
listen 80;
server_name aaa.bbb.com ccc.bbb.com;
rewrite ^(.*) https://$server_name$1 permanent;
}
server {
listen 443 ssl;
server_name aaa.bbb.com ccc.bbb.com;
charset utf-8;
ssl_certificate /etc/letsencrypt/live/bbb.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/bbb.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3; # TLSv1.3需要nginx 1.13.0以上版本
# 如果nginx版本低,建议使用这种加密算法配置
# ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_ecdh_curve secp384r1;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
keepalive_timeout 70;
#日志
access_log /var/log/nginx/bbb.access.log;
error_log /var/log/nginx/bbb.error.log;
#跨域
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
add_header Access-Control-Allow-Headers Content-Type,Authorization;
#白名单
allow xx.xx.0.0/16;
allow xx.xx.0.0/16;
deny all;
root /usr/share/nginx/bbb;
location / {
proxy_redirect off; #隐藏nginx版本
proxy_http_version 1.1;
index index.html;
#.....其他
}
}
方式二
return把http的域名请求转成https
server {
listen 80;
server_name aaa.bbb.com ccc.bbb.com;
#schema判断是https的就按照下面的方式跳转
if ($scheme = http){
return 301 https://$server_name$request_uri;
}
}
#or
#server {
# listen 80;
# server_name aaa.bbb.com ccc.bbb.com;
# return 301 https://$server_name$request_uri;
#}
server {
listen 443 ssl;
server_name aaa.bbb.com ccc.bbb.com;
charset utf-8;
ssl_certificate /etc/letsencrypt/live/bbb.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/bbb.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3; # TLSv1.3需要nginx 1.13.0以上版本
# 如果nginx版本低,建议使用这种加密算法配置
# ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_ecdh_curve secp384r1;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
keepalive_timeout 70;
#日志
access_log /var/log/nginx/bbb.access.log;
error_log /var/log/nginx/bbb.error.log;
#跨域
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
add_header Access-Control-Allow-Headers Content-Type,Authorization;
#白名单
allow xx.xx.0.0/16;
allow xx.xx.0.0/16;
deny all;
root /usr/share/nginx/bbb;
location / {
proxy_redirect off; #隐藏nginx版本
proxy_http_version 1.1;
index index.html;
#.....其他
}
}
方式三
error_page 497 重新定义端口和链接
当nginx 配置的站点只允许https访问时,我们使用http去访问,就会报出497错误码
我们就可以利用error_page将497状态码的链接重定向到 https
这个也可以用来将http跳转到非443的ssl端口
例如:
error_page 497 https://$host:8443$request_uri;
其他配置:
error_page 497 https://$host:$server_port$request_uri; 重定向到其他端口
error_page 497 https://$host$request_uri; 默认用302,临时重定向
error_page 497 =301 https://$host$request_uri; 永久重定向
error_page 497 =307 https://$host$request_uri; 临时重定向,不改变请求的方法(如post还是post)
server {
listen 80;
server_name aaa.bbb.com ccc.bbb.com;
error_page 497 https://$host$uri?$args;
# error_page 497 https://$host:$server_port$request_uri;
}
server {
listen 443 ssl;
server_name aaa.bbb.com ccc.bbb.com;
charset utf-8;
ssl_certificate /etc/letsencrypt/live/bbb.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/bbb.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3; # TLSv1.3需要nginx 1.13.0以上版本
# 如果nginx版本低,建议使用这种加密算法配置
# ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_ecdh_curve secp384r1;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
keepalive_timeout 70;
#日志
access_log /var/log/nginx/bbb.access.log;
error_log /var/log/nginx/bbb.error.log;
#跨域
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
add_header Access-Control-Allow-Headers Content-Type,Authorization;
#白名单
allow xx.xx.0.0/16;
allow xx.xx.0.0/16;
deny all;
root /usr/share/nginx/bbb;
location / {
proxy_redirect off; #隐藏nginx版本
proxy_http_version 1.1;
index index.html;
#.....其他
}
}
Nginx http跳转https(非443端口)
方式一
return 加 proxy_set_header Host $host:$server_port
$host参数不包含端口号,如果请求头部有端口就会丢失,从而使后端程序不能正确的获取端口号
server {
listen 80;
server_name aaa.bbb.com ccc.bbb.com;
#schema判断是https的就按照下面的方式跳转
if ($scheme = http){
return 301 https://$server_name:8443$request_uri;
}
}
server {
listen 8443 ssl;
server_name aaa.bbb.com ccc.bbb.com;
charset utf-8;
ssl_certificate /etc/letsencrypt/live/bbb.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/bbb.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3; # TLSv1.3需要nginx 1.13.0以上版本
# 如果nginx版本低,建议使用这种加密算法配置
# ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_ecdh_curve secp384r1;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
keepalive_timeout 70;
#日志
access_log /var/log/nginx/bbb.access.log;
error_log /var/log/nginx/bbb.error.log;
#跨域
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
add_header Access-Control-Allow-Headers Content-Type,Authorization;
#白名单
allow xx.xx.0.0/16;
allow xx.xx.0.0/16;
deny all;
root /usr/share/nginx/bbb;
location / {
index index.html;
proxy_redirect off; #隐藏nginx版本
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host:$server_port;
location /live {
proxy_redirect off;
proxy_pass http://127.0.0.1:8081;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
#.....其他
}
}
方式二
error_page 497 重新定义端口和链接
server {
listen 80;
server_name aaa.bbb.com ccc.bbb.com;
error_page 497 https://$host:8443$request_uri;
}
server {
listen 8443 ssl;
server_name aaa.bbb.com ccc.bbb.com;
charset utf-8;
ssl_certificate /etc/letsencrypt/live/bbb.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/bbb.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3; # TLSv1.3需要nginx 1.13.0以上版本
# 如果nginx版本低,建议使用这种加密算法配置
# ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_ecdh_curve secp384r1;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
keepalive_timeout 70;
#日志
access_log /var/log/nginx/bbb.access.log;
error_log /var/log/nginx/bbb.error.log;
#跨域
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
add_header Access-Control-Allow-Headers Content-Type,Authorization;
#白名单
allow xx.xx.0.0/16;
allow xx.xx.0.0/16;
deny all;
root /usr/share/nginx/bbb;
location / {
proxy_redirect off; #隐藏nginx版本
proxy_http_version 1.1;
index index.html;
#.....其他
}
}
Nginx http,https多端口共存
这个需求常见于老服务,比如一个老项目以前是http的,后来又开发新的项目的访问域名还是这个,不过新地址需要改成https,比如加了个项目/live,这要求访问bbb.com/live是https
并且要不影响其他用户用http访问bbb.com/one,还有不清楚另外配置的那个https的项目是否有问题,这时候就可能需要2个访问方式都要暂时存在,之后看情况再看是否配置跳转
简单的来说就是,
只需要把listen 80; listen 443 ssl; 及其他要开启的端口一起放在同一个server里就可以
server {
listen 80;
listen 443 ssl;
listen 8443 ssl;
server_name aaa.bbb.com ccc.bbb.com;
charset utf-8;
......
}
补充
一台服务器上能部署多个nginx服务吗?
原则上来说是可以的,nginx安装到不同的位置,并且nginx的配置文件的端口不冲突即可
但不建议这样做,一般是人们是通过server添加多个虚拟主机,而不是启动多个nginx
即使是搞高可用也是一台服务器一个nginx,一台服务器上搞什么高可用,如果那台服务器宕机web全挂了