nginx 安全配置文檔


1.配置文檔中有多處明確寫出了nginx的配置文件路徑,該路徑是測試環境中的路徑,線上系統的nginx配置文件與文檔中所寫的路徑可能不一樣,在進行相關配置時,應以線上配置文件的實際路徑為准。

線上系統nginx的安裝目錄在:/usr/local/nginx,默認配置文件在/usr/local/nginx/conf/nginx.conf,此外也引用了/usr/local/nginx/conf/conf.d目錄下的配置文件。

2.本文檔僅包括了用於提升安全的配置方法。

3.在遵從本文檔的方法進行配置前,請做好相關配置文件的備份,以便在配置失敗時可以回退到變更前狀態。

1.新安裝,選用安全穩定版本

編號:

Nginx_Sec_001

適用:

LINUX下新安裝或者升級nginx服務器

配置要求:

1.安裝包要求nginx官方網站獲取,官方網站地址:http://nginx.org/

2.安裝包優先選用穩定版(stable)最新版,如果要跨大版本升級nginx,則要求在測試環境測試不存在兼容性問題后才在生產環境進行部署。

3.要求對下載的源碼安裝包文件進行完整性驗證。

 

具體方法參考“備注”處的方法。

安全增強說明:

1.從官方網站下載安裝包及對安裝包進行指紋驗證可以最大程度確保安裝文件未被篡改;

2.使用最新版本,最大避免舊版版中已發現安全漏洞的威脅,使用穩定版可以確保功能穩定。

備注:

完整性驗證方法:

(1)每個nginx源碼包都有一個簽名文件,從官網訪問下載nginx源碼包的同時也下載該源碼包的簽名文件到同一目錄,該簽名文件是nginx官方使用pgp私鑰對源碼包進行簽名得到,該文件后綴..asc,獲取pgp簽名文件方法:

 

(2)nginx源碼包使用的是pgp簽名,進行簽名驗證時需要到GnuPG程序,如果沒有安裝該工具,可以使用yum install gnupg進行安裝。

  (3)獲取pgp簽名文件的公鑰ID,執行:# sudo gpg --verify nginx-1.11.3.tar.gz.asc

gpg: Signature made Tue 26 Jul 2016 09:59:49 PM CST using RSA key ID A1C052F8

gpg: Can't check signature: No public key

  (4)根據ID號從公鑰服務器中下載公鑰,如下:

 #sudo  gpg --keyserver hkp://keys.gnupg.net --recv-keys A1C052F8

gpg: requesting key A1C052F8 from hkp server keys.gnupg.net

gpg: /root/.gnupg/trustdb.gpg: trustdb created

gpg: key A1C052F8: public key "Maxim Dounin <mdounin@mdounin.ru>" imported

gpg: key A1C052F8: public key "Maxim Dounin <mdounin@mdounin.ru>" imported

gpg: no ultimately trusted keys found

gpg: Total number processed: 2

gpg:               imported: 2  (RSA: 2)

(5)利用公鑰驗證nginx源碼包和簽名文件,如下,說明文件沒有被篡改:

# sudo  gpg --verify nginx-1.11.3.tar.gz.asc

gpg: Signature made Tue 26 Jul 2016 09:59:49 PM CST using RSA key ID A1C052F8

gpg: Good signature from "Maxim Dounin <mdounin@mdounin.ru>"

gpg: WARNING: This key is not certified with a trusted signature!

gpg:          There is no indication that the signature belongs to the owner.

Primary key fingerprint: B0F4 2533 73F8 F6F5 10D4  2178 520A 9993 A1C0 52F8

2.使用普通賬號運行nginx服務 

編號:

Nginx_Sec_002

適用:

LINUX下新安裝部署或已上線nginx服務器

配置要求:

nginx服務器的work進程不能使用root賬號運行,要求以普通賬號運行,具體方法參考“備注”處的方法。

安全增強說明:

防范或降低攻擊者通過上傳webshell來獲取到的執行權限

備注:

配置普通賬號運行nginx服務方法:

1.nginx(worker進程)默認以nobody運行,創建普通賬號nginx,使用nginx賬號來運行

 # sudo  groupadd -g 1001 nginx #創建nginx組

