1. 調整參數隱藏nginx軟件版本號信息javascript
軟件的漏洞和版本有關,咱們應儘可能隱藏或消除web服務對訪問用戶顯示各種敏感信息(例如web軟件名稱及版本號等信息),這樣惡意的用戶就很難猜到他攻擊的服務器所用的是否有特定漏洞的軟件,或者是否有對應漏洞的某一特定版本,從而增強web服務的安全性。
要了解服務器使用的軟件版本號,對於linux客戶端php
[root@Poppy conf]# curl -i bbs.joker.com HTTP/1.1 200 OK Server: nginx/1.6.3 Date: Fri, 15 Jun 2018 02:18:23 GMT Content-Type: text/html Content-Length: 4 Last-Modified: Thu, 07 Jun 2018 10:06:23 GMT Connection: keep-alive ETag: "5b19039f-4" Accept-Ranges: bytes bbs 瀏覽器上訪問若是出現404的時候,會顯示軟件和版本號。
咱們來訪問下百度看看是否能夠隱藏版本css
[root@Poppy conf]# curl -i baidu.com HTTP/1.1 200 OK Date: Fri, 15 Jun 2018 02:23:35 GMT Server: Apache 軟件更改爲了apache,還隱藏了版本號 Last-Modified: Tue, 12 Jan 2010 13:48:00 GMT ETag: "51-47cf7e6ee8400" Accept-Ranges: bytes Content-Length: 81 Cache-Control: max-age=86400 Expires: Sat, 16 Jun 2018 02:23:35 GMT Connection: Keep-Alive Content-Type: text/html <html> <meta http-equiv="refresh" content="0;url=http://www.baidu.com/"> </html>
經過修改配置文件nginx.conf中的http標籤段內加入「server_tokens off」;參數html
[root@Poppy conf]# cat nginx.conf worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; # 訪問日誌,main就是讀http裏面的main日誌變量 access_log logs/www_access.log main; server_tokens off; include extra/bbs.conf; }
再來訪問看看java
[root@Poppy conf]# curl -i bbs.joker.com HTTP/1.1 200 OK Server: nginx Date: Fri, 15 Jun 2018 02:27:21 GMT Content-Type: text/html Content-Length: 4 Last-Modified: Thu, 07 Jun 2018 10:06:23 GMT Connection: keep-alive ETag: "5b19039f-4" Accept-Ranges: bytes bbs
語法格式爲node
server_tokens off; off 爲關閉 on爲開啓 (默認開啓安)
存放的位置能夠是http,server,location
2. 更改源碼隱藏nginx軟件名稱及版本號python
隱藏了nginx版本號後,更近一步,咱們能夠經過一些手段把web服務軟件的名稱也隱藏起來,或者更改成其餘web服務軟件名以迷惑黑客。因爲商業及品牌的展現緣由等,軟件提供商不但願使用者把軟件名字隱藏起來。所以,若是要修改軟件名稱就只能更改nginx源代碼
咱們不作修改mysql
3. 更改nginx服務默認用戶linux
爲了讓web服務更安全,要儘量的改掉軟件默認的全部配置,包括端口,用戶等
nginx服務的默認用戶是nobody,即便是註釋或者不配置默認用戶都是nobodynginx
[root@Poppy conf]# grep "#user" nginx.conf.default #user nobody;
#1 爲nginx服務創建新用戶的操做過程以下
useradd www -s /sbin/nologin -M
不須要有系統登陸權限,應當禁止其登陸行爲
#2 配置nginx服務,讓其使用剛創建的nginx用戶
第一種方法是直接修改配置文件,將默認的#user nobody改成 user nginx; 第二種方法是直接在編譯nginx軟件時指定編譯的用戶和組 ./configure --user=nginx --group=nginx 檢查更改用戶的效果 [root@Poppy conf]# ps -ef|grep nginx root 9032 1 0 Jun14 ? 00:00:00 nginx: master process /application/nginx/sbin/nginx www 10609 9032 0 10:27 ? 00:00:00 nginx: worker process 能夠看到worker process進程對應的用戶都變成了nginx。上述2種方法均可以設置nginx的worker進程運行的用戶,固然,nginx的主進程仍是以root身份運行的。
優化nginx服務的worker進程個數
在高併發,高訪問量的web服務場景,須要事先啓動好更多的nginx進程,以保證快速響應並處理大量併發用戶的請求
這相似於開飯店,在營業前,須要事先招聘必定數量的服務員準備接待顧客,但這裏就有個問題,若是飯店對客流沒有正確評估,就會致使一些問題發生,例如;服務員人數招聘多了,可是客流不多,那麼服務員就可能很閒,沒事幹,飯店的成本也就高了;若是客流很大,而服務員人數少了,可能就接待不過來顧客,致使顧客吃飯體驗差。所以,飯店要根據客戶的流量及併發量來調整接待的服務人員數量,而後根據監測顧客量變化及時調整到最佳的配置。
nginx服務就至關於飯店,網站用戶就至關於顧客,nginx的進程就至關於服務員
1. 優化nginx進程對應的配置
優化nginx的進程反應nginx服務的配置參數以下
worker_processes 1;指定了nginx要開啓的進程數,結尾的數字就是進程個數
調整的是nginx服務的worker進程數,nginx有master進程和worker進程之分,master是管理進程,worker是工做處理進程
2. 優化nginx進程個數的策略
如何設置worker_processes樹木,官方建議咱們起始爲cpu的核數,這樣起始提供服務時就不會出現由於訪問量快速增長而臨時啓動新進程提供服務的問題,縮短了系統的瞬間開銷和提供服務的時間,提高了服務用戶的速度。高流量高併發場合也能夠考慮將進程數提升至cpu核數具體狀況根據實際業務來選擇,由於這個參數除了要和cpu核數匹配外,也和硬盤存儲的數據及系統的負載有關。
3. 查看web服務器cpu硬件資源信息
[root@Poppy conf]# grep -c processor /proc/cpuinfo 1 一顆cpu一核 [root@Poppy conf]# grep 'physical id' /proc/cpuinfo|sort|uniq|wc -l 1 一顆cpu
4. 實踐修改nginx配置
服務器cpu顆數爲1顆,核數爲4核,則初始的配置可經過查看默認的nginx.conf裏的work_process瞭解,命令以下
[root@Poppy conf]# grep worker_processes nginx.conf worker_processes 1;
咱們修改將其修改成4,而後重啓nginx
[root@Poppy conf]# grep worker_processes nginx.conf worker_processes 4;
咱們經過ps -ef,來查看下nginx進程
[root@Poppy conf]# ps -ef|grep nginx root 9032 1 0 Jun14 ? 00:00:00 nginx: master process /application/nginx/sbin/nginx www 10862 9032 0 14:02 ? 00:00:00 nginx: worker process www 10863 9032 0 14:02 ? 00:00:00 nginx: worker process www 10864 9032 0 14:02 ? 00:00:00 nginx: worker process www 10865 9032 0 14:02 ? 00:00:00 nginx: worker process
可知,worker的進程數爲4個,ngxin master主進程不包含在這個參數內,nginx master的主進程爲管理進程,負責調度和管理worker進程。
默認狀況下,nginx的多個進程有可能跑在某一個cpu或cpu的某一核上,致使nginx進程使用硬件的資源不均,如何儘量地分配不一樣的nginx進程給不一樣的cou處理,達到充分有效利用硬件的多cpu多核資源的目的
四核cpu服務器參數配置參考
worker_processes 4; worker_cpu_affinity 0001 0010 0100 1000; worker_cpu_affinity就是配置nginx進程與cpu親和力的參數,即把不一樣的進程分給不一樣的cpu處理,這裏0001 0010 0100 1000是掩碼,分別表明第1,2,3,4核cpu,因爲worker_processes進程數位4,所以,上述配置會把每一個進程分配一核cpu處理,默認狀況下進程不會綁定人和cpu,參數位置爲main段
八核cpu服務器參數配置參考
worker_cpu_affinity 0001 0010 0100 1000 0001 0010 0100 1000
worker_cpu_affinity 00000001 00000002 00000003 00000004 00000005 00000006 00000007 00000008
其語法就是
worker_cpu_affinity cpumask; cpumask是掩嗎
worker_cpu_affinity的做用是綁定不一樣的worker進程數到一組cpu上
壓力測試 。webbench -c 2000 -t 180 http://www.joker.com/
nginx的連接處理機制在不一樣的操做系統會採用不一樣的i/o模型,在linux下,nginx使用epoll的i/o多路複用模型,具體配置以下
events{
events 指令是設定nginx的工做模式及鏈接數上限
user epoll;
use是一個事件模塊指令,用來指定nginx的工做模式。
}
nginx的工做模式
nginx的工做模式有select,poll,kqueue,epoll,rtsig和/dev/poll。其中select,poll都是標準的工做模式,kqueue和epoll是高效的工做模式,不一樣的是epoll用來linux平臺上,而kqueue用來bsd系統中。對於linux系統linux 2.6+的內核,推薦選擇epoll工做模式,這是高性能高併發的設置。
nginx官方文檔建議,咱們能夠不指定事件處理模型,nginx會自動選擇最佳的事件處理模型服務
調整nginx單個進程容許的客戶端最大鏈接數,這個控制鏈接數的參數爲worker_connections
worker_connections的值要根據具體服務器性能和程序的內存使用量來執行(一個進程啓動使用的內存根據程序肯定),以下
events{ events指令是設定nginx的工做模式及鏈接數上限 worker_connections 20480; worker_connections也是個事件模塊指令,用於定義nginx每一個進程的最大鏈接數,默認是1024。最大客戶端鏈接數由worker_processes和worker_connections決定,即max_client=worker_processes*worker_connections。進程的最大鏈接數接受linux系統接受linux系統進程的最大打開文件數限制,在執行操做系統命令「ulimit -Hsn 65535」或配置相應文件後,worker_connections的設置才能生效 } worker_connections用來設置一個worker process支持的最大併發鏈接數
調整配置nginx worker進程最大打開文件數,這個控制鏈接數的參數爲worker_rlimit_nofile。
worker_rlimit_nofile 65535;
最大打開文件數,可設置爲系統優化後的ulimit -HSn的結果
先要將確切名字和通配符名字存儲在散列表中,散列表和監聽端口關聯,每一個端口最多關聯到三張表;確切名字的散列表,以星號起始的通配符名字的散列表和以星號結束的通配符名字的散列表。散列表的尺寸在配置階段進行了優化,能夠以最小的cpu緩存命中失敗來找名字。nginx首先會搜索確切名字的散列表,若是沒有找到,則搜索以星號起始的通配符名字的散列表,若是仍是沒有找到,繼續搜索以星號結束的通配符名字的散列表。
[root@Poppy extra]# cat bbs.conf server { listen 80; server_name bbs.joker.com *.joker.com; 很明顯*.joker.com效率低 location / { root html/bbs; index index.html; } }
若是你要想定義大量的名字,或者定義很是長的名字,就須要在http配置塊中調整server_names_hash_max_size和server_names_hash_bucket_size的值。server_names_hash_max_size的默認值多是32或64,也多是其餘值,這取決於cpu的緩存行的長度。那麼定義「wwwwwwwwwwwwwwwwwwwwww.joker.com」做爲虛擬主機名就會失敗,此時會顯示下面的錯誤信息;
could not build the server_name_hash; you should increase server_names_hash_bucket_size:32
出了這種狀況,就須要將server_names_hash_max_size擴大一倍。
http{ server_names_hash_max_size 64 ....... }
若是定義了大量名字,會獲得以下另一個錯誤消息;
could not build the server_name_hash; you should increase server_names_hash_max_size:512 # 默認512kb,通常查看系統給出確切的值,cpu l1的4倍到5倍 or server_names_hash_bucket_size; 32
咱們應該修改server_names_hash_max_size的值,此值差很少等於名字列表的名字總量。
注意:後面不能帶單位
1. 設置參數sendfile on;
sendfile參數用於開啓文件的高效傳輸模式,同時將tcp_nopush和tcp_nodelay倆個指令設置爲on,可防止網絡及磁盤i/o阻塞,提高nginx工做效率
在http ,server,location,if in location字段標籤裏面能夠設置
http {
sendfile on; 默認是off
}
激活sendfile功能,sendfile()是做用於倆個文件描述符之間的數據拷貝函數,這個拷貝操做是在內核之中的,被稱爲「零拷貝」,sendfile()比read和write函數要高效不少,由於,read和write函數要把數據拷貝到應用層在進行操做。
2. 設置參數tcp_nopush
在http,server,location字段標籤裏面能夠設置
http {
sendfile on;
tcp_nopush on; 默認是off
}
激活linux上傳遞tcp_cork socket選項,此選項僅僅當開啓sendfile時才生效,激活這個,tcp_nopush參數能夠容許把http response header和文件的開始部分放在一個文件裏發佈,其積極的做用是減小網絡報文段的數量。
1. 連接超時的定義
當服務器創建的連接沒有接收處理請求時,可在指定的時間內就讓它超時自動退出。還有當nginx和fastcgi服務沒法給nginx返回數據,此時能夠經過配置nginx服務參數使其不會死等,由於前面用戶還等着它返回數據呢。
2. 連接超時的做用
簡單地說,連接超時是服務的一種自我管理,自我保護的重要機制。
3. 連接超時帶來的問題,以及不一樣程序連接設定知識
服務器創建連接是要消耗資源的,超時設置的過短而併發很大,就會致使服務器瞬間沒法響應用戶的請求,致使用戶體驗降低。
php程序站點會但願設置成短連接,由於php程序創建連接消耗資源和時間相對要少些。而對於java程序站點來講,建議設置長連接,由於java程序創建連接消耗的資源和時間更多。
4. nginx連接超時的參數設置
(1)設置參數;keepalive_timeout 60;
用於設置客戶端保持連接會話超時時間爲60秒。超過這個時間,服務器會關閉該連接
keepalive_timeout 60;
可設置在http,server,location字段標籤中,默認是75s
keep-alive可使客戶端到服務器端已經創建的連接一直工做不退出,當服務器有持續請求時,keep-alive會使用已經創建的連接提供服務,從而避免服務器從新創建新連接處理請求。
(2)設置參數:tcp_nodelay on;
用於激活tcp_nodelay功能,提升i/o性能,能夠設置在http,server,location字段標籤裏
http {
sendfile on;
tcp_nodelay on; 默認是on
}
當數據發送時,內核不會立刻發送,可能會等待更多的字節組成一個數據包,這樣能夠提升i/o性能。可是,在每次只發送不多字節的業務場景彙總,使用tcp_nodelay功能,等待時間會比較長。
(3)設置參數;client_header_timeout 15;
讀取客戶端請求頭數據的超時時間
能夠設置在http,server字段標籤裏
http {
sendfile on;
client_header_timeout 60s; 默認是60s
}
若是超過這個時間,客戶端尚未發送完整的header數據,服務器端將返回"Request timo out(408)"錯誤。
(4) 設置參數;client_body_timeout 15;
用於設置讀取客戶端請求主體的超時時間,默認值是60
http {
sendfile on;
client_bodyr_timeout 60s; 默認是60s
}
僅僅爲倆次成功的讀取操做之間的一個超時,非請求整個主體數據的超時時間。若是在這個超時時間內,客戶端沒有發 人和數據,nginx將返回"Request timo out(408)"錯誤。
(5) 設置參數;send_timeout 25;
用於指定響應客戶端的超時時間。這個超時僅限於2個連接活動之間的時間,若是超過這個時間,客戶端沒有人和活動,nginx將會關閉連接,默認值爲60秒。
http { sendfile on; send_timeout 25; 默認是60s }
服務器傳送http響應信息到客戶端的超時時間,這個超時僅僅爲倆次成功握手後的一個超時,非請求整個響應數據的超時時間,若是在這個超時時間內,客戶端沒有接收任何數據,連接將被關閉。
備註,細節能夠參考http://nginx.org/en/docs/http/ngx_http_core_module模塊
可設置在http,server,location字段標籤裏
http {
sendfile on;
client_max_body_size 8m; 默認是1m
}
設置最大容許客戶端請求主體的大小,post請求
nginx gzip壓縮模塊提供了壓縮文件內容的功能,用戶請求內容在發送用戶客戶端以前,nginx服務器會根據一些具體的策略實施壓縮,已節約網站出口帶寬,同時加快傳輸效率,來提高用戶訪問體驗
nginx gzip壓縮的優勢
須要和不須要壓縮的對象
功能依賴於ngx_http_gzip_module模塊,默認已安裝
這個模塊主要是負責Gzip功能的開啓和設置,對響應數據進行在線實時壓縮。指令以下
語法 | 說明 |
---|---|
是否開啓壓縮 gzip on | off |
該指令用於開啓或者關閉Gzip功能, 默認狀況下該指令設置爲off,只有爲on時,下面指令纔有效 |
壓縮須要申請的空間 gzip_buffers number size |
number:指定Nginx服務器須要向系統申請緩存空間的個數 size :指定緩存空間的大小; 根據該配置,nginx在對響應輸出數據經壓縮時須要向系統申請number*size 大小的空間用來存儲壓縮數據. 默認大小是128,其中size的值是取系統內存頁一頁的大小,爲4kb或者8kb 即: gzip_buffers 32 4k | 16 8k |
壓縮等級 gzip_comp_level level |
該指令用於設置Gzip壓縮程度,包括級別1-9, 級別1表示壓縮程度最低效率最高, 級別9表示 壓縮程度最高,效率最低 。 默認值是1 |
根據客戶端類型動態開啓壓縮 gzip_disabel regex… |
針對不一樣的客戶端的請求,能夠選擇性的開啓和關閉Gzip的功能 ,Nginx服務器在響應這種種類的客戶端請求時,不使用Gzip功能緩存響應輸出數據。regex根據客戶端的瀏覽器標誌(User-Agent,UA)設置,支持正則表達式。 例如 gzip_disable MSIE [4-6] 表示MSIE四、MSIE五、MSIE六、這些客戶端請求後,nginx不進行Gzip壓縮返回 |
根據瀏覽器版本是否開啓壓縮 gzip_http_version version |
早期的瀏覽器也許不支持Gzip的自解壓,所以客戶端有可能會看到亂碼,因此針對不一樣的HTTP協議版本,須要選擇性地開啓或者關閉Gzip功能。 默認設置爲1.1版本,即只有客戶端1.1及以上版本的HTTP協議,才使用Gzip壓縮功能,目前來看大部分瀏覽器都支持Gzip自解壓,因此使用默認值便可。 |
根據響應數據大小是否開啓壓縮 gzip_min_length length |
Gzip壓縮功能對大數據的壓縮效果明顯,可是若是壓縮的數據很小,就可能數據越壓縮越大,所以咱們也應該有選擇的壓縮。當響應頁面的大小大於該值纔開啓Gzip壓縮功能。響應頁面的大小經過HTTP響應頭部中的Content-Length指令獲取,若是咱們使用了Chunk編碼壓縮,Content-Length或不存在或被忽略,這條指令這不起做用。 默認值是20,設置爲0表示無論頁面多大都要壓縮。建議大於1kb的壓縮;好比:gzip_min_length 1024 |
根據響應頭部是否開啓壓縮 gzip_proxied off|expired |no-cache | no-store | private | no_last_modified | no_etag | auth | any …; |
off:表示關閉Nginx服務器對後端服務器返回結果的壓縮,這是默認設置 expired:表示當後端服務器響應頁頭部包含用於指示響應數據過時時間的expired頭域時,啓用對響應數據的Gzip壓縮 no-cache:表示當後端服務器響應頁頭部包含用於通知緩存機制是否緩存的Cache-Control頭域,且其指令值爲no-cache時,啓用對響應數據的Gzip壓縮 no-store:表示當後端服務器響應頁頭部包含用於通知緩存機制是否緩存的Cache-Control頭域,且其指令值爲no-store時,啓用對響應數據的Gzip壓縮 private:表示當後端服務器響應頁頭部包含用於通知緩存機制是否緩存的Cache-Control頭域,且其指令值爲private時,啓用對響應數據的Gzip壓縮 no_last_modified:表示當後端服務器響應頁頭部不包含用於指明獲取數據最後修改時間的Last-Modified頭域時,啓動對響應數據的Gzip壓縮 no_etag:表示當後端服務器響應頁頭部不包含用於標示被請求變量的實體值的ETag頭域時,啓動對響應數據的Gzip壓縮 auth:表示當後端服務器響應頁頭部包含用於標示HTTP受權證書的Authorization頭域時時,啓動對響應數據的Gzip壓縮 any:無條件啓動對響應數據的Gzip壓縮 |
根據響應頁的MIME類型開啓是否壓縮 gzip_types mime-type …; |
這個mime-type的默認值是text/html,實際上當gzip設置爲on的時候,Nginx服務器會對全部的text/html類型的頁面進行Gzip壓縮,該變量還能夠取值「*」,表示對全部的MIME類型頁面進行壓縮,通常咱們以下設置: gzip_types text/plain application/x-javascript text/css text/html application/html; |
用與設置Gzip功能是否發送帶有「Vary:Accept-Encoding」頭域的響應頭部 gzip_vary on | off |
該頭域的主要功能主要是告訴接收方發送的數據時經過壓縮處理,開啓後的效果是在響應頭部添加Accept-Encoding:gzip.這對於自己不止Gzip壓縮的客戶端瀏覽器是頗有用的。 默認是off的,固然我也能夠經過nginx配置的add_header指令強制Nginx服務器在響應頭部添加「Vary:Accept-Encoding」頭域: add_header Vary Accept-Encoding gzip; |
參考以下
gzip on;
gzip_min_length 1k;
gzip_comp_level 6;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
就是本地瀏覽器緩存的有效期,配置參數以下
(1)根據文件擴展名進行判斷,添加expires功能,server字段標籤中
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)${
expires 3650d;
}
(2) 根據url中的路徑(目錄)進行判斷,添加expires功能
location ~ ^/(images|javascript|js|css|flash|media|static)/ {
expires 360d;
}
(3) 單個文件添加expires功能
下面的命令會給robots.txt機器人文件設置過時時間
location ~ (robots.txt) { expires 70d; break; }
對於負載均衡器健康節點檢查或某些特定文件(好比圖片,js,css)的日誌,由於在統計pv時時按照頁面計算的,並且日誌寫入太頻繁會消耗大量磁盤i/o,下降服務的性能
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)${
access_log off;
}
日誌權限不要設爲nginx,www用戶讀或寫許可。
ab -c 1 -n 10 http://1.1.1.1/ -c 併發數,-n請求總數,1.1.1.1爲nginx的ip地址
server { listen port; server_name localhost; root html/a; index index.php; location / { #try_files $uri $uri/ /index.php =404; try_files $uri $uri/ /index.php =500; } error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } location ~ \.php$ { try_files $uri = 404; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
用戶請求 http://localhost/example 時,這裏的 $uri 就是 /example。 try_files 會到硬盤裏嘗試找這個文件。若是存在名爲 /$root/example(其中 $root 是項目代碼安裝目錄html/a)的文件,就直接把這個文件的內容發送給用戶。 顯然,目錄中沒有叫 example 的文件。而後就看 $uri/,增長了一個 /,也就是看有沒有名爲 /$root/example/ 的目錄。 又找不到,就會 fall back 到 try_files 的最後一個選項 /index.php,發起一個內部 「子請求」,也就是至關於 nginx 發起一個 HTTP 請求到 http://localhost/index.php。 這個請求會被 location ~ .*\.(php|php5)?$ { ... } catch 住,也就是進入 FastCGI 的處理程序。而具體的 URI 及參數是在 REQUEST_URI 中傳遞給 FastCGI 和 PHP 程序的,所以不受 URI 變化的影響。