1. 程式人生 > >Nginx之常用基本配置(三)

Nginx之常用基本配置(三)

  前面我們聊了下了Nginx作為WEB伺服器對客戶端請求相關配置,檔案操作優化、Nginx訪問控制、basic驗證,、狀態模組狀態頁、gzip壓縮配置;回顧請參考https://www.cnblogs.com/qiuhom-1874/p/12381331.html;今天我們來聊一聊日誌模組、ssl模組、rewrite模組;

  一、ngx_http_log_module:此模組作用是指定nginx的訪問日誌格式;

    log_format name [escape=default|json|none] string ...;此指令就是用來定義ngxin訪問日誌的格式,其中escape這個引數允許設定在變數中轉義的json或預設字元,預設情況下使用預設轉義,none表示禁止轉義。string可以使用nginx核心模組及其它模組內嵌的變數;注意這個指令只用於http配置段中,用於定義日誌格式,後面對所有虛擬主機都可以在定義日誌檔案時可以呼叫定義的日誌格式;

    access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];指定日誌檔案路徑,其中buffer=size表示指定日誌緩衝區大小,gzip=level表示指定日誌壓縮級別,fulsh=time表示指定日誌每隔多久就把緩衝區的日誌內容存到磁碟檔案中去;

  示例:

   提示:以上配置表示定義一個日誌格式其名稱是 main ,後面用單引號引起來的部分就是日誌格式內容,其中$remote_addr表示客戶端ip這個值不一定是客戶端ip,這個要看應用環境,如果nginx伺服器前面有代理伺服器,這個變數就會記錄前端代理的ip,如果nginx是直接面向客戶端,那麼這個值就是記錄客戶端ip,具體它記錄那個ip 這個要看應用環境;$remote_user表示遠端使用者,如果我們配置的網站有驗證的話,這個值就是記錄的是用於驗證的使用者名稱,如果沒有則預設就是“-”;$time_local表示本地伺服器時間;$request表示客戶端使用的方法請求資源路徑,以及http協議版本;$status這個變數記錄客戶端請求伺服器資源時的響應狀態碼;$body_bytes_sent這個變數記錄客戶端訪問伺服器時響應體的位元組數,這個位元組數不包含響應頭部;$http_referer此變數記錄客戶端的referer資訊;referer是http頭部的一部分,通常情況下客戶端瀏覽器訪問web伺服器時,都會把這個referer資訊帶上,目的是告訴伺服器本次請求是從那個頁面連結過來的;$http_user_agent此變數記錄客戶端的User_Agent資訊,User_Agent也是http頭部的一部分,客戶端訪問web伺服器時會帶上這個資訊,目的就是告訴伺服器客戶端的作業系統型別,版本,瀏覽器資訊等;$http_x_forwarded_for這個變數用於記錄客戶端真實IP,如果客戶端是通過代理訪問本伺服器,那麼這個值不是記錄代理客戶端的IP,而是客戶端真實IP資訊;更多內建變數可參考http://nginx.org/en/docs/http/ngx_http_core_module.html#variables

  定義好上面的日誌格式,我們可以通過access_log 來指定存放日誌的檔案路徑並明確指定用我們定義的日誌格式“main”,當我們瀏覽器訪問web伺服器時,服務端就會以我們定義的格式記錄日誌,如下所示

     open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];指定快取各日誌檔案相關的元資料資訊;其中max=N表示快取的最大檔案描述符數量,如果滿了就用LRU演算法清理快取;inactive=time表示指定非活動時長,預設情況下,10秒;min_user=N表示在inactive指定的時長內訪問大於等於此值方可被當作活動項;;vaild=time指定驗正快取中各快取項是否為活動項的時間間隔;

  二、ngx_http_ssl_module:此模組實現nginx基於https提供web服務

    ssl on | off;啟用或禁用ssl功能

    ssl_certificate file;設定當前虛擬主機的證書

    ssl_certificate_key file;設定當前虛擬主機證書私鑰檔案

    ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];支援ssl協議版本,預設為後三個;

    ssl_session_cache off | none | [builtin[:size]] [shared:name:size];其中builtin[:size]表示使用OpenSSL內建的快取,此快取為每worker程序私有;[shared:name:size]:表示在各worker之間使用一個共享的快取;

    ssl_session_timeout time;客戶端一側的連線可以複用ssl session cache中快取 的ssl引數的有效時長;

  示例:

    要讓nginx工作為https伺服器,首先我們要對其申請證書,有關CA伺服器搭建,以及證書申請相關原理說明請參考https://www.cnblogs.com/qiuhom-1874/p/12237944.html,這裡說下過程,首先我們要準備一臺CA(可以是本機),然後在nginx伺服器上生成證書申請檔案,然後把該檔案傳送給CA伺服器,然後CA伺服器簽發證書申請檔案生成對應的證書,然後CA把簽好的證書檔案發給nginx伺服器,然後nginx伺服器拿到證書後在配置檔案中配置使用證書即可,當然以上步驟也可以直接在CA上做,最後把生成的私鑰檔案和證書傳送給nginx伺服器,過程入下;

    1、搭建CA,其實很簡單,所謂CA就是生成一個自簽名證書即可

