nginx 使用ssl證書配置https協(xié)議
如果能給你帶來幫助,不勝榮幸,如果有錯誤也請批評指正,共同學(xué)習(xí),共同進(jìn)步。
第一,需要去申請或者購買ssl證書(這步略過,因?yàn)殚_發(fā)過程中沒有給我提供證書和域名,只有ip地址),我從網(wǎng)上找了一份如何申請(購買)ssl證書(阿里云)的過程。
https://blog.csdn.net/qq_39241986/article/details/121448584
生成步驟我粘貼了一份:(這里我強(qiáng)調(diào)一下,使用openssl生成的證書,或者說是私鑰,就是自己鬧著玩還行,一般瀏覽器都不信任,建議去購買)
https://www.jianshu.com/p/1a0958202087
第二,開始在nginx當(dāng)中的配置(我個人認(rèn)為是重點(diǎn))
打開nginx里面的conf目錄 ==> 打開nginx.conf文件
listen 443 ssl; #https 的默認(rèn)端口
server_name 127.0.0.1;#默認(rèn)我代理到了本地,你可以代理到你的服務(wù)器地址,
#我用的是我自己簽名生成的ssl證書,應(yīng)該去各大云廠商申請自己的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;# 這個是需要代理服務(wù)器的ip地址和端口,也可以代理到域名,由域名綁定IP地址
}
proxy_set_header 這幾個值路由配置:
起初沒有配置 proxy_set_header Host $host 等參數(shù), 請求總是報 400(bad request)
nginx為了實(shí)現(xiàn)反向代理的需求而增加了一個ngx_http_proxy_module模塊。其中proxy_set_header指令就是該模塊需要讀取的配置文件。在這里,所有設(shè)置的值的含義和http請求同中的含義完全相同,除了Host外還有X-Forward-For。
Host的含義是表明請求的主機(jī)名,因?yàn)閚ginx作為反向代理使用,而如果后端真是的服務(wù)器設(shè)置有類似防盜鏈或者根據(jù)http請求頭中的host字段來進(jìn)行路由或判斷功能的話,如果反向代理層的nginx不重寫請求頭中的host字段,將會導(dǎo)致請求失敗【默認(rèn)反向代理服務(wù)器會向后端真實(shí)服務(wù)器發(fā)送請求,并且請求頭中的host字段應(yīng)為proxy_pass指令設(shè)置的服務(wù) 器】。同理,X_Forward_For字段表示該條http請求是有誰發(fā)起的?如果反向代理服務(wù)器不重寫該請求頭的話,那么后端真實(shí)服務(wù)器在處理時會認(rèn)為所有的請求都來在反向代理服務(wù)器,如果后端有防攻擊策略的話,那么機(jī)器就被封掉了。因此,在配置用作反向代理的nginx中一般會增加兩條配置,修改http的請求頭:這里的$http_host和$remote_addr都是nginx的導(dǎo)出變量,可以再配置文件中直接使用。如果Host請求頭部沒有出現(xiàn)在請求頭中,則$http_host值為空,但是$host值為主域名。因此,一般而言,會用$host代替$http_host變量,從而避免http請求中丟失Host頭部的情況下Host不被重寫的失誤。X-Forwarded-For:簡稱XFF頭,它代表客戶端,也就是HTTP的請求端真實(shí)的IP,只有在通過了HTTP 代理或者負(fù)載均衡服務(wù)器時才會添加該項(xiàng)。 它不是RFC中定義的標(biāo)準(zhǔn)請求頭信息,在squid緩存代理服務(wù)器開發(fā)文檔中可以找到該項(xiàng)的詳細(xì)介紹。標(biāo)準(zhǔn)格式如下:X-Forwarded-For: client1, proxy1, proxy2。
這里做簡短的proxy_set_header 及其值的說明,具體詳細(xì)介紹可以參考這篇文章(寫的非常好):
https://blog.csdn.net/yujia_666/article/details/109391066
還有就是涉及到跨域問題的配置,我這塊處理的不好,也可以寫成這樣因?yàn)?/p>
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.
僅當(dāng)當(dāng)前層級中沒有add_header指令才會繼承父級設(shè)置。
最后你需要重新監(jiān)聽一下原有的https的端口,如果輸入的是http的端口,讓他重新跳轉(zhuǎn)到https
listen http的端口;
server_name 跳轉(zhuǎn)的服務(wù)路徑;
location / {
rewrite ^(.*) https://$server_name:12000$1 permanent;
}
強(qiáng)制跳轉(zhuǎn)的方法有很多種:這是其中一種,具體如下:
方法一 (這是最古老的寫法,不推薦)
rewrite ^(.*)$ https://$host$1 permanent;
方法二 (比較推薦)
return 301 https://$server_name$request_uri;
方法三 如果你有多個域名綁定在一起,可以只設(shè)定某些域名強(qiáng)制跳轉(zhuǎn)
if ($host = “1.dyseo.com.cn”) {
rewrite ^/(.*)$ https://1.dyseo.com.cn permanent;
}
方法四
方法四跟之前的都不一樣,我們不需要另外監(jiān)聽 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匹配后面的內(nèi)容會在alias指定的目錄下查找,即alias+匹配到path路徑后面的部分。
例:
location /www/ {
root /home/data;
}
訪問路徑:http://www.abc.com/www/a.html,實(shí)際上是訪問/home/data/www/a.html。
location /www/ {
alias /home/data;
}
訪問路徑:http://www.abc.com/www/a.html,實(shí)際上是訪問/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之間沒有斜杠。
總結(jié):
path有無斜杠無影響,主要看proxy_pass有沒有斜杠。proxy_pass沒有的話,proxy_pass+path;有的話(包括端口和上下文都是一樣的),proxy_pass+匹配到path路徑后面的部分。
如果有什么疑問或者鏈接失效的問題,隨時可以留言聯(lián)系,鏈接內(nèi)容都是親自測試和使用的,我掛上其他鏈接是因?yàn)榈谝皇怯X得人家寫得好,更深入,想分享給大家。第二:我比較懶,我學(xué)到了,但是不想寫出來了。
參考鏈接:
https://www.zhzz.org/asp/1055
https://blog.csdn.net/lizzehqs/article/details/123661065
https://blog.csdn.net/goldenfish1919/article/details/126629250

浙公網(wǎng)安備 33010602011771號