Nginx基本安全優化 隱藏Nginx軟體版本號信息 一般來說,軟體的漏洞都和版本有關,這個很像汽車的缺陷,同一批次的要有問題就都有問題,別的批次可能就都是好的。因此,我們應儘量隱藏或者消除Web服務對訪問用戶顯示各類敏感信息(例如Web軟體名稱以及版本號等信息),增加惡意用戶攻擊伺服器的難度,從而 ...
目錄
- Nginx基本安全優化
- 修改參數優化Nginx服務性能
- Nginx日誌相關優化與安全
- Nginx圖片及目錄防盜鏈解決方案
- 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。