Nginx安全優化與性能調優

来源:https://www.cnblogs.com/itbsl/archive/2020/07/25/13376448.html
-Advertisement-
Play Games

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


目錄

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。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 許可權概述 在mongodb裡面的用戶是屬於資料庫的,每個資料庫有自己的管理員,管理員登錄後,只能操作所屬的資料庫。 註意:一般在admin資料庫中創建的用戶授予超級管理員許可權,登錄後可以操作任何的資料庫。 創建超級管理員 註意:在開啟許可權管理控制時,一定先要創建一個超級管理員授予超級管理許可權。 (1 ...
  • 添加文檔 語法: db.集合名.insert({k1:"v1", k2:"v2"....}) 註意: (1)文檔就是鍵值對,數據類型是BSON格式,支持的值更加豐富。 比如:db.集合名.insert({name:"bashlog", spc:{weight:100, address:"henan" ...
  • 創建資料庫 語法: use database_name; 註意:如果該資料庫不存在,則創建,如果該資料庫存在,則是切換,如果創建了資料庫,沒有任何操作,則會自動刪除該資料庫。 可以使用db命令查看當前所處的資料庫 查看資料庫 語法: show dbs; 創建集合 語法: db.集合名.insert( ...
  • 報錯信息 無法訪問資料庫 ReportServer。 (ObjectExplorer) 具體錯誤信息: 程式位置: 在 Microsoft.SqlServer.Management.UI.VSIntegration.ObjectExplorer.DatabaseNavigableItem.get_C ...
  • 時光在不經意間,總是過得出奇的快。小暑已過,進入中暑,太陽更加熱烈的綻放著ta的光芒,...在外面被太陽照顧的人們啊,你們都是勤勞與可愛的人啊。在房子里已各種姿勢看我這篇這章的你,既然點了進來,那就由我繼續帶你回顧MySql的知識吧! 回顧練習資料girls庫以及兩張表的腳本: https://pa ...
  • Java事務解析(事務的基本操作+隔離的等級+事務的四大特性+事務的概念) 什麼是事務? 如果一個包含多個步驟的業務操作,這些操作被事務管理,那麼這些操作要麼同時成功要麼同時失敗 事務的四大特性(必須記住): 持久性:當事務回滾或者提交之後,資料庫會持久化數據 一致性:事務操作前後,數據的總量不變 ...
  • 快手,快影的App保護用的是同一套代碼,反調試也很容易,下麵請看過程。 >作為一個開發者,有一個學習的氛圍跟一個交流圈子特別重要,這是一個我的iOS交流群:761407670 進群密碼‘博客’,不管你是小白還是大牛歡迎入駐 ,分享BAT,阿裡面試題、面試經驗,討論技術, 大家一起交流學習成長! 1. ...
  • 《全棧工程師 Web 開髮指南》 [作者] (意) Dino Esposito[譯者] (中) 李永倫[出版] 人民郵電出版社[版次] 2019年03月 第1版[印次] 2019年03月 第1次 印刷[定價] 79.00元 【第02章】 【選擇支撐架構】 (P018) 領域模型模式的要點是構建一個完 ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...