Nginx安全優化與性能調優

Nginx基本安全優化

隱藏Nginx軟件版本號信息

通常來講,軟件的漏洞都和版本有關,這個很像汽車的缺陷,同一批次的要有問題就都有問題,別的批次可能就都是好的。所以,咱們應儘可能隱藏或者消除Web服務對訪問用戶顯示各種敏感信息(例如Web軟件名稱以及版本號等信息),增長惡意用戶攻擊服務器的難度,從而增強Web服務器的安全性。javascript

我如今在個人CentOS7上編譯安裝了Nginx,當咱們請求服務器的時候咱們能夠經過chrome的調試工具看到咱們請求的服務器Nginx的版本,以下圖所示css

假如Nginx1.18.0這個版本有漏洞,那麼惡意用戶就能夠根據這個信息經過漏洞來攻擊咱們的服務器html

如今咱們來在Nginx的配置文件nginx.conf中增長一項參數來隱藏Nginx的版本,這樣用戶就不知道咱們用的是哪一個版本的Nginx了。前端

在nginx.conf中的http標籤段內加入server_tokens off;參數,以下圖所示java

如今咱們重啓服務器再次訪問能夠看到Nginx版本號已經看不到了node

更改源碼隱藏Nginx軟件名及版本號

隱藏了Nginx版本號後,更進一步,能夠經過一些手段把Web服務軟件的名稱也隱藏起來,或者改成其餘Web服務軟件名以迷惑惡意用戶。Nginx並不提供修改Nginx軟件名稱的參數和入口,須要修改源碼才行,這裏只是提供一個思路,修改源碼需慎重,防止修改源碼致使服務器不能正常運行。其它服務器軟件同理。修改方法自行百度。nginx

修改Nginx服務的默認用戶

爲了讓Web服務更安全,要儘量地改掉軟件默認的配置,好比端口、用戶等。web

下面就來更改Ninx服務的默認用戶。算法

首先,查看Ninx服務對應的默認用戶。通常狀況下,Ninx服務啓動後,默認使用的用戶是nobody,查看默認的配置文件命令以下:chrome

grep '#user' nginx.conf.default

爲了防止黑客猜到這個Web服務的用戶,咱們須要更改成特殊的用戶名,例如www、nginx或者特殊點的itbsl,可是這個用戶必須是系統裏事先存在的,下面以nginx用戶爲例進行說明

(1)爲Nginx服務建立新用戶

爲Nginx服務創建新用戶的操做過程以下:

useradd nginx -s /sbin/nologin -M # 不須要有系統登陸權限,應當禁止其登陸能力

(2)配置Nginx服務,讓其使用剛創建的Nginx用戶

更改Nginx服務默認使用的用戶,方法有兩種

第一種是直接修改配置文件參數,將默認的#user nobody;修改成以下內容:

user nginx nginx;

若是註釋或不設置上述參數,默認爲nobody用戶,不推薦使用nobody用戶名,最好採用一個普通用戶。

第二種方法爲直接在編譯Nginx軟件的時候指定編譯的用戶名和組,命令以下(推薦使用該種方式):

./configure \
--user=nginx \
--group=nginx \
--prefix=/usr/local/nginx-1.18.0 \
--with-http_v2_module \
--with-http_ssl_module \
--with-http_stub_status_module

提示:在編譯Nginx服務時,直接指定用戶和組,這樣不管配置文件中是否加參數,默認都是nginx用戶。

修改參數優化Nginx服務性能

優化Nginx服務的worker進程數

在高併發、高訪問量的Web服務場景,須要事先啓動好更多的Nginx進程,以保證快速響應並處理大量併發用戶的請求。

1.優化NGINX進程對應的配置

優化Nginx進程對應的Nginx服務的配置參數以下:

worker_processes  1; # 指定了Nginx要開啓的進程數,結尾的數字就是進程的個數

上述參數調整的是Nginx服務的worker進程數,Nginx有Master進程和worker進程之分,Master爲管理進程,真正處理請求的是worker進程。

2.優化Nginx進程個數的策略

worker_processes參數大小的設置最好和網站的用戶數量相關聯,可若是是新配置,不知道網站的用戶數量該怎麼辦?