[root@test ~]# cd /etc/pki/CA/
[root@test CA]# tree
.
├── certs
├── crl
├── newcerts
└── private

4 directories, 0 files
[root@test CA]# (umask 077;openssl genrsa -out private/cakey.pem 2048)
Generating RSA private key, 2048 bit long modulus
...+++
...................+++
e is 65537 (0x10001)
[root@test CA]# tree
.
├── certs
├── crl
├── newcerts
└── private
    └── cakey.pem

4 directories, 1 file
[root@test CA]#

  提示:以上是生成CA私鑰

  2、生成自簽名證書

[root@test CA]# openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3650
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:SICHUAN
Locality Name (eg, city) [Default City]:GUANGYUAN
Organization Name (eg, company) [Default Company Ltd]:TEST
Organizational Unit Name (eg, section) []:DEVOPS
Common Name (eg, your name or your server's hostname) []:ca.ilinux.io
Email Address []:
[root@test CA]# touch index.txt
[root@test CA]# echo 01 >serial
[root@test CA]# tree
.
├── cacert.pem
├── certs
├── crl
├── index.txt
├── newcerts
├── private
│   └── cakey.pem
└── serial

4 directories, 4 files
[root@test CA]# 

  提示:到此CA就準備好了

  3、準備nginx伺服器證書私鑰和伺服器證書申請檔案

[root@www ~]# mkdir /etc/nginx/ssl
[root@www ~]# cd /etc/nginx/ssl
[root@www ssl]# ls
[root@www ssl]# (umask 077;openssl genrsa -out nginx.key 2048)
Generating RSA private key, 2048 bit long modulus
.........................................+++
.......+++
e is 65537 (0x10001)
[root@www ssl]# ll
total 4
-rw------- 1 root root 1679 Mar  2 23:06 nginx.key
[root@www ssl]# openssl req -new -key nginx.key -out nginx.csr 
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:SICHUAN
Locality Name (eg, city) [Default City]:GUANGYUAN
Organization Name (eg, company) [Default Company Ltd]:TEST
Organizational Unit Name (eg, section) []:DEVOPS
Common Name (eg, your name or your server's hostname) []:www.ilinux.io
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@www ssl]# ll
total 8
-rw-r--r-- 1 root root 1009 Mar  2 23:07 nginx.csr
-rw------- 1 root root 1679 Mar  2 23:06 nginx.key
[root@www ssl]#

  提示:到此nginx伺服器的證書申請檔案就做好了,我們只需要把這個申請檔案傳送給CA

[root@www ssl]# scp -P 41319 nginx.csr [email protected]:/tmp/
[email protected]'s password: 
nginx.csr                                                     100% 1009   225.4KB/s   00:00    
[root@www ssl]# 

  提示:如果SSH沒有工作在標準埠,用scp命令時需要用-P(大寫)指定ssh埠

  4、CA簽發nginx證書

[root@test CA]# openssl ca -in /tmp/nginx.csr -out certs/nginx.pem -days 365
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Mar  2 15:11:02 2020 GMT
            Not After : Mar  2 15:11:02 2021 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = SICHUAN
            organizationName          = TEST
            organizationalUnitName    = DEVOPS
            commonName                = www.ilinux.io
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                F7:76:62:31:04:D8:CE:0E:6E:CD:C5:14:05:EF:7F:E4:A5:AD:A0:91
            X509v3 Authority Key Identifier: 
                keyid:D5:61:A5:2F:BF:67:51:78:D7:5D:F8:51:F4:3C:FB:22:F9:E5:A7:3B

Certificate is to be certified until Mar  2 15:11:02 2021 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
[root@test CA]# tree
.
├── cacert.pem
├── certs
│   └── nginx.pem
├── crl
├── index.txt
├── index.txt.attr
├── index.txt.old
├── newcerts
│   └── 01.pem
├── private
│   └── cakey.pem
├── serial
└── serial.old

4 directories, 9 files
[root@test CA]# 

  提示:我們只需要把簽好的證書傳送給nginx伺服器即可

[root@test CA]# scp certs/nginx.pem 192.168.0.30:/etc/nginx/ssl/
The authenticity of host '192.168.0.30 (192.168.0.30)' can't be established.
ECDSA key fingerprint is SHA256:EG9nua4JJuUeofheXlgQeL9hX5H53JynOqf2vf53mII.
ECDSA key fingerprint is MD5:57:83:e6:46:2c:4b:bb:33:13:56:17:f7:fd:76:71:cc.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.0.30' (ECDSA) to the list of known hosts.
[email protected]'s password: 
nginx.pem                                                             100% 4464     2.1MB/s   00:00    
[root@test CA]# 

  提示:到此CA的工作就完成了,接下來我們直接在nginx伺服器上直接配置ngxin使用證書

[root@www conf.d]# cat login.conf 
server {
        listen 443 ssl;
        server_name 192.168.0.30;
        root /data/web/html;
        gzip on;
        gzip_types text/xml text/plain;
        gzip_disable Firefox;
        location /basic_status {
                stub_status;
                auth_basic "please input you username and passwd login";
                auth_basic_user_file /etc/nginx/conf.d/.ngxpasswd;
        }
        ssl_certificate "/etc/nginx/ssl/nginx.pem";
        ssl_certificate_key "/etc/nginx/ssl/nginx.key";
        ssl_protocols sslv2 sslv3 tlsv1 tlsv1.1 tlsv1.2;
        ssl_session_cache shared:SSL:10m;


}
[root@www conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@www conf.d]# nginx -s reload
[root@www conf.d]# 

  驗證:用瀏覽器訪問下看看我們配置的證書是否生效

   提示:出現這個介面上正常的,因為我們的CA是自己搭建的,瀏覽器預設不認識,我們可以把CA證書匯入瀏覽器就不會存在這個問題了,接下來我們把CA證書匯入瀏覽器吧

  提示:windows預設是通過後綴來識別檔案,所以把CA證書放到windows上後需要更改為.crt為字尾即可.

  匯入CA的證書後,我們再來用瀏覽器訪問下我們的網站是否還會提示不是私密連線呢?

 

  我們匯入CA證書後,我們重新開啟瀏覽器訪問網站,就沒有提示不是私密連線了,同時我們訪問我們網站也是基於https訪問,不再是http;以上就是nginx工作成https伺服器搭建過程;

   三、ngx_http_rewrite_module:此模組用於使用PCRE正則表示式查詢匹配使用者請求的URI,返回重定向和有條件地選擇配置來更改請求URI。本質上就是查詢替換的過程,使用者請求的url通過正則匹配,然後用其他url或uri進行替換,隨後把新的url或uri返回給客戶端,由客戶端重新對新的URL或URI傳送請求;

  1、rewrite regex replacement [flag]:將使用者請求的URI基於regex所描述的模式進行檢查,匹配到時將其替換為replacement指定的新的URI;注意:如果在同一級配置塊中存在多個rewrite規則,那麼會自上而下逐個檢查;被某條件規則替換完成後,會重新一輪的替換檢查,因此,隱含有迴圈機制;[flag]所表示的標誌位用於控制此迴圈機制;如果replacement是以http://或https://開頭,則替換結果會直接以重向返回給客戶端;其中flag有四種,last表示重寫完成後停止對當前URI在當前location中後續的其它重寫操作,而後對新的URI啟動新一輪重寫檢查;提前重啟新一輪迴圈; 這個也是預設行為,有點類似continue指令的意思,不退出迴圈,只是退出當次迴圈,提前進入下次迴圈;break表示重寫完成後停止對當前URI在當前location中後續的其它重寫操作,而後直接跳轉至重寫規則配置塊之後的其它配置;結束迴圈;這個我們可以理解為迴圈裡的break指令,直接跳出迴圈,進行下面的配置指令;redirect表示重寫完成後以臨時重定向方式直接返回重寫後生成的新URI給客戶端,由客戶端重新發起請求;不能以http://或https://開頭;permanent表示重寫完成後以永久重定向方式直接返回重寫後生成的新URI給客戶端,由客戶端重新發起請求;這四個值的區別是,前兩個瀏覽器上都看不到跳轉(使用者是看不到明確的跳轉),後兩者者看得到;

  示例:

rewrite /(.*)$ https://www.ilinux.io/basic_status;

  提示:以上配置表示客戶端訪問我們伺服器的任何uri都給重寫為https://www.ilinux.io/basic_status這個url

  提示:之所以能夠看到302的響應碼是因為我們在規則裡把使用者的rul重寫成https://www.ilinux.io/basic_status ,瀏覽器看到重寫後的URL是以https開頭的,它就會拿著這個url去請求新的URL,所以我們這裡可以看到302響應碼;

   提示:以上配置表示,使用者訪問.jpg結尾的URL時,我們都對它重寫為訪問/test/test.html

  提示:我們對使用者請求的url進行替換時,沒有用到http或https去替換時,我們在瀏覽器上是看不到後面瀏覽器重新對新的url發起請求的請求資訊,這是我們重寫規則預設使用了last,last和break如果都不以http或https去替換使用者的rul,在瀏覽器是看不到跳轉的響應碼,要想看到該過程我們可以在後面加redirect或者permanent,它倆的區別在於,一個是臨時重定向,響應碼是302,一個是永久重定向響應碼是301;如下

 rewrite /(.*)\.jpg  /test/ redirect;

  提示:我們只在上面的配置上在rewrite規則上加了一個redirect標記,加上它,瀏覽器就會對新的uri發起新的請求,如下

  2、return:停止處理並將指定的響應碼或URL返回給客戶端

    return code [text];表示返回狀態碼或簡短原因短語

    return code URL;返回狀態碼和url

    return URL;返回url

  3、rewrite_log on | off;是否開啟重寫日誌

  4、if(condition) {……};引入一個新的配置上下文;條件滿足時執行配置塊中的配置指令;可用在server和location配置段中;這裡的條件可以是變數,如果變數是字串,非空為真,空為假;如果變數是數字則非0為真,0為假;當然條件也可以是一個比較表示式,所謂表示式就是由操作符連線起來的式子,常用的操作符有比較操作符,檔案及目錄存在性判斷;比較操作符有:== 、!= 、~表示模式匹配,區分字元大小寫;~*表示模式匹配,不區分字元大小寫;!~表示模式不匹配,區分字元大小寫;!~*表示模式不匹配,不區分字元大小寫;檔案及目錄存在性判斷的有 -e,!-e、-f,!-f、-d,!-d,、-x,!-x,這裡的檔案或目錄存在性判斷同shell裡面的檔案或目錄存在性判斷是一樣的;

  5、set $variable value;設定使用者指定以變數;

  示例:

if ($http_user_agent ~ MSIE) {
    rewrite ^(.*)$ /msie/$1 break;
}

if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
    set $id $1;
}

