前面咱們聊了下了Nginx做爲WEB服務器對客戶端請求相關配置,文件操做優化、Nginx訪問控制、basic驗證,、狀態模塊狀態頁、gzip壓縮配置;回顧請參考http://www.javashuo.com/article/p-cxaceool-cy.html;今天咱們來聊一聊日誌模塊、ssl模塊、rewrite模塊;html
1、ngx_http_log_module:此模塊做用是指定nginx的訪問日誌格式;前端
log_format name [escape=default|json|none] string ...;此指令就是用來定義ngxin訪問日誌的格式,其中escape這個參數容許設置在變量中轉義的json或默認字符,默認狀況下使用默認轉義,none表示禁止轉義。string可使用nginx核心模塊及其它模塊內嵌的變量;注意這個指令只用於http配置段中,用於定義日誌格式,後面對全部虛擬主機均可以在定義日誌文件時能夠調用定義的日誌格式;linux
access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];指定日誌文件路徑,其中buffer=size表示指定日誌緩衝區大小,gzip=level表示指定日誌壓縮級別,fulsh=time表示指定日誌每隔多久就把緩衝區的日誌內容存到磁盤文件中去;nginx
示例:web
提示:以上配置表示定義一個日誌格式其名稱是 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指定驗正緩存中各緩存項是否爲活動項的時間間隔;shell
2、ngx_http_ssl_module:此模塊實現nginx基於https提供web服務json
ssl on | off;啓用或禁用ssl功能windows
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服務器搭建,以及證書申請相關原理說明請參考http://www.javashuo.com/article/p-eqvaoxip-bq.html,這裏說下過程,首先咱們要準備一臺CA(能夠是本機),而後在nginx服務器上生成證書申請文件,而後把該文件發送給CA服務器,而後CA服務器簽發證書申請文件生成對應的證書,而後CA把簽好的證書文件發給nginx服務器,而後nginx服務器拿到證書後在配置文件中配置使用證書便可,固然以上步驟也能夠直接在CA上作,最後把生成的私鑰文件和證書發送給nginx服務器,過程入下;
一、搭建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私鑰
二、生成自簽名證書
[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就準備好了
三、準備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 qiuhom@192.168.0.99:/tmp/ qiuhom@192.168.0.99's password: nginx.csr 100% 1009 225.4KB/s 00:00 [root@www ssl]#
提示:若是SSH沒有工做在標準端口,用scp命令時須要用-P(大寫)指定ssh端口
四、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. root@192.168.0.30'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服務器搭建過程;
3、ngx_http_rewrite_module:此模塊用於使用PCRE正則表達式查找匹配用戶請求的URI,返回重定向和有條件地選擇配置來更改請求URI。本質上就是查找替換的過程,用戶請求的url經過正則匹配,而後用其餘url或uri進行替換,隨後把新的url或uri返回給客戶端,由客戶端從新對新的URL或URI發送請求;
一、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發起新的請求,以下
二、return:中止處理並將指定的響應碼或URL返回給客戶端
return code [text];表示返回狀態碼或簡短緣由短語
return code URL;返回狀態碼和url
return URL;返回url
三、rewrite_log on | off;是否開啓重寫日誌
四、if(condition) {……};引入一個新的配置上下文;條件知足時執行配置塊中的配置指令;可用在server和location配置段中;這裏的條件能夠是變量,若是變量是字符串,非空爲真,空爲假;若是變量是數字則非0爲真,0爲假;固然條件也能夠是一個比較表達式,所謂表達式就是由操做符鏈接起來的式子,經常使用的操做符有比較操做符,文件及目錄存在性判斷;比較操做符有:== 、!= 、~表示模式匹配,區分字符大小寫;~*表示模式匹配,不區分字符大小寫;!~表示模式不匹配,區分字符大小寫;!~*表示模式不匹配,不區分字符大小寫;文件及目錄存在性判斷的有 -e,!-e、-f,!-f、-d,!-d,、-x,!-x,這裏的文件或目錄存在性判斷同shell裏面的文件或目錄存在性判斷是同樣的;
五、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來指定;