搭建服務器時,worker進程數最開始的設置能夠等於CPU的核數,且worker進程數要多一些,這樣起始提供服務時就不會出現由於訪問量快速增長而臨時啓動新進程提供服務的問題,縮短了系統的瞬時開銷和提供服務的時間,提高了服務用戶的速度。高流量高併發場合也能夠考慮將進程數提升至CPU核數*2,具體狀況要根據實際的業務來選擇,由於這個參數除了要和CPU核數匹配外,也和硬盤存儲的數據及系統的負載有關,設置爲CPU的核數是一個好的起始配置,這也是官方的建議。

3.查看Web服務器CPU硬件資源信息

經過/proc/cpuinfo可查看CPU個數及總核數。查看PCU總核數的示例以下:

# 方法一
grep processor /proc/cpuinfo | wc -l
# 方法二
grep -c processor /proc/cpuinfo

經過top命令,而後按數字1,便可顯示全部的CPU核數,以下:

4.修改服務器Nginx配置

個人服務器時1核2G,假設服務器的CPU顆數爲1顆,核數爲4核,咱們將參數值改成4

worker_processes  4;

修改並保存後,優雅重啓Nginx,使修改生效,以下:

nginx -s reload

如今檢查修改後的worker進程數量,以下:

# 假如Nginx監聽的是8端口
lsof -i:80
# 或者經過以下命令查看
ps -ef | grep nginx | grep -v grep

worker_process可知,worker的進程數爲4個。Nginx Master主進程不包含在這個參數裏,Nginx Master的主進程爲管理進程,負責調度和管理worker進程。

綁定不一樣的Nginx進程到不一樣的CPU上

默認狀況下,Nginx的多個進程有可能跑在某一個CPU或CPU的某一核上,致使Nginx進程使用硬件的資源不均,因此咱們須要配置Nginx與CPU的親和力參數,儘量地分配不一樣的Nginx進程給不一樣的CPU處理,打到充分有效利用硬件的多CPU多核資源的目的。

在優化不一樣的Nginx進程對應不一樣的CPU配置時,四核CPU服務器的參數配置參考以下:

worker_processes  4;
# worker_cpu_affinity就是配置Nginx進程與CPU親和力的參數,即把不一樣的進程分給不一樣的CPU處理。這裏0001 0010 0100 1000
# 是掩碼,分別表明第一、二、三、4核CPU,因爲worker_processes進程數爲4,所以,該配置會吧每一個進程分配一核CPU處理,默認狀況
# 下進程不會綁定任何CPU,參數位置爲main段
worker_cpu_affinity 0001 0010 0100 1000;

八核CPU服務器的參數配置參考以下:

worker_processes  8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;

Nginx事件處理模型優化

Nginx的鏈接鏈接處理機制在不一樣的操做系統會採用不一樣的I/O模型,在Linux下,Nginx使用epoll的I/O多路複用模型,在Freebsd中使用kqueue的I/O多路複用模型,在Solaris中使用/dev/poll方式的I/O多路複用模型,在Windows中使用的是icop,等等。

要根據系統類型選擇不一樣的事件處理模型,可供使用的選擇有use [kqueue|rtsig|epoll|/dev/poll|select|poll]。我使用的是CentOS7,所以將Nginx的時間處理模型調整爲epoll模型。

具體的配置參數以下:

# events指令是設定Nginx的工做模式及鏈接數上限
events {
    use epoll;
    worker_connections  10240;
}
# use是一個事件模塊指令,用來指定Nginx的工做模式。Nginx支持的工做模式有select、poll、kqueue、epoll、rtsig和/dev/poll
# 其中select和poll都是標準的工做模式,kqueue和epoll是高效的工做模式,不一樣的是epoll用在Linux平臺上,kqueue用在BSD系統中。對於Linux系統Linux2.6+的內核,推薦選擇epoll工做模式,這是高性能高併發的設置

調整Nginx單進程容許的客戶端最大鏈接數

接下來,調整Nginx單個進程容許的客戶端最大鏈接數,這個控制鏈接數的參數爲worker_connections