# sudo  useradd  -s /sbin/nologin -M -g nginx -u 1001 nginx #創建nginx用戶並加入到nginx組,不創建家目錄,不允許nginx賬號登錄。

說明:GID和UID定義為1000,避免與nis系統上的賬號的ID沖突。

2.以普通賬號nginx來運行Nginx,兩個方法:

 方法1:如果是新安裝nginx,編譯時添加--user=nginx  --group=nginx參數;

 方法2:已完成nginx的安裝,通過修該配置文件來指定,如下:

  1)# sudo vim /usr/local/nginx/conf/nginx.conf

  2)#user  nobody;改成user nginx nginx;

 3)測試配置文件是否正確,執行命令# sudo /usr/local/nginx/sbin/nginx –t 

 4)3)步驟測試配置無錯誤后重啟Nginx服務器,執行命令# sudo  /usr/local/nginx/sbin/nginx -s reload

 5)查看work進程賬號,確認該進程賬號為nginx,執行命令# sudo  ps -aux |grep nginx

 Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ

root     30153  0.0  0.1  17976  1604 ?        Ss   22:53   0:00 nginx: master process /usr/local/nginx/sbin/nginx

nginx    30245  0.0  0.1  18404  1528 ?        S    23:05   0:00 nginx: worker process

3.修改nginx根目錄的用戶與用戶組:

1)chown –R ngin.nginx  nginx根目錄

 

注意:設置nginx根目錄的用戶和用戶組為nginx后,且安全加固中將umask設置成027后,nginx安裝目錄的權限為750,普通用戶無法訪問該目錄,此時需要nginx的安裝目錄的權限應該是755 

3.隱藏nginx的版本信息

編號:

Nginx_Sec_003

適用:

LINUX下新安裝部署或已上線nginx服務器

配置要求:

要求隱藏nginx的版本信息, 具體方法參考“備注”處的方法。

安全增強說明:

絕大多數漏洞掃描工具通過獲取目標web服務器的版本號來判斷該web服務器是否存在安全漏洞,隱藏版本號后可以最大減少惡意攻擊者通過漏掃工具來收集漏洞信息。

備注:

隱藏nginx版本信息方法:

1.編輯nginx配置文件,http塊中添加

server_tokens  off;

2.重啟nginx服務即可。

 

 

 

4.禁止目錄列表

編號:

Nginx_Sec_004

適用:

LINUX下新安裝部署或已上線nginx服務器

配置要求:

要求禁止nginx服務器目錄列表功能,默認已禁止目錄列表功能。具體方法參考“備注”處的方法。

安全增強說明:

1.當目標web服務器允許目錄時,只要訪問目標web服務器的目錄,如果該目錄下沒有設置默認訪問的文件,則會同時將該目錄的所有文件列出來,如下:

 

2.禁止目錄列表功能可以避免因暴露目標網站的目錄結構和敏感文件,最終造成敏感信息丟失。

備注:

nginx配置文件的locationserver http塊中都允許設置autoindex on;確認nginx沒有啟用目錄列表功能,即同時檢查這幾個地方沒有配置參數autoindex on; 

說明:

禁止目錄列表后,url訪問目錄應該是403錯誤,如下:

 

 

5.日志規范

編號:

Nginx_Sec_005

適用:

LINUX下新安裝部署或已上線nginx服務器

配置要求:

要求nginx服務器同時啟用訪問日志和錯誤日志的記錄,具體方法參考“備注”處的方法。

安全增強說明:

nginx訪問日志記錄了客戶端的請求行為,通過對訪問日志的分析能夠發現潛在的攻擊行為;nginx的錯誤日志反映了nginx 服務器的健康狀況,通過分析或者監控nginx的報錯信息能夠及時發現nginx存在故障問題。

備注:

1.設置訪問日志(access_log),日志的格式定義如下:

log_format  access  '$remote_addr - $remote_user [$time_local] '

                        '"$request" $status $body_bytes_sent "$http_referer" '

                        '"$http_user_agent" $http_x_forwarded_for';

各個變量的說明:

$remote_user    :用來記錄客戶端用戶名稱;

