Nginx安全優化與性能調優


Nginx基本安全優化

隱藏Nginx軟件版本號信息

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

我現在在我的CentOS7上編譯安裝了Nginx,當我們請求服務器的時候我們可以通過chrome的調試工具看到我們請求的服務器Nginx的版本,如下圖所示

假如Nginx1.18.0這個版本有漏洞,那么惡意用戶就可以根據這個信息通過漏洞來攻擊我們的服務器

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

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

現在我們重啟服務器再次訪問可以看到Nginx版本號已經看不到了

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

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

修改Nginx服務的默認用戶

為了讓Web服務更安全,要盡可能地改掉軟件默認的配置,比如端口、用戶等。

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

首先,查看Ninx服務對應的默認用戶。一般情況下,Ninx服務啟動后,默認使用的用戶是nobody,查看默認的配置文件命令如下:

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
# 是掩碼,分別代表第1、2、3、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頭,以提高性能

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM