nginx 使用ssl证书配置https协议
如果能给你带来帮助,不胜荣幸,如果有错误也请批评指正,共同学习,共同进步。
第一,需要去申请或者购买ssl证书(这步略过,因为开发过程中没有给我提供证书和域名,只有ip地址),我从网上找了一份如何申请(购买)ssl证书(阿里云)的过程。
https://blog.csdn.net/qq_39241986/article/details/121448584
生成步骤我粘贴了一份:(这里我强调一下,使用openssl生成的证书,或者说是私钥,就是自己闹着玩还行,一般浏览器都不信任,建议去购买)
https://www.jianshu.com/p/1a0958202087
第二,开始在nginx当中的配置(我个人认为是重点)
打开nginx里面的conf目录 ==> 打开nginx.conf文件
listen 443 ssl; #https 的默认端口
server_name 127.0.0.1;#默认我代理到了本地,你可以代理到你的服务器地址,
#我用的是我自己签名生成的ssl证书,应该去各大云厂商申请自己的ssl证书
ssl_certificate F:/tool/nginx-1.19.6/ssl/lee.crt;
ssl_certificate_key F:/tool/nginx-1.19.6/ssl/lee.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
add_header Cross-Origin-Embedder-Policy 'require-corp';
add_header Cross-Origin-Opener-Policy 'same-origin';
add_header Cross-Origin-Resource-Policy 'cross-origin';
add_header 'Access-Control-Allow-Origin' *;
#允许带上cookie请求
add_header 'Access-Control-Allow-Credentials' 'true';
#允许请求的方法,比如 GET/POST/PUT/DELETE
add_header 'Access-Control-Allow-Methods' *;
#允许请求的header
add_header 'Access-Control-Allow-Headers' *;
#需要代理的路径, /:代表根 你可以随意追加,我写成了/Api
location /Api {
rewrite ^.+Api/(.*)$ /$1 break;
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_next_upstream http_502 http_504 error timeout invalid_header;
proxy_pass xxx.xxx.xxx.xxx:xxxx;# 这个是需要代理服务器的ip地址和端口,也可以代理到域名,由域名绑定IP地址
}
proxy_set_header 这几个值路由配置:
起初没有配置 proxy_set_header Host $host 等参数, 请求总是报 400(bad request)
nginx为了实现反向代理的需求而增加了一个ngx_http_proxy_module模块。其中proxy_set_header指令就是该模块需要读取的配置文件。在这里,所有设置的值的含义和http请求同中的含义完全相同,除了Host外还有X-Forward-For。
Host的含义是表明请求的主机名,因为nginx作为反向代理使用,而如果后端真是的服务器设置有类似防盗链或者根据http请求头中的host字段来进行路由或判断功能的话,如果反向代理层的nginx不重写请求头中的host字段,将会导致请求失败【默认反向代理服务器会向后端真实服务器发送请求,并且请求头中的host字段应为proxy_pass指令设置的服务 器】。同理,X_Forward_For字段表示该条http请求是有谁发起的?如果反向代理服务器不重写该请求头的话,那么后端真实服务器在处理时会认为所有的请求都来在反向代理服务器,如果后端有防攻击策略的话,那么机器就被封掉了。因此,在配置用作反向代理的nginx中一般会增加两条配置,修改http的请求头:这里的$http_host和$remote_addr都是nginx的导出变量,可以再配置文件中直接使用。如果Host请求头部没有出现在请求头中,则$http_host值为空,但是$host值为主域名。因此,一般而言,会用$host代替$http_host变量,从而避免http请求中丢失Host头部的情况下Host不被重写的失误。X-Forwarded-For:简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP,只有在通过了HTTP 代理或者负载均衡服务器时才会添加该项。 它不是RFC中定义的标准请求头信息,在squid缓存代理服务器开发文档中可以找到该项的详细介绍。标准格式如下:X-Forwarded-For: client1, proxy1, proxy2。
这里做简短的proxy_set_header 及其值的说明,具体详细介绍可以参考这篇文章(写的非常好):
https://blog.csdn.net/yujia_666/article/details/109391066
还有就是涉及到跨域问题的配置,我这块处理的不好,也可以写成这样因为
location /api{
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
add_header 'Access-Control-Allow-Origin' $http_origin;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' '*';
return 204;
}
}
他的这个配置都是
There could be several add_header directives,These directives are inherited from the previous level if and only if there are no add_header directives defined on the current level.
仅当当前层级中没有add_header指令才会继承父级设置。
最后你需要重新监听一下原有的https的端口,如果输入的是http的端口,让他重新跳转到https
listen http的端口;
server_name 跳转的服务路径;
location / {
rewrite ^(.*) https://$server_name:12000$1 permanent;
}
强制跳转的方法有很多种:这是其中一种,具体如下:
方法一 (这是最古老的写法,不推荐)
rewrite ^(.*)$ https://$host$1 permanent;
方法二 (比较推荐)
return 301 https://$server_name$request_uri;
方法三 如果你有多个域名绑定在一起,可以只设定某些域名强制跳转
if ($host = “1.dyseo.com.cn”) {
rewrite ^/(.*)$ https://1.dyseo.com.cn permanent;
}
方法四
方法四跟之前的都不一样,我们不需要另外监听 443 端口的 server,而是都放在一起,像这样
listen 80;
listen 443 ssl http2;
server_name dyseo.com.cn www.dyseo.com.cn;
if ($server_port !~ 443){
rewrite ^(/.*)$ https://$host$1 permanent;
最后涉及到路径和/等问题,这块一块写一下:
1、root和alias
root:root指定的目录是上级目录,path匹配的整个路径会追加,即root+path;
alias:alias指定的目录必须带/,path匹配后面的内容会在alias指定的目录下查找,即alias+匹配到path路径后面的部分。
例:
location /www/ {
root /home/data;
}
访问路径:http://www.abc.com/www/a.html,实际上是访问/home/data/www/a.html。
location /www/ {
alias /home/data;
}
访问路径:http://www.abc.com/www/a.html,实际上是访问/home/data/a.html。
2、proxy_pass的斜杠问题
(1)path没有斜杠
location /api1 { proxy_pass http://localhost:8080; }
# http://localhost/api1/xxx -> http://localhost:8080/api1/xxx
location /api2 { proxy_pass http://localhost:8080/; }
# http://localhost/api2/xxx -> http://localhost:8080/xxx
location /api5 { proxy_pass http://localhost:8080/haha; }
# http://localhost/api5/xxx -> http://localhost:8080/haha/xxx,请注意这里的这里的双斜线。
(2)path有斜杠
location /api1/ { proxy_pass http://localhost:8080; }
# http://localhost/api1/xxx -> http://localhost:8080/api1/xxx
location /api2/ { proxy_pass http://localhost:8080/; }
# http://localhost/api2/xxx -> http://localhost:8080/xxx
location /api5/ { proxy_pass http://localhost:8080/haha; }
# http://localhost/api5/xxx -> http://localhost:8080/hahaxxx,请注意这里的haha和xxx之间没有斜杠。
总结:
path有无斜杠无影响,主要看proxy_pass有没有斜杠。proxy_pass没有的话,proxy_pass+path;有的话(包括端口和上下文都是一样的),proxy_pass+匹配到path路径后面的部分。
如果有什么疑问或者链接失效的问题,随时可以留言联系,链接内容都是亲自测试和使用的,我挂上其他链接是因为第一是觉得人家写得好,更深入,想分享给大家。第二:我比较懒,我学到了,但是不想写出来了。
参考链接:
https://www.zhzz.org/asp/1055
https://blog.csdn.net/lizzehqs/article/details/123661065
https://blog.csdn.net/goldenfish1919/article/details/126629250