$time_local     :用來記錄訪問時間與時區;

$request        :用來記錄請求的url與http協議;

$status         :用來記錄請求狀態;成功是200,

$body_bytes_sent:記錄發送給客戶端文件主體內容大小;

$http_referer   :用來記錄從那個頁面鏈接訪問過來的;

$http_user_agent:記錄客戶端瀏覽器的相關信息;

$http_x_forwarded_for:用以記錄原始客戶端IP地址,如果原始客戶端原始請求發送到nginx前沒有經過任何代理,則該變量的值為-。

2.生成的訪問日志格式如下:

效果:

192.168.12.92 - - [12/Aug/2016:20:14:41 +0800] "GET /index.html HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0" –

3.錯誤日志的級別要求定義為warn,如下

error_log  logs/error.log  warn;

注意:如果更改日志文件的默認路徑,則nginx運行賬號需要具有新路勁下日志文件的讀寫權限。

 

說明:錯誤日志級別包括: debug, info, notice, warn, error, crit, alert, or emerg.默認是error級別.

當前3.0系統線上環境nginx編譯時將access日志和error日志存在/var/log/nginx目錄下。

 

6.限制不安全請求方法

編號:

Nginx_Sec_006

適用:

LINUX下新安裝部署或已上線nginx服務器

配置建議:

建議拒絕接受除POST和GET,HEAD以外的請求方法,具體方法參考“備注”處的方法。

安全增強說明:

http定義了8種請求方法,其中PUT、DELETE等請求方法是不安全的,限制不安全的請求方法降低目標網站文件被惡意篡改的風險。

備注:

配置拒絕除get,head和post方法以外的請求方法:

編輯Nginx配置文件如下:

server{

       ... ...

      if ($request_method !~ ^(GET|HEAD|POST)$) {        

                     return 444;

              }

       ... ...

注:非標准的444錯誤代碼可以強制關閉服務器與客戶端的連接而不返回任何響應信息給客戶端。

 

http的8種請求方式:

GET:當瀏覽器要從服務器讀取指定文檔。Get方法要求服務器將URL定位的資源放在響應報文的正文中,回傳給瀏覽器。

HEAD:使用post方法,瀏覽器只讀取請求文件的頭部信息,而不是文件的正文;

POST:向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。

PUT:從客戶端傳送的數據取代(替換)指定文件的內容;

DELETE:請求服務器刪除指定文件;

TRACE:回顯服務器收到的請求,主要用於測試或診斷;

OPTIONS:1)獲取服務器支持的HTTP請求方法;2)用來檢查服務器的性能;

CONNECT: HTTP/1.1協議中預留給能夠將連接改為管道方式的代理服務器。

 

7.禁用SSL/TSL不安全協議和弱加密算法

編號:

Tomcat_Sec_007

適用:

使用提供HTTPS方式訪問的Tomcat服務器

配置要求:

nginx使用到https訪問時,要求禁止使用SSLV1.0SSLV2.0SSLV3.0不安全協議,建議也不要使用TLSv1.0協議,要求禁止使用以下不安全加密算法:

 

具體配置方法參考“備注”處的方法。

安全增強說明:

降低由於使用不安全協議和弱加密導致被中間人攻擊,最終造成敏感信息泄露的風險。

備注:

在nginx配置文件中的ssl_protocols和ssl_ciphers做如下配置:

ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;

ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH:!kEDH:!kECDH;

ssl_prefer_server_ciphers   on;

保存配置文件並重啟nginx服務即可。

 

最終支持的加密協議和加密套件如下:

 

 

優先使用說明:

加密協議

優先使用順序TLSv1.2,TLSv1.1,TLS1.0。其中TLS1.0也被認為是不安全協議,建議不使用。

加密套件:

密鑰交換算法,優先使用順序:ECDHE(支持正向安全,2048位,防止中間人攻擊),DHE,RSA(無法防止中間人攻擊),不要使用1024位的DH。

認證算法,優先使用RSA, ECDSA

對稱加密算法,優先使用AES_256_GCM,AES_128_GCM,AES_256_CBC,AES_128_CBC,3DES_EDE_CBC

