前言
上次分享了一些開發過程中常用的功能,但如果到真實環境中,其實還需要一些額外的配置,比如說跨域、快取、配置SSL證照、高可用等,老規矩,還是挑幾個平時比較常用的進行演示分享。上篇詳見Nginx超詳細常用功能演示,夠用啦~~~。
正文
1. 跨域
跨域是因為瀏覽器同源策略的保護,不能直接執行或請求其他站點的指令碼和資料;一般我們認為的同源就是指協議、域名、埠都相同,否則就不是同源。
現在前後端分離開發已經很普遍了,跨域問題肯定少不了,但解決的方式也很多,比如JsonP、後端新增相關請求頭等;很多時候,不想改動程式碼,如果用到nginx做代理伺服器,那就可以輕鬆配置解決跨域問題。
1.1 環境準備
需要準備兩個專案,一個前端專案釋出在80埠上,一個API專案釋出在5000埠上,這裡需要在阿里雲的安全組中將這兩個埠開放;
-
API專案環境(對外是5000埠)
API介面還是使用上次演示的專案,很簡單,過程我就不再重複上圖啦,直接來兩張重要的;
配置nginx反向代理,然後執行看效果:
-
前端環境(對外是80埠)
前端頁面(kuayu.html)
<!DOCTYPE html> <html> <head> <title>跨域測試</title> <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script> <script type="text/javascript"> $(document).ready(function(){ // 點選按鈕 請求資料, $("#b01").click(function(){ // 請求資料 htmlobj=$.ajax({url:"http://47.113.204.41:5000/weatherforecast/getport",async:false}); // 將請求的資料顯示在div中 $("#myDiv").html(htmlobj.responseText); }); }); </script> </head> <body> <h2>獲取結果</h2> <div id="myDiv">結果顯示</div> <button id="b01" type="button">GetPort</button> </body> </html>
將kuayu.html通過xFtp拷貝到伺服器上,對應的static目錄是自己建立的,如下圖:
-
nginx配置及執行測試
配置nginx,在原有配置檔案中再新增一個server塊,如下配置:
執行測試:
跨域問題出現了,現在前後端都不想改程式碼,要幹架嗎?nginx說:和諧,一定要和諧~~~
1.2 配置跨域及執行
在API的server中進行跨域配置,如下:
重啟nginx之後,再測試,看看搞定了沒?
2. 配置SSL證照
現在的站點幾乎都是https了,所以這個功能必須要實操一把;為了更符合真實線上場景,我特意準備了域名和證照,真真實實在阿里雲伺服器上演示; 這裡需要登入到阿里雲上購買域名,然後根據域名申請免費的SSL證照,最後進行配置使用,詳情如下:
2.1 準備域名
這裡我註冊了一個域名為:codezyq.cn;下面先說說註冊域名的流程:
-
登入阿里雲,找到域名註冊入口
-
進入到一個頁面,然後輸入需要註冊的域名
-
然後就出現搜尋結果,如果被註冊就會提示,可以選擇其他型別或更換域名
-
買了域名之後,需要進行實名認證,個人上傳身份證就完事啦,一會就實名完成; 完成之後就需要配置域名解析,即解析到自己的雲伺服器上,後續通過域名才可以訪問;
-
測試是否能解析成功,直接在自己電腦上ping一下域名,看看是否解析到指定IP即可,簡單直接;這樣域名就可以用啦~~~
2.2 準備證照
免費證照這塊的申請需要用到買的域名,大概步驟如下:
-
領取免費證照數量(20個)
-
進入SSL證照(應用安全頁面)進行證照建立
-
進行證照申請,即繫結域名
填寫申請資訊,如下:
這裡一般填完申請資訊,後續驗證那塊直接過也能簽發,列表狀態如下:
-
簽發完成之後,下載對應伺服器的證照即可,點選下載選擇
直接下載下來一會配置使用。
2.3 nginx配置證照
-
檢查環境
檢查埠是否可訪問
https需要443埠,所以在阿里雲中將443埠加入到安全組中,如下圖:
另外還需要檢視雲伺服器的防火牆有沒有開放對應的埠,如下命令:
# 檢視防火牆埠開放情況 firewall-cmd --list-all public target: default icmp-block-inversion: no interfaces: sources: services: dhcpv6-client ssh # 顯示的結果沒有開放443埠 ports: 80/tcp 22/tcp 5000/tcp 3306/tcp 6379/tcp # 將443埠加入到裡面 firewall-cmd --zone=public --add-port=443/tcp --permanent # 重新載入 firewall-cmd --reload # 再看防火牆埠開放情況 firewall-cmd --list-all public target: default icmp-block-inversion: no interfaces: sources: services: dhcpv6-client ssh # 443埠加入進來了 ports: 80/tcp 22/tcp 5000/tcp 3306/tcp 6379/tcp 8080/tcp 443/tcp
檢查nginx中是否包含http_ssl_module模組
在配置證照之前需要檢查一下nginx中是否已經包含http_ssl_module:
如果沒有就算配置了也不能用,如下:
-
為nginx加上http_ssl_module
需要下載一個原始碼進行引入,這裡還是使用版本1.18.0,具體步驟如下:
第一步,先準備環境,比如支援編譯、openssl等,執行以下命令:
# 安裝對應的包 yum -y install gcc openssl openssl-devel pcre-devel zlib zlib-devel
第二步,下載對應版本原始碼到usr/local/src中,並進行解壓,執行以下命令
# 下載指定版本nginx包 wget http://nginx.org/download/nginx-1.18.0.tar.gz # 解壓 tar -zxvf nginx-1.18.0.tar.gz
第三步,進入解壓目錄中,配置http_ssl_module,命令如下:
# 進入解壓目錄 cd nginx-1.18.0 # 加入http_ssl_module ./configure --prefix=/usr/local/nginx --with-http_ssl_module
第四步,編譯,在解壓目錄中直接執行make命令即可
# 執行make命令,在當前目錄就會新增新目錄objs make # 如果是新安裝nginx,執行以下命令 # make&make install
如果沒報錯,就編譯出最新的啦; 這裡我在實操的時候,先執行的./configure 配置命令,然後再執行第一步的命令,所以導致make的時候老是不成功,這裡解決方案是在新增http_ssl_module模組時,同時指定了openssl原始碼路徑(直接下載即可),然後再執行make命令就成功了。命令如下:
# 指定openssl原始碼路徑 需要下載 ./configure --prefix=/usr/local/nginx --with-openssl=/usr/src/openssl-1.1.1d --with-http_ssl_module # 再執行make命令編譯 make
第五步,將編譯出來新的nginx檔案替換原有的nginx檔案,操作如下:
-
在nginx配置SSL的支援
還記得獲取下載證照的時候嗎,下載介面那有一個幫助操作,點選就有nginx配置SSL證照的詳細步驟,如下圖:
這裡演示配置的內容如下(新增一個server塊,專門配置SSL的):
server { # https 監聽的是443埠 listen 443 ssl; # 指定準備好的域名 server_name codezyq.cn; # 指定證照路徑,這裡需要把準備好的證照放到此目錄 ssl_certificate /usr/local/nginx/myssl/codezyq.cn.pem; ssl_certificate_key /usr/local/nginx/myssl/codezyq.cn.key; ssl_session_cache shared:SSL:1m; # 超時時間 ssl_session_timeout 5m; # 表示使用的加密套件的型別 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; # 表示使用的TLS協議的型別 ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; location /www/ { root static; index index.html index.htm; } }
-
重啟nginx,然後進行https訪問對應的連線就可以啦
注:網站如果沒有備案,會被攔截,會導致不能訪問,正規站點都是要備案的。
3. 防盜鏈配置
盜鏈通俗一點的理解就是別人的網站使用自己伺服器的資源,比如常見的在一個網站引入其他站點伺服器的圖片等資源,這樣被盜鏈的伺服器頻寬等資源就會額外被消耗,在一定程度上會損害被盜鏈方的利益,所以防盜鏈是必要的;這裡通過nginx簡單實現靜態資源防盜鏈的案例,原理很簡單,就是判斷一下請求源是否被允許。
3.1 準備一個html和圖片
將準備的html和圖片放在建立的static目錄下,如下圖:
anti-stealing-link.html內容如下
<!DOCTYPE html>
<html>
<head>
<title>anti-stealing-link test</title>
</head>
<body>
<h2>使用雲伺服器上的圖片</h2>
<!-- 訪問伺服器圖片 -->
<img src="http://47.113.204.41/img/test.jpg" alt="">
</body>
</html>
3.2 正常配置nginx
server {
listen 80;
server_name 47.113.204.41;
# 針對html訪問的匹配規則
location /www/ {
root static;
index index.html index.htm;
}
# 針對圖片訪問的匹配規則
location /img/ {
root static;
}
charset utf-8;
}
執行起來看效果:
現在有個需求,只能是雲伺服器的html才能使用圖片,其他引用源都認為是盜鏈,直接返回403或重寫到固定圖片。
3.3 輕鬆配置nginx防盜鏈
針對img配置如下:
server {
listen 80;
server_name 47.113.204.41;
# 針對html訪問的匹配規則
location /www/ {
root static;
index index.html index.htm;
}
# 針對圖片訪問的匹配規則
location /img/ {
root static;
#對源站點的驗證,驗證IP是否是47.113.204.41
#可以輸入域名,多個空格隔開
valid_referers 47.113.204.41;
#非法引入會進入下方判斷
if ($invalid_referer) {
#這裡返回403,也可以rewrite到其他圖片
return 403;
}
}
charset utf-8;
}
重啟nginx,清除快取再試:
防盜鏈是不是很簡單,也可以通過程式碼的形式,比如在過濾器或管道中也可以實現,如果沒有特殊需求,nginx稍微一配置就能實現,豈不美哉~~~
4. 隱藏版本資訊
之前在專案中做滲透測試時,其中有一項問題就是不希望在響應頭中體現伺服器相關版本,避免在某些版本出現漏洞時,攻擊者可以特意針對此版本進行惡意攻擊,從而影響系統服務可用性。
現有情況:
頁面找不到時:
看看nginx是如何關閉,如下配置:
看效果:
正常訪問
找不到報錯,版本也沒有啦
5. 高可用配置
儘管nginx效能再強,但伺服器和網路有很多因素是不可控的,如:網路抖動、網路不通、伺服器當機等情況,都會導致服務不可用(可理解為單點故障),這樣的系統體驗肯定得不到好評;如果當一個伺服器當機或服務掛掉時,另外一臺伺服器自動代替當機伺服器提供服務,保證系統的正常執行,這就實現了高可用;這裡nginx實現高可用的方式和Redis的主從模式很相似,只是nginx使用的是keepalived來實現高可用叢集。
5.1 keepalived簡介
keepalived實現高可用的關鍵思路還是主、備節點的來回切換;
- 首先需要配置一個VIP(虛擬IP),用於提供訪問的介面地址,剛開始是在主節點上的;
- 當主節點發生故障時,VIP就漂移到備節點,由備節點提供服務;
- 如果主節點恢復,會通知備節點健康狀態,VIP就會漂移到主節點;
由上可見,在keepalive實現高可用時,肯定要有機制選擇主備節點,主備之間肯定要互相通知,不然咋知道節點之間的健康狀態,所以就使用了VRRP協議,目的就是為了解決靜態路由的單點故障。
VRRP協議,全稱Virtual Router Redundancy Protocol(虛擬路由冗餘協議),利用IP多播的方式實現通訊;通過競選協議機制(根據配置的優先順序來競選)來將路由任務交給某臺VRRP路由器,保證服務的連續性;
理論先了解這麼多,先來把keepalived安裝上,
方式一
執行以下命令可直接安裝:
# 安裝,這種直接安裝完成了,修改配置檔案啟動即可
yum install-y keepalived
# 啟動
systemctl start keepalived.service
這種方式可能會遇到啟動keepalived的時候報錯,原因可能是服務配置檔案(/usr/lib/systemd/system/keepalived.service)指定的keepalived相關目錄找不到; 如果檔案目錄都正常,還報錯,我折騰了好久,後來用原始碼方式進行安裝就正常啦~~~
方式二
建議使用原始碼的形式進行安裝,大概步驟如下:
第一步,環境準備
# 安裝對應的依賴包
yum -y install gcc openssl openssl-devel pcre-devel zlib zlib-devel
第二步,下載並解壓原始碼包
# 在/usr/local/src目錄下執行,下載到該目錄
wget https://www.keepalived.org/software/keepalived-2.0.18.tar.gz
# 解壓
tar -zxvf keepalived-2.0.18.tar.gz
第三步,安裝
# 進入到解壓出來的目錄
cd keepalived-2.0.18
# 編譯並安裝
./configure && make && make install
第四步,建立啟動檔案,即將編譯出來的檔案拷貝到對應的目錄下
cp -a /usr/local/etc/keepalived /etc/init.d/
cp -a /usr/local/etc/sysconfig/keepalived /etc/sysconfig/
cp -a /usr/local/sbin/keepalived /usr/sbin/
第五步,建立配置檔案
# 先建立配置檔案存放的目錄
mkdir /etc/keepalived
# 再將建立好的配置檔案通過xFtp傳到此目錄,也可以直接在這裡建立
配置檔名為keepalived.conf,內容如下:
! Configuration File for keepalived
global_defs {
# 每臺機器的唯一標識
router_id 31
}
# vrrp例項,可以配置多個
vrrp_instance VI_1 {
# 標識為主節點,如果是被節點,就為BACKUP
state MASTER
# 網路卡名稱,通過ip addr 命令可以看到對應網路卡,需要哪個就配置哪個就行
interface enp0s8
# 路由ID,主、備節點的id要一樣
virtual_router_id 3
# 優先順序,主節點的優先順序要大於備節點的優先順序
priority 200
# 主備心跳檢測,間隔時間為1s
advert_int 1
# 認證方式,主備節點要一致
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
# 虛擬IP
192.168.30.108
}
}
第六步,啟動
# 啟動
systemctl start keepalived.service
# 檢視虛擬IP情況
ip addr
檢視效果如下,虛擬ip正常在master節點上:
安裝完keepalived和nginx之後就可以進行主備演示啦~~~
5.2 主備演示
這裡用了兩臺虛擬機器,結構如下:
-
第一步nginx配置準備
這裡用到的就是nginx預設配置,基本沒咋改,如果要了解配置檔案詳情,點選(Nginx超詳細常用功能演示,夠用啦~~~)有詳細說明。兩臺虛擬機器配置的nginx.conf內容如下:
#user nobody; worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; #gzip on; server { # 需要防火牆開放80埠 listen 80; server_name localhost; location / { root html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
-
第二步準備html
兩臺虛擬機器中html,用的是nginx預設的index.html(路徑:/usr/local/nginx/html),為了方便演示,在index.html中增加了個105和106的顯示標註,105機器內容如下,106機器上的html只是把內容中的105改成106即可:
-
第三步準備兩臺虛擬機器上keepalived配置檔案(路徑:/etc/keepalived)
105機器上keepalived.conf內容如下:
! Configuration File for keepalived global_defs { # 每臺機器不一樣 router_id 31 } #檢測nginx服務是否在執行 vrrp_script chk_nginx { #使用指令碼檢測 script "/usr/local/src/chk_nginx.sh" #指令碼執行間隔,每2s檢測一次 interval 2 #指令碼結果導致的優先順序變更,檢測失敗(指令碼返回非0)則優先順序 -5 weight -5 #連續2次檢測失敗才確定是真失敗 fall 2 #檢測到1次成功就算成功 rise 1 } vrrp_instance VI_1 { # vrrp例項,可以配置多個 state MASTER # 網路卡名稱,通過ip addr 命令可以看到對應網路卡,需要哪個就配置哪個就行 interface enp0s8 # 路由ID,主、備節點的id要一樣 virtual_router_id 3 # 優先順序,主節點的優先順序要大於備節點的優先順序 priority 200 # 主備心跳檢測,間隔時間為1s advert_int 1 # 認證方式,主備節點要一致 authentication { auth_type PASS auth_pass 123456 } #執行監控的服務。 track_script { #引用VRRP指令碼,即在 vrrp_script 部分指定的名字。 chk_nginx } virtual_ipaddress { # 虛擬IP 192.168.30.108 } }
在/usr/local/src/中準備chk_nginx.sh,keepalived和nginx沒有直接關係的,只有通過檢查nginx的執行狀態來進行高可用服務切換,chk_nginx.sh內容如下:
然後給這個檔案增加執行許可權,命令如下:
chmod +x chk_nginx.sh
106虛擬機器上的步驟和檢測指令碼chk_nginx.sh都一樣,只是keepalived.conf內容稍微有點變動。
106機器上keepalived.conf內容如下:
! Configuration File for keepalived global_defs { # 每臺機器上不一樣 router_id 32 } #檢測nginx服務是否在執行 vrrp_script chk_nginx { #使用指令碼檢測 script "/usr/local/src/chk_nginx.sh" #指令碼執行間隔,每2s檢測一次 interval 2 #指令碼結果導致的優先順序變更,檢測失敗(指令碼返回非0)則優先順序 -5 weight -5 #連續2次檢測失敗才確定是真失敗 fall 2 #檢測到1次成功就算成功 rise 1 } vrrp_instance VI_1 { # 配置為備節點 state BACKUP # ip addr 檢視對應的網路卡名稱 interface enp0s8 virtual_router_id 3 # 優先順序比主節點低 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 123456 } #執行監控的服務 track_script { #引用VRRP指令碼,即在 vrrp_script 部分指定的名字。 chk_nginx } virtual_ipaddress { # 虛擬IP 192.168.30.108 } }
-
第四步分別啟動兩臺虛擬機器上的nginx和keepalived,命令如下:
# 啟動nginx cd /usr/local/nginx/sbin/ ./nginx # 啟動keepalived systemctl start keepalived.service # 檢視keepalived狀態,是否執行 systemctl status keepalived.service
兩臺虛擬機器都要執行
-
第五步測試,效果如下:
直接訪問虛擬IP就能訪問到主節點的服務啦;現在測試當主節點掛掉時,還會不會正常訪問服務,在105機器上執行如下命令:
# 模擬當機,停止keepalived systemctl stop keepalived.service # ip addr 檢視虛擬IP已經漂移到備節點上了,在備節點用ip addr 檢視
備節點顯示,虛擬IP已經漂移過來啦~
再用虛擬IP訪問,效果如下:
看見已經切換到106機器上提供服務啦,這樣就實現高可用啦;
那主節點重新恢復,虛擬IP會不會恢復回來繼續提供服務呢?
# 重啟keepalived systemctl restart keepalived.service #ip addr 檢視虛擬IP情況,恢復過來啦
繼續用虛擬IP訪問服務,又回到主服務啦,如果沒有,那可能是瀏覽器快取,因為這裡用靜態html演示,清掉快取再訪問。
5.3 多主多備演示
對於上面的主備模式,只有主節點提供服務,如果主節點不發生故障,備節點伺服器就有點資源浪費啦,這個時候多主多備不僅能合理利用資源,還得提供備用服務(根據實際需要配置),形成真正叢集提供服務。
這裡就演示一下雙主雙備的配置,思路就是在keepalived增加多個vrrp例項,105機器在vrrp例項VI_1中作為主節點,106機器作為備節點,在vrrp例項VI_2中,105機器作為備節點,106機器作為主節點,這樣就形成了互為主備的模式,資源就能很好的利用啦;其他邏輯不變,只是分別在105、106機器上加上的keepalived.conf中加上VI_2例項即可,如下:
105機器上keepalived.conf內容如下:
global_defs {
router_id 31
}
#檢測nginx服務是否在執行
vrrp_script chk_nginx {
#使用指令碼檢測
script "/usr/local/src/chk_nginx.sh"
#指令碼執行間隔,每2s檢測一次
interval 2
#指令碼結果導致的優先順序變更,檢測失敗(指令碼返回非0)則優先順序 -5
weight -5
#連續2次檢測失敗才確定是真失敗
fall 2
#檢測到1次成功就算成功
rise 1
}
vrrp_instance VI_1 {
state MASTER
interface enp0s8
virtual_router_id 3
priority 200
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
track_script {
chk_nginx
}
virtual_ipaddress {
192.168.30.108
}
}
vrrp_instance VI_2 {
# VI_1是MASTER,這裡就是備節點
state BACKUP
interface enp0s8
# 修改路由編號
virtual_router_id 5
# 備節點優先順序稍低
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
track_script {
chk_nginx
}
virtual_ipaddress {
# 虛擬IP
192.168.30.109
}
}
106機器上keepalived.conf內容如下:
global_defs {
router_id 32
}
#檢測nginx服務是否在執行
vrrp_script chk_nginx {
#使用指令碼檢測
script "/usr/local/src/chk_nginx.sh"
#指令碼執行間隔,每2s檢測一次
interval 2
#指令碼結果導致的優先順序變更,檢測失敗(指令碼返回非0)則優先順序 -5
weight -5
#連續2次檢測失敗才確定是真失敗
fall 2
#檢測到1次成功就算成功
rise 1
}
vrrp_instance VI_1 {
state BACKUP
interface enp0s8
virtual_router_id 3
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
track_script {
chk_nginx
}
virtual_ipaddress {
192.168.30.108
}
}
vrrp_instance VI_2 {
# 這裡是主節點
state MASTER
interface enp0s8
# 這裡和105機器上的VI_2中id一致
virtual_router_id 5
priority 200
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
track_script {
chk_nginx
}
virtual_ipaddress {
# 虛擬IP
192.168.30.109
}
}
分別重啟兩臺機器上的keepalived,執行命令如下:
然後分別訪問虛擬ip 192.168.30.108 和192.168.30.109,都能提供對應的服務啦,這裡不截圖了。
總結
開發和生產環境比較常用的功能大概就這麼多,後續如果用得多的功能會及時和小夥伴分享哦。
這次主要遇見一些問題,小夥伴可以作為參考,彙總如下:
-
VMware虛擬機器網路問題,主機ping不通虛擬機器、虛擬機器ping不通主機、上不了外網
這個問題折騰了兩個晚上,原因是之前的網路配置有一些問題,然後重新裝了虛擬機器,但是用單網路卡的方式依然沒有同時解決上面的問題,最後使用兩個網路卡的方式解決了; 一個網路卡使用動態分配,另外一個使用靜態IP,資訊如下:
-
keepalived啟動不起來
使用yum直接安裝的方式,可能會遇到啟動不起來的情況,排查了服務裡面配置路徑,目錄都對,依賴包也裝了還不行;最後使用原始碼方式安裝沒問題。
-
keepalived的虛擬ip主機ping不通
這也是個棘手的問題,虛擬ip能在主、備機器之間正常漂移,就是主機ping不同虛擬IP,當前解決的措施主要步驟,如下:
首先註釋掉keepalived.conf 中vrrp_strict ,然後重啟keepalived;
如果還不行,就排查防火牆;
再不行,就清arp快取
一個被程式搞醜的帥小夥,關注"Code綜藝圈",跟我一起學~~~