events {
    # worker_connections也是個事件模塊指令,用於定義Nginx每一個進程的最大鏈接數,默認是1024。最大客戶端鏈接數由
    # worker_processes和worker_connections決定,即Max_client=worker_processes*worker_connections。進程
    # 的最大鏈接數受Linux系統進程的最大打開文件數限制,在執行操做系統命令`ulimit -HSn 65535`或配置相關文件後,
    # worker_connections的設置才能生效
    worker_connections  10240;
}

說明:worker_connections用來設置一個worker process支持的最大併發鏈接數,這個鏈接數包括了全部鏈接,例如:代理服務器的鏈接、客戶端的鏈接等,實際的併發鏈接數除了受worker_connections參數控制外,還和最大打開文件數 worker_rlimit_nofile有關,Nginx總併發鏈接=worker數量 * worker_connections。

配置Nginx worker進程最大打開文件數

接下來,調整配置Nginx worker進程的最大打開文件數,這個控制鏈接數的參數爲worker_rlimit_nofile。該參數的實際配置以下:

# 最大打開文件數,可設置爲系統優化後的ulimit -HSn的結果,調整系統文件描述和這個問題有相同之處
worker_rlimit_nofile 65535;

開啓高效文件傳輸模式

1.設置參數: sendfile on;

sendfile參數用於開啓文件的高效傳輸模式。同時將tcp_nopush和tcp_nodelay兩個指令設置爲on,可防止網絡及磁盤I/O阻塞,提高Nginx工做效率。

sendfile    on;

2.設置參數:tcp_nopush on;

參數做用:激活或禁用

限制文件上傳大小

下面介紹如何調整上傳文件的大小(http Request body size)限制。

在nginx.conf的http段增長以下配置參數:

client_max_body_size 10m; # 最大容許上傳的文件大小根據業務需求來設置

若是上傳的文件大小超過該設置,那麼就會報413 Request Entity Too Large的錯誤。

配置gzip壓縮實現性能優化

Nginx gzip壓縮功能介紹

Nginx gzip壓縮模塊提供了壓縮文件內容的功能,用戶請求的內容在發送到用戶客戶端以前,Nginx服務器會根據一些具體的策略實施壓縮策略,以節約網站出口帶寬,同時加快數據傳輸效率,來提高用戶訪問體驗。

Nginx gzip壓縮的優勢

  • 提高網站用戶體驗:發送給用戶的內容小了,用戶訪問單位大小的頁面就加快了,用戶體驗提高了,網站口碑就行了
  • 節約網站帶寬成本:數據是壓縮傳輸的,所以節省了網站的帶寬流量成本,不過壓縮時會稍微消耗一些CPU資源,這個通常能夠忽略不計

須要和不須要壓縮的對象

  • 純文本內容壓縮比很高,所以,純文本的內容最好進行壓縮,例如:html、css、js、xml、shtml等格式的文件
  • 被壓縮的純文本文件必須大於1KB,因爲壓縮算法的特殊緣由,極小的文件壓縮後可能反而變大
  • 圖片、視頻(流媒體)等文件儘可能不要壓縮,由於這些文件大多都是通過壓縮的,若是再壓縮極可能不會減少或減少不多,或者可能增大,同事壓縮時還會消耗大量的CPU、內存資源

參數介紹及配置使用

此壓縮功能與早期的Apache服務的mod_deflate壓縮功能很類似,Nginx的gzip壓縮功能依賴於ngx_http_gzip_module模塊,默認已安裝。

對應的壓縮參數說明以下:

#壓縮配置
# 開啓gzip壓縮功能
gzip on;  
# 設置容許壓縮的頁面最小字節數,頁面字節數從header頭的Content-Length中獲取。默認值是0,表示無論頁面多大都進行壓縮。
# 建議設置成大於1K,若是小於1K可能會越壓越大
gzip_min_length 1k; 
# 壓縮緩存區大小。表示申請4個單位的位16K的內存做爲壓縮結果流緩存,
# 默認值是申請與原始數據大小相同的內存空間來存儲gizp壓縮結構
gzip_buffers 4 16k;
# 壓縮版本(默認1.1),用於設置識別HTTP協議版本,默認是1.1,目前大部分瀏覽器都支持GZIP解壓,使用默認便可
gzip_http_version 1.1;
# 壓縮比率。用來指定gzip壓縮比,1壓縮比最小,處理速度最快;9壓縮比最大,傳輸速度快,但處理最慢,也比較消耗CPU資源
gzip_comp_level 2;
# 用來指定壓縮的類型
gzip_types text/plain text/css text/xml application/javascript;
# vary header支持。該選項可讓前端的緩存服務器緩存通過gzip壓縮的頁面,例如用Squid緩存通過Nginx壓縮的數據
gzip_vary on;