散列算法,優先使用順序SHA_256,SHA1

 

8.自定義緩沖區

編號:

Nginx_Sec_008

適用:

LINUX下新安裝部署或已上線nginx服務器

配置建議:

此方法可用於在遭受攻擊時用於減輕攻擊的防范手段,平時不強制要求配置,如要配置,相關參數則需要根據實際情況來定,具體配置方法如下:

http{

    ... ...

    server{

        ... ...

        client_body_buffer_size  16K;

        client_header_buffer_size  1k;

        large_client_header_buffers  4  8k;

        client_max_body_size  1m;

安全增強說明:

主要用於防范或者減輕緩沖區溢出攻擊。

備注:

語法:    client_body_buffer_size size;

默認: client_body_buffer_size 8k|16k;

上下文: http, server, location

參數使用說明:

設置緩沖區(buffer)大小,用於存放所讀取客戶端的請求體,在請求體(request body)大於buffer,那么整個請求體或者請求體的一部分會寫到臨時文件(a temporary file)。默認情況下:buffer大小等於兩個內存頁,在 x86, other 32-bit platforms, and x86-64這些平台它的大小是8K,64-bit平台通常是16k.

--------------------------------------------------------------------------------------------------

語法: client_header_buffer_size size;

默認: client_header_buffer_size 1k;

上下文: http, server

參數使用說明:

設置緩沖區(buffer)大小,用於存放所讀取客戶端的請求頭,在大多數的請求中1k大小的buffer已經足夠。但是,如果一個請求頭包括很長的cookies或者來自WAP客戶端,配置1k可能是不適合的,如果分配的buffer無法容納 request_line/request_header

,那么則根據large_client_header_buffers配置的參數來分配large_buffer。

------------------------------------------------------------------------------------------------------------------

語法: large_client_header_buffers number size;

默認: large_client_header_buffers 4 8k;

上下文: http, server

參數使用說明:

設置單個buffers的大小以及buffers最大個數用於存放所讀取客戶端的大請求頭(reading large client request header),先根據client_header_buffer_size配置的值分配一個buffer,如果分配的buffer無法容納 request_line/request_header,那么就會再次根據large_client_header_buffers配置的參數分配large_buffer,如果large_buffer還是無法容納,那么就會返回414(處理request_line)/400(處理request_header)錯誤。

------------------------------------------------------------------------------------------------------------------

語法: client_max_body_size size;

默認: client_max_body_size 1m;

上下文: http, server, location

參數使用說明:

Sets the maximum allowed size of the client request body(請求體), specified in the “Content-Length” request header field(請求體的大小在請求頭Content-Length字體寫明,單位字節). If the size in a request exceeds the configured value, the 413 (Request Entity Too Large) error is returned to the client(如果請求體大小大於該設定值,則給客戶端返回413錯誤). Please be aware that browsers cannot correctly display this error(但瀏覽器不能正確顯示該錯誤). Setting size to 0 disables checking of client request body size.(設置值為0時,不限制請求體大小)

該參數用於設置nginx允許客戶端請求體的最大值,請求體的大小在請求頭Content-Length字體寫明,單位字節。如果親請求體的大小超過了配置的值,則向客戶端返回413錯誤,但需要注意的是瀏覽器不能正確顯示該錯誤,如果該參數值設置0,則不限制請求體大小。

 

9.設置連接超時時間

編號:

Nginx_Sec_009

適用:

LINUX下新安裝部署或已上線nginx服務器

配置建議:

此方法可用於在遭受攻擊時用於減輕攻擊的防范手段,平時不強制要求配置,如要配置,相關參數則需要根據實際情況來定,具體配置方法如下:

 

http {

    ... ...

       client_body_timeout   10;

       client_header_timeout  30;

       keepalive_timeout     30  30;

       send_timeout          10;

安全增強說明:

主要用於防范或者減輕慢連接攻擊。

備注:

語法: client_body_timeout time;

默認: client_body_timeout 60s;

上下文: http, server, location

參數使用說明:

設置讀取客戶端的請求體(request body.)超時時間,該超時時間為在兩個連續的讀取操作間的超時時間,而不是整個請求體的傳輸超時時間。如果在這個時間內客戶端沒有響應(transmit anything),nginx將向客戶端返回408請求超時錯誤。

 

注意:只有請求體需要被1次以上讀取時,該超時時間才會被設置。

---------------------------------------------------------------------------------------------------

語法: client_header_timeout time;

默認: client_header_timeout 60s;

上下文: http, server

參數使用說明:

設置讀取客戶端請求頭的超時時間,如果在該時間內客戶端沒有傳輸完整個請求頭(the entire header),nginx將返回408(請求超時)錯誤。

-------------------------------------------------------------------------------------------------------------------

語法:  keepalive_timeout timeout [header_timeout];
默認:  keepalive_timeout 75s;

上下文:http, server, location

參數使用說明:

第一個參數的值指定了客戶端與服務器長連接的超時時間,超過這個時間,服務器將關閉連接。值為0時,關閉客戶端的會話保持連接,(即關閉長連接).

第二個參數的值(可選)指定了應答頭中Keep-Alive: timeout=time的time值,這個值可以使一些瀏覽器知道什么時候關閉連接,以便服務器不用重復關閉,如果不指定這個參數,nginx不會在應答頭中發送Keep-Alive信息。

----------------------------------------------------------------------------------------------------------------

語法: send_timeout time;

默認: send_timeout 60s;

上下文: http, server, location

參數使用說明:

該指令指定了發送給客戶端應答后的超時時間,Timeout是指沒有進入完整established狀態,只完成了兩次握手,如果超過這個時間客戶端沒有任何響應,nginx將關閉連接。

10.限制並發連接

 

編號:

Nginx_Sec_010

適用:

LINUX下新安裝部署或已上線nginx服務器

配置建議:

此方法可用於在遭受攻擊時用於減輕攻擊的防范手段,平時不強制要求配置,如要配置,相關參數則需要根據實際情況來定,具體配置方法如下:

1.nginx.conf里的http{}里加上如下代碼:

limit_conn_zone $binary_remote_addr zone=perip:10m; 

limit_conn_zone $server_name zone=perserver:10m;

2.在需要限制並發數和下載帶寬的網站配置server{}里加上如下代碼:

#每IP最大並發為2。

limit_conn perip 2;  

限制單一虛擬服務器,最大只接受20個並發

limit_conn perserver 20; 

limit_rate 100k;

安全增強說明:

主要用以防范或者減輕DDOS攻擊。

備注:

語法:   limit_conn_zone key zone=name:size;

默認: —

上下文: http

參數使用說明:

定義一個用於存放key變量,大小為szie名稱為name的zone,key的值可以是特定變量的任何非空值(空值將不會被考慮)。

例如:

limit_conn_zone $binary_remote_addr zone=perip:10m;

定義一個大小為10m字節,名稱為perip的zone,該zone用於二進制來儲存客戶端的IP地址; Ipv4地址對應的 $binary_remote_addr 變量的大小為 4 bytes ,IPv6 地址對應的是16字節。.

--------------------------------------------------------------------------------------------------

語法: limit_conn zone number;

默認: —

上下文: http, server, location

使用參數說明:

Zone變量是一個需要引起的zone,zone在前面的limit_conn_zone命令中已經定義好,使用limit_conn_zone名義中定義的zone名稱即可引用,number參數用於定義一個數字,並應用到該zone,說明對該zone做並發連接數限制,最大並發連接數為number定義的值,如果客戶端並發連接請求大於該值,則向客戶端返回503錯誤(服務暫時不可用)。

例如:

limit_conn_zone $binary_remote_addr zone=addr:10m;

server {

    location /download/ {

        limit_conn addr 1;

}

 

在同一時間(at a time),一個IP僅允許一個連接。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

語法:    limit_rate rate;

默認: limit_rate 0;

上下文: http, server, location, if in location

參數使用說明

限制響應傳輸給客戶端的速率(下載速度),rate指定多少字節每秒,值為0時不限速。注意,這里是對連接限速,而不是對IP限速。如果一個IP允許兩個並發連接,那么這個IP就是限速limit_rate×2。


免責聲明!

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



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