if ($request_method = POST) {
    return 405;
}

if ($slow) {
    limit_rate 10k;
}

if ($invalid_referer) {
    return 403;
}

  提示:第一個if表示判斷使用者瀏覽器型別,如果匹配MSIE 則進行url重寫,重寫為/msie/$1 ,這裡的$1表示rewrite規則裡匹配到第一個括號裡的內容的引用,和sed命令裡的\1類似;第二個if表示判斷變數$http_cookie 裡的值是否匹配後面的正則表示式,如果匹配則設定$id變數的值為$1,這裡的$1表示正則表示式裡括號分組匹配到的內容;第三個if表示判斷使用者請求的方法是否是POST,如果是就返回405,意思就是不讓使用者用POST方法提交資料;第五個if表示判斷$slow是否為空,不為空就設定limit_rate 10k,意思就是如果$slow的值為真,則限制客戶端的響應;最後一個if表示判斷$invalid_referer 是否為空,為空表示沒有非法的referer,沒有非法referer就不做處理,如果有非法referer,即不為空,則返回403,這是一個防盜鏈的配置;通常我們要先定義合法的referer,然後再來判斷非法referer來實現防盜鏈(定義了合法的referer後相對的不在合法的referer列表裡就表示非法的referer);合法referer的定義可以用valid_referers來指