不一樣Nginx版本中,gzip_types的配置可能會有不一樣,對應的文件類型,請查看安裝目錄的mime.types文件

增長http accept-ranges頭來提升性能

網頁的圖片,js ,css ,視頻 都加 http accept-ranges頭,以支持多線程加載,斷點續傳,提升性能!目前各大網站都在使用此方式!

server {
  listen 80;
  server_name p2hp.com;
  location ~ ^/(img/|js/|css/|upload/|font/|fonts/|res/|video) {
    add_header Access-Control-Allow-Origin *;
    add_header Accept-Ranges bytes;
    root /var/www/...;
    access_log off;
    expires 30d;
  }
}

Nginx日誌相關優化與安全

Nginx access日誌切割

爲何要作日誌切割?

由於隨時系統訪問量的增加,訪問日誌裏會出現愈來愈多的數據,若是不去按照時間去作合理的日誌切割,訪問日誌裏的數據多到沒法打開的地步,因此須要作日誌切割。

建立一個runlog.sh文件,按天切割

LOGPATH=/usr/local/nginx/logs/access.log
BASEPATH=/usr/local/nginx/logs/access/$(date -d yesterday +%Y%m)

mkdir -p $BASEPATH

BACKUP=$BASEPATH/$(date -d yesterday +%Y%m%d).access.log

mv $LOGPATH $BACKUP
touch $LOGPATH
/usr/local/nginx/sbin/nginx -s reopen

而後配合定時任務,天天零點切割一次

0 0 * * * sh /usr/local/nginx/logs/runlog.sh

Nginx圖片及目錄防盜鏈解決方案

若是咱們本身網站內的圖片資源被其它網站所盜用,這會增長本身網站的帶寬資源,增長不少額外的消耗,並且會對咱們系統的穩定性有影響,爲了防止本身網站上的圖片資源被其它網站所盜用,咱們須要給本身的服務器配置防盜鏈。

在Nginx的配置文件nginx.conf的 server段匹配圖片資源容許的域名,,不匹配的直接重定向到其它鏈接或者直接返回403錯誤。

# 圖片防盜鏈
location ~* \.(png|jpg|jpeg|gif|swf|flv)$ {
    valid_referers none blocked www.test.com *.test.com;
    if ($invalid_referer) {
        # 若是有盜鏈的狀況就使用url重寫到錯誤頁面(示例重定向到了百度首頁logo圖片)
        rewrite ^/ https://www.baidu.com/img/bd_logo1.png?qua=high;
        # 或者直接返回403錯誤碼
        #return 403;
    }
}

Nginx防爬蟲優化

robots.txt機器人協議介紹

Robots協議(也稱爲爬蟲協議、機器人協議等)的全稱是「網絡爬蟲排除標準」(Robots Exclusion Protocol),網站經過Robots協議告訴搜索引擎那些頁面能夠抓取,那些頁面不能抓取。

Nginx防爬蟲優化配置

咱們能夠根據客戶端的user-agent信息,輕鬆地阻止指定的爬蟲爬取咱們的網站。下面來看幾個案例。

範例1:阻止下載協議代理,命令以下:

if ($http_user_agent ~* LWP::Simple|BBBike|wget) {
    return 403;
}

說明:若是用戶匹配了if後面的客戶端(例如wget),就返回403

範例2:測試禁止不一樣的瀏覽器軟件訪問

示例代碼以下:

if ($http_user_agent ~* "Firefox|MSIE") {
    rewrite ^(.*) http://www.baidu.com/$1 permanent;
}

若是瀏覽器爲FireFox或IE,就會跳轉到http://www.baidu.com。

整理自:
跟老男孩學Linux運維:Web集羣實戰,機械工業出版社
網頁的圖片,js ,css ,視頻 都加 http accept-ranges頭,以提升性能

若是該文章對您有幫助,請點擊推薦,感謝。

相關文章
相關標籤/搜索