大佬必備!99%的Nginx安全問題都能用這些方法解決!

簡介: 在當今數字化時代,網路安全至關重要。Nginx作為流行的Web伺服器,不僅提供高效能,還具備強大的安全保障功能。然而,預設配置可能無法抵禦所有安全威脅,因此對Nginx進行安全加固尤為重要。本文為系統管理員、開發者等提供詳盡的安全加固指南,涵蓋基礎到高階策略,包括隱藏版本號資訊、限制敏感目錄訪問、啟用HTTPS、配置錯誤頁面、應用內容安全策略(CSP)、設定正確檔案許可權、新增安全HTTP響應頭、限制連線數、配置IP白名單、最佳化SSL配置、確保檔案上傳安全、防止常見攻擊。透過這些措施,可以有效提升Nginx的安全性,保護網站和應用程式免受潛在威脅。

引言

在當今數字化的世界中,網路安全已成為每一個組織和個人不可忽視的重要議題。作為最流行的Web伺服器之一,Nginx不僅因為其高效能而被廣泛使用,還因為它能夠提供強大的安全保障。然而,預設配置下的Nginx可能無法抵禦所有潛在的安全威脅。為了確保您的網站和應用程式能夠在網際網路上穩健執行,對Nginx進行適當的安全加固顯得尤為重要。
本文旨在為系統管理員、開發者以及任何對提升Nginx安全性感興趣的讀者提供一份詳盡的安全加固路線圖。我們將探討從基礎到高階的各種策略,包括但不限於正確的許可權設定、限制對外暴露的資訊、啟用加密連線、配置防火牆等關鍵措施。無論您是希望保護個人部落格免受攻擊,還是為企業的線上服務構建堅固的防線,本文都將為您提供寶貴的實踐指導和技術支援。讓我們一起深入瞭解如何透過最佳化Nginx配置來提高您的網路環境的安全性吧。

隱藏版本號資訊

預設情況下,Nginx會在HTTP響應頭中暴露其版本號。攻擊者可以利用這些資訊來尋找特定版本的漏洞。透過在配置檔案中的http、server或location塊內新增server_tokens off;來關閉這個功能。
步驟
  1. 開啟Nginx配置檔案:通常位於/etc/nginx/nginx.conf/usr/local/nginx/conf/nginx.conf,具體位置取決於你的安裝方式。
  2. 編輯配置檔案:找到http塊,並在其中新增server_tokens off;指令。如果你有多個server塊,也可以在每個server塊中單獨設定這個選項,以確保它在整個伺服器範圍內生效。
  3. 儲存並退出編輯器:完成修改後儲存更改。
  4. 檢查配置語法:使用命令nginx -t來測試配置檔案是否有語法錯誤。
  5. 重新載入Nginx:如果配置檔案沒有問題,使用命令nginx -s reload來應用新的配置。

# nginx.conf 或者某個特定的 server 配置檔案
http {
# 其他配置...
# 關閉版本資訊顯示

server_tokens off;
# 更多其他配置...
server {
listen

80

;

server_name example.com;
# 在 server 塊內也可以設定 server_tokens

# server_tokens off;
location / {
root /

var

/www/html;

index index.html index.htm;

}

}

}

限制訪問敏感目錄

為了防止外部使用者訪問敏感資源,比如.htaccess檔案或.git目錄,你可以使用Nginx的location塊和deny all;指令來實現。以下是如何配置的具體示例程式碼以及一個實際案例說明。
下面的例子展示瞭如何在Nginx配置中新增規則以阻止對.git目錄和.htaccess檔案的訪問:

server {
listen

80

;

server_name example.com;
# 根目錄設定

root /

var

/www/html;
# 禁止訪問.git目錄

location ~ /\.git {
deny all;

}
# 禁止訪問.htaccess檔案

location ~ /\.ht {
deny all;

}
# 其他location配置...

}

在這個例子中,我們使用了正則表示式匹配來定位.git和.htaccess檔案,並透過deny all;指令拒絕所有請求到這些資源的訪問。
假設你有一個基於Git版本控制的Web專案部署在你的伺服器上,並且你不希望任何訪問者能夠看到.git目錄下的內容,因為這可能包含敏感資訊如提交歷史、開發者郵箱等。同樣地,如果你不小心將.htaccess檔案留在了你的Web根目錄下,你也希望能夠阻止外部訪問這個檔案。
按照上述配置,當你嘗試直接訪問http://example.com/.git/ 或 http://example.com/.htaccess 時,Nginx會返回403 Forbidden錯誤,從而保護這些敏感資源不被公開訪問。
此外,如果你想提供一個友好的錯誤頁面而不是預設的403錯誤頁面,可以結合使用error_page指令。例如:

server {
listen

80

;

server_name example.com;
# 根目錄設定

root /

var

/www/html;
# 定義自定義

403

錯誤頁面

error_page

403

/custom_403.html;
# 禁止訪問.git目錄

location ~ /\.git {
deny all;

}
# 禁止訪問.htaccess檔案

location ~ /\.ht {
deny all;

}
# 自定義

403

錯誤頁面的位置

location = /custom_403.html {
allow all;

root /usr/share/nginx/html;

}

}

這樣,當發生403錯誤時,使用者將會看到位於/usr/share/nginx/html/custom_403.html的自定義錯誤頁面,而不是預設的Nginx 403錯誤提示。

配置錯誤頁面

配置自定義錯誤頁面是提升使用者體驗和增強安全性的重要措施。下面將透過具體的Nginx配置示例來說明如何設定404、500等錯誤頁面,並確保這些頁面不會洩露過多的伺服器資訊。
首先,你需要編輯Nginx的配置檔案(通常是nginx.conf或位於sites-available目錄下的某個站點配置檔案)。以下是一個簡單的配置示例:

server {
listen

80

;

server_name example.com;
# 根目錄設定

root /

var

/www/html;

index index.html index.htm;
# 隱藏

Nginx

版本資訊

server_tokens off;
# 定義自定義錯誤頁面

error_page

404

/custom_404.html;

error_page

500502503504

/custom_50x.html;
# 自定義

404

錯誤頁面的位置

location = /custom_404.html {
root /usr/share/nginx/html;

internal;

}
# 自定義50x錯誤頁面的位置

location = /custom_50x.html {
root /usr/share/nginx/html;

internal;

}
# 其他location配置...

}

在這個例子中,我們使用了error_page指令來指定當發生404或500系列錯誤時應該顯示的頁面。internal;指示Nginx只在內部重定向到這個位置,不允許直接訪問這些錯誤頁面。
假設你正在運營一個線上商店,網站偶爾會因為各種原因出現臨時性的問題,比如資料庫連線失敗導致的500內部伺服器錯誤。為了確保即使在這種情況下也能提供良好的使用者體驗,你可以建立一個設計精美的500錯誤頁面,它不僅告訴使用者當前遇到了問題,還提供了幫助連結或者聯絡客服的方式。
同樣地,對於404錯誤,一個好的做法是提供一個搜尋框或者導航連結,讓使用者可以方便地找到他們可能感興趣的內容,而不是簡單地顯示“頁面未找到”。
例如,你的custom_404.html頁面可能包含如下內容:

<!

DOCTYPE

html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Page Not Found</title>

</head>

<body>

<h1>Oops! Page not found.</h1>

<p>We're sorry, but the page you were looking for doesn't exist.</p>

<form action="/search" method="get">

<input type="text" name="query" placeholder="Search...">

<button type="submit">Search</button>

</form>

<a href="/">Go back to homepage</a>

</body>

</html>

而custom_50x.html可能會這樣設計:

<!

DOCTYPE

html>

<

htmllang

=

"en"

>

<

head

>

<

metacharset

=

"UTF-8"

>

<

title

>Server Error</

title

>

</

head

>

<

body

>

<

h1

>Something went wrong!</

h1

>

<

p

>Our team has been notified and is working on fixing the issue as quickly as possible.</

p

>

<

ahref

=

"/"

>Return to homepage</

a

>

<

p

>Contact us if you need further assistance.</

p

>

</

body

>

</

html

>

啟用HTTPS

啟用HTTPS對於保護資料傳輸的安全性至關重要。這通常涉及到幾個步驟:獲取SSL證書、安裝SSL證書以及在Nginx配置中設定以支援HTTPS連線。下面,我將透過具體的程式碼示例和實際案例來詳細說明這個過程。
獲取並安裝SSL證書
首先,你需要從一個可信的證書頒發機構(CA)獲取SSL證書。你可以選擇付費的SSL證書提供商,如DigiCert、Comodo等,或者使用Let's Encrypt提供的免費SSL證書。
生成CSR檔案
在申請SSL證書之前,你需要生成一個證書籤名請求(CSR)。以下是使用OpenSSL工具生成CSR檔案的命令:

openssl req -

new

-newkey

rsa

:

2048

-nodes -out yourdomain.csr -keyout yourdomain.key

系統會提示你輸入一些資訊,例如國家、組織名稱、域名等。
提交CSR並下載證書
完成上述步驟後,提交生成的CSR給選定的CA,並按照其指示進行身份驗證。一旦驗證透過,你會收到一個或多個證書檔案,包括伺服器證書和中間證書。
在Nginx中啟用HTTPS
假設你已經獲取了SSL證書並且準備好了所有必要的檔案(如yourdomain.crt和yourdomain.key),接下來需要在Nginx配置中啟用HTTPS。
Nginx配置示例
以下是一個基本的Nginx配置示例,展示瞭如何設定HTTPS支援:

server {
listen

80

;

server_name yourdomain.com www.yourdomain.com;
# 將

HTTP

請求重定向到

HTTPS
return301https

:

//$host$request_uri;

}
server {
listen

443

ssl;

server_name yourdomain.com www.yourdomain.com;
ssl_certificate /path/to/yourdomain.crt;

ssl_certificate_key /path/to/yourdomain.key;

ssl_trusted_certificate /path/to/intermediate.crt;
ssl_protocols

TLSv1.2TLSv1.3

;

ssl_prefer_server_ciphers on;

ssl_ciphers

'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'

;
location / {
# 你的網站根目錄和其他配置

root /

var

/www/html;

index index.html index.htm;

}

}

在這個配置中,我們首先定義了一個監聽80埠的伺服器塊,用於處理HTTP請求並將它們重定向到HTTPS。然後,我們定義了另一個伺服器塊,它監聽443埠,並啟用了SSL/TLS加密。這裡指定了證書檔案的位置以及一些額外的安全引數。

應用內容安全策略(CSP)

內容安全策略(CSP)是一個額外的安全層,用於檢測並削弱某些特定型別的攻擊,包括跨站指令碼(XSS)和資料注入攻擊等。透過在Nginx配置中應用CSP,你可以指定哪些資源是允許載入的,從而防止潛在的惡意程式碼執行。
設定CSP的基本步驟
首先,你需要定義一個適合你網站需求的CSP策略。這通常涉及到指定哪些源可以載入指令碼、樣式、圖片等資源。然後,將這個策略新增到你的Nginx配置檔案中。
示例程式碼
假設你有一個簡單的部落格網站,並且希望確保所有的資源都來自相同的源(即self),除了圖片可以從任何地方載入外,其他資源都不允許內聯或使用eval()函式。以下是如何在Nginx中設定這樣一個CSP的例子:

server {
listen

80

;

server_name example.com;
# 其他配置...
add_header

Content

-

Security

-

Policy"default-src 'self'; img-src *; script-src 'self' 'unsafe-inline' 'unsafe-eval'"

;
# 其他location配置...

}

在這個例子中,我們設定了以下規則:
  • default-src 'self':預設情況下,只允許從當前域名載入資源。
  • img-src *:允許圖片從任何源載入。
  • script-src 'self' 'unsafe-inline' 'unsafe-eval':允許指令碼從當前域名載入,並允許內聯指令碼和eval()函式。然而,在實際生產環境中應儘量避免使用unsafe-inline和unsafe-eval,因為它們會增加XSS攻擊的風險。
假設一個線上銀行系統,它需要非常嚴格的安全措施來保護使用者的資料。在這種情況下,銀行可能會採取如下的CSP策略:

add_header

Content

-

Security

-

Policy"default-src 'self'; script-src 'self' https://trustedscripts.example.com; style-src 'self' https://trustedstyles.example.com; img-src 'self' data: https://trustedimages.example.com; connect-src 'self' https://api.example.com; object-src 'none'; frame-src 'none';"

;

這裡,我們做了如下限制:
  • 只允許從當前域載入所有型別的內容(default-src 'self')。
  • 指令碼只能從當前域和一個可信的第三方指令碼提供者載入(script-src 'self' https://trustedscripts.example.com )。
  • 樣式表也受到類似的限制(style-src 'self' https://trustedstyles.example.com)。
  • 圖片可以從當前域、data URI以及一個可信的圖片伺服器載入(img-src 'self' data: https://trustedimages.example.com)。
  • API請求只能傳送到當前域或一個可信的API端點(connect-src 'self' https://api.example.com)。
  • 禁止載入外掛內容(object-src 'none')以減少潛在的安全風險。
  • 不允許頁面被嵌入到任何iframe中,防止點選劫持攻擊(frame-src 'none')。
監控與調整
一旦部署了CSP,重要的是要監控其表現。透過使用report-uri指令,你可以讓瀏覽器向你指定的URL報告任何違反CSP的行為,這樣就可以及時發現並修復問題。例如:

add_header

Content

-

Security

-

Policy"default-src 'self'; report-uri /csp-report-endpoint"

;

這將指示瀏覽器將任何CSP違規報告發送到/csp-report-endpoint路徑上。定期審查這些報告有助於最佳化你的CSP策略,確保既不過於寬鬆也不過於嚴格。
請根據實際情況調整CSP策略,逐步實施新的限制,並測試對網站功能的影響,同時保持對新威脅的關注並適時更新策略。

設定正確的檔案許可權

設定正確的檔案許可權是確保Nginx服務安全執行的重要步驟。這涉及到配置檔案、日誌檔案以及網站根目錄下的檔案和目錄的許可權設定。以下是一些指導原則和具體的程式碼示例,用於幫助你正確地設定這些許可權。
檔案和目錄許可權的一般規則
  • 檔案許可權:通常推薦將檔案許可權設為644,這意味著所有者可以讀寫(rw-),而組使用者和其他人只能讀取(r–)。
  • 目錄許可權:目錄許可權通常設為755,允許所有者讀寫執行(rwx),組使用者和其他人只能讀取和執行(r-x)。
  • 所有者和組:所有者應設定為執行Nginx服務的非root使用者,例如nginx或www-data,具體取決於你的系統配置。
設定檔案和目錄許可權的命令
在Linux系統中,你可以使用chmod命令來修改檔案或目錄的許可權,使用chown命令來更改檔案或目錄的所有者和所屬組。
假設你有如下結構:

/

var

/www/html/ # 網站根目錄

/etc/nginx/nginx.conf #

Nginx

主配置檔案

/

var

/log/nginx/access.log # 訪問日誌檔案

你可以使用以下命令來設定許可權:

# 設定檔案許可權為

644

sudo chmod

644

/

var

/www/html/index.html

sudo chmod

644

/etc/nginx/nginx.conf

sudo chmod

644

/

var

/log/nginx/access.log
# 設定目錄許可權為

755

sudo chmod

755

/

var

/www/html/

更改檔案所有者和組
如果你需要更改檔案的所有者和組,可以使用chown命令:

# 假設nginx執行使用者為nginx,組也為nginx

sudo chown

nginx

:nginx /

var

/www/html/index.html

sudo chown

root

:nginx /etc/nginx/nginx.conf # 主配置檔案可能由root擁有,但屬於nginx組

sudo chown

nginx

:nginx /

var

/log/nginx/access.log

假設正在維護一個基於Nginx的WordPress部落格。為了確保安全性,你需要正確設定檔案和目錄的許可權。
首先,確定Nginx是以哪個使用者執行的。可以透過檢視Nginx配置檔案中的user指令得知,通常是nginx或www-data。

grep

'user'

/etc/nginx/nginx.conf

然後,應用適當的許可權設定:

# 設定

WordPress

安裝目錄下的檔案和目錄許可權

find /

var

/www/html -type f -exec chmod

644

{

} \;

find /

var

/www/html -type d -exec chmod

755

{

} \;
# 更改所有權

sudo chown -R

nginx

:nginx /

var

/www/html
# 設定

Nginx

日誌檔案許可權

sudo chmod

640

/

var

/log/nginx

/*.log

sudo chown nginx:nginx /var/log/nginx/*.log

在這個例子中,我們對WordPress安裝目錄下的所有檔案設定了644許可權,對目錄設定了755許可權,並且將所有權更改為Nginx使用者。對於日誌檔案,我們採用了稍微嚴格的許可權640,以限制訪問。

配置安全Headers

新增安全相關的HTTP響應頭,可以有效防禦常見的Web攻擊:

# 防止點選劫持

add_header X-

Frame

-

OptionsSAMEORIGIN

;

add_header

Content

-

Security

-

Policy"frame-ancestors 'self';"

;
# 強化

XSS

防護

# 注意:根據實際情況決定是否保留X-

XSS

-

Protection

,因為現代瀏覽器支援程度不同

add_header X-

XSS

-

Protection"1; mode=block"

;
# 防止

MIME

型別混淆攻擊

add_header X-

Content

-

Type

-

Options

nosniff;
# 增強隱私保護

add_header

Referrer

-

Policy"strict-origin-when-cross-origin"

;
# 強化的

CSP

策略

add_header

Content

-

Security

-

Policy"default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'self'; upgrade-insecure-requests;"

;

限制連線數

為了防止DoS(拒絕服務)攻擊,可以透過限制單個IP的連線數和請求頻率來減少惡意流量對伺服器的影響。
Nginx提供了兩個模組來進行這種型別的限制:ngx_http_limit_conn_module 和 ngx_http_limit_req_module。前者用於限制連線數,後者用於限制請求頻率。
以下是一個簡單的Nginx配置片段,用於限制每個客戶端IP的最大併發連線數為10:

http {
# 定義一個名為addr的共享記憶體區域,大小為10MB,鍵值為$binary_remote_addr

limit_conn_zone $binary_remote_addr zone=

addr

:10m;
server {
location / {
# 每個

IP

地址最多允許

10

個併發連線

limit_conn addr

10

;

}

}

}

下面是一個限制請求頻率的例子,它限制了每個客戶端IP每秒最多發起20次請求,並且設定了突發緩衝區為5次請求:

http {
# 定義一個名為req_zone的共享記憶體區域,大小為10MB,鍵值為$binary_remote_addr,速率限制為每秒

20

次請求

limit_req_zone $binary_remote_addr zone=

req_zone

:10m rate=20r/s;
server {
location / {
# 應用名為req_zone的限制規則,允許突發請求量為

5

limit_req zone=req_zone burst=

5

nodelay;

}

}

}

配置白名單

配置IP白名單是一種有效的安全措施,特別是對於管理後臺等敏感區域。透過只允許特定的、受信任的IP地址訪問這些區域,可以大大減少未經授權訪問的風險。
如果你使用Nginx作為你的Web伺服器,可以透過以下方式限制對某些路徑的訪問僅限於指定的IP地址:

server {
listen

80

;

server_name yourdomain.com;
location /admin/ {
allow

192.168.1.1

; # 允許的

IP

地址

deny all; # 拒絕所有其他

IP

地址

proxy_pass

http

:

//backend;

}

}

上述配置會使得只有來自192.168.1.1的請求能夠訪問/admin/路徑下的資源,而所有其他IP地址的請求都將被拒絕。

最佳化SSL配置

最佳化SSL配置是確保網站安全性和效能的關鍵步驟。以下是一些具體的建議和程式碼示例,用於增強SSL/TLS的安全性:
停用舊版本的SSL/TLS協議(如SSLv3, TLS 1.0, 和 TLS 1.1),因為它們存在已知的安全漏洞。
在Nginx中,你可以透過以下配置來實現:

server {
listen

443

ssl http2;

ssl_protocols

TLSv1.2TLSv1.3

;
# 其他配置...

}

選擇強加密套件以保護資料傳輸。避免使用含有MD5、RC4等不安全演算法的套件。

server {
listen

443

ssl http2;

ssl_protocols

TLSv1.2TLSv1.3

;

ssl_ciphers

'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256'

;

ssl_prefer_server_ciphers on;
# 其他配置...

}

線上證書狀態協議(OCSP)Stapling允許伺服器預先獲取證書吊銷狀態,並將其提供給客戶端,從而減少客戶端查詢時間。

server {
listen

443

ssl http2;

ssl_stapling on;

ssl_stapling_verify on;

resolver

8.8.8.88.8.4.4

valid=300s;

resolver_timeout 10s;
# 其他配置...

}

HSTS告訴瀏覽器總是使用HTTPS訪問你的站點,即使使用者嘗試透過HTTP訪問。

server {
listen

443

ssl http2;

add_header

Strict

-

Transport

-

Security"max-age=31536000; includeSubDomains"

always;
# 其他配置...

}

會話票據可以加快後續連線的速度,因為它們允許跳過完整的TLS握手過程。

server {
listen

443

ssl http2;

ssl_session_tickets on;
# 其他配置...

}

檔案上傳安全

為了確保Nginx配置能夠防止透過上傳大檔案耗盡伺服器資源,並且保證上傳目錄的許可權配置正確,我們需要從幾個方面入手:限制上傳檔案大小、設定正確的目錄許可權以及確保上傳的檔案不會被執行。
在Nginx中,我們可以透過client_max_body_size指令來控制允許客戶端上傳的最大檔案大小。這個指令可以在http, server, 或者 location塊中進行設定。以下是一個示例配置:

http {
# 其他配置...
client_max_body_size 10m; # 設定最大上傳檔案大小為10MB
server {
listen

80

;

server_name example.com;
location /upload {
# 將請求轉發給後端處理檔案上傳的應用伺服器

proxy_pass

http

:

//backend_server;

# 確保這裡也設定了client_max_body_size以覆蓋預設值

client_max_body_size 10m;

}
# 其他配置...

}

}

上述配置將所有上傳請求的最大檔案大小限制為10MB。如果使用者嘗試上傳超過此大小的檔案,Nginx會返回413 (Request Entity Too Large)錯誤。
為了保護上傳的檔案不被惡意執行,應該對上傳目錄設定適當的許可權,並禁止該目錄下的指令碼執行。以下是如何在Nginx配置中做到這一點的一個例子:

server {
listen

80

;

server_name example.com;
location /uploads {
alias /path/to/uploads; # 指定上傳目錄的實際路徑
# 防止任何

PHP

或類似指令碼被執行

location ~* \.(php|pl|py|jsp|asp|sh|cgi)$ {
deny all; # 對匹配這些副檔名的檔案返回

403Forbidden

}

}

}

在這個配置中,任何試圖訪問具有.php, .pl, .py, .jsp, .asp, .sh, 或 .cgi副檔名的檔案都會被拒絕訪問,即使這些檔案位於/uploads目錄下。這可以有效避免由於檔案上傳而導致的安全風險。

防止常見攻擊

防止DDoS攻擊

http {
# 設定請求速率限制

limit_req_zone $binary_remote_addr zone=

one

:10m rate=30r/m;
server {
location /login.html {
# 應用請求速率限制

limit_req zone=one;

}
# 設定併發連線數限制

limit_conn_zone $binary_remote_addr zone=

addr

:10m;
location /shopping/ {
limit_conn addr

10

; # 每個

IP

最多允許

10

個併發連線

}
# 關閉慢連線

client_body_timeout 5s;

client_header_timeout 5s;

}

}

透過這種方式,可以有效地減少惡意使用者發起的大量請求對伺服器造成的壓力。

防止SQL注入

雖然SQL注入主要是應用程式層面的問題,但是Nginx也可以透過過濾特定的查詢字串來輔助防護:

location / {
# 檢查

URL

中是否包含特殊字元

# 如果包含分號、單引號、尖括號等字元,返回

444

狀態碼

#

444

Nginx

特殊狀態碼,表示關閉連線而不傳送響應頭

if

($request_uri ~* [;

'<>] ) {
return 444;

}

# 檢查查詢字串中的特殊字元

if ($args ~* [;'

<>] ) {

return444

; }

# 保護敏感

URI

location ~*

/(admin|backup|config|db|src)/

{
deny all;

}}

這會阻止包含有潛在危險字元的請求到達後端服務。

防止跨站指令碼攻擊(XSS)

可以透過設定HTTP響應頭來增加安全性:

add_header X-

XSS

-

Protection"1; mode=block"

;

這個頭部告訴瀏覽器啟用XSS過濾,並在檢測到XSS攻擊時阻止渲染頁面。

點選劫持(Clickjacking)防禦

透過設定X-Frame-Options響應頭來防止點選劫持:

add_header X-

Frame

-

OptionsSAMEORIGIN

;

這樣可以確保你的網站只能被嵌入到相同域名下的iframe中,增加了額外的安全層

防止目錄遍歷

防止目錄遍歷攻擊是Nginx配置中的一個重要方面,這種攻擊允許攻擊者透過構造特殊的URL訪問Web伺服器上的未授權檔案或目錄。
停用目錄列表(autoindex off)
預設情況下,Nginx不會列出目錄內容,但是如果你不小心啟用了autoindex on,則可能暴露敏感資訊。確保在所有相關位置塊中停用目錄列表:

server {
listen

80

;

server_name example.com;
location / {
autoindex off; # 確保目錄瀏覽被關閉

root /

var

/www/html;

}

}

使用正則表示式阻止包含../的請求
你可以使用正則表示式匹配並拒絕任何試圖進行目錄遍歷的請求:

location ~

/\.\./

{
deny all; # 拒絕所有包含“../”的請求

}

正確配置別名(alias)和根路徑(root)
當使用alias時,確保正確地新增斜槓以避免潛在的目錄遍歷漏洞:

location /

static

/ {

# 注意這裡的斜槓

alias /

var

/www/static_files/; # 確保這裡也有斜槓

}

啟用基於IP的訪問控制
你可以限制對特定目錄的訪問,只允許某些IP地址訪問:

location /admin/ {
allow

192.168.1.100

; # 允許特定

IP

訪問

deny all; # 拒絕其他所有

IP

訪問

}

URL解碼過濾
雖然Nginx預設會對URL進行解碼,但你仍然可以新增額外的安全層來確保路徑中的特殊字元不會導致問題:
if

($uri ~*

"\.\."

) {

return403

; # 如果

URI

包含“..”,返回

403Forbidden

}

假設你有一個網站託管在Nginx上,並且你希望保護你的伺服器不受目錄遍歷攻擊的影響。你的網站有一個公開可訪問的靜態資源目錄/static/images/,以及一個後臺管理面板/admin/。為了防止目錄遍歷攻擊,你可以採取以下措施:
對於靜態資源目錄,確保autoindex被關閉,並且正確配置了別名:

location /

static

/ {
alias /

var

/www/static_files/;

autoindex off; # 確保目錄瀏覽被關閉

}

對於後臺管理面板,你可以設定基於IP的訪問控制:

location /admin/ {
allow

192.168.1.100

; # 只允許特定

IP

訪問

deny all; # 拒絕其他所有

IP

訪問

}

全域性防護,在整個伺服器配置中新增針對目錄遍歷的防護規則:

server {
listen

80

;

server_name yoursite.com;
# 拒絕不含斜槓的父級目錄嘗試

location ~

/\.\./

{
deny all;

}
# 正常的站點配置...

}

這些配置能夠幫助你構建一個更加安全的環境,有效地防止目錄遍歷攻擊。

日誌安全

在Nginx中,透過配置訪問日誌和錯誤日誌,可以有效地記錄使用者行為和系統狀態,這對於安全分析至關重要。下面我將提供具體的程式碼示例來說明如何配置這些日誌。
為了詳細記錄訪問資訊,你可以自定義log_format來包含儘可能多的相關欄位,並使用access_log指令指定日誌檔案的位置以及使用的格式。以下是一個詳細的訪問日誌配置示例:

http {
# 定義一個名為

'main'

的日誌格式,包含多種有用的資訊

log_format main

'$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$http_x_forwarded_for" "$msec" '
'"$connection" "$connection_requests" '
'"$upstream_addr" "$upstream_response_time" '
'"$request_time" "$gzip_ratio"'

;
# 指定使用

'main'

格式記錄訪問日誌到特定位置

access_log /

var

/log/nginx/access.log main buffer=32k flush=1m;
server {
listen

80

;

server_name example.com;
location / {
root /

var

/www/html;

index index.html;

}

}

}

在這個例子中,我們定義了一個叫做main的複雜日誌格式,它包括了客戶端IP地址、請求時間、請求詳情、響應狀態碼、傳送給客戶端的資料大小、來源頁面、使用者代理、X-Forwarded-For頭(如果有的話)、毫秒級的時間戳、連線序列號、透過該連線發出的請求數量、上游伺服器地址、上游響應時間、整個請求處理時間和壓縮率等。
對於錯誤日誌,你需要根據實際情況選擇合適的日誌級別。例如,在生產環境中,你可能希望設定為warn或error級別,以減少不必要的資訊並專注於實際問題。以下是配置錯誤日誌級別的示例:

http {
# 設定全域性錯誤日誌級別為warn

error_log /

var

/log/nginx/error.log warn;
server {
listen

80

;

server_name example.com;
location / {
root /

var

/www/html;

index index.html;

}
# 可以為特定虛擬主機設定不同的錯誤日誌級別

error_log /

var

/log/nginx/example.error.log error;

}

}

在這個配置中,全域性錯誤日誌被設定為warn級別,這意味著只有警告及以上級別的訊息會被記錄。而對於特定的虛擬主機(如example.com),錯誤日誌被設定為更嚴格的error級別,這樣可以集中關注那些真正可能導致服務中斷的問題。

其他安全措施

禁止執行指令碼

在Nginx中,你可以透過配置location塊來限制特定目錄下的指令碼執行許可權。下面是一個示例,展示瞭如何阻止在/uploads目錄下執行PHP指令碼:

server {
listen

80

;

server_name example.com;
location /uploads/ {
# 禁止訪問任何php指令碼

location ~* \.php$ {
deny all;

}
# 或者使用以下方式直接返回

403

錯誤給所有嘗試執行php指令碼的請求

# location ~* \.php$ {
#

return403

;

# }
# 其他靜態資源處理規則...

}
# 其他server配置...

}

另一種方法是使用偽靜態規則來實現同樣的目的,這在寶塔面板等管理工具中較為常見:

location ~

/(uploads)/

.*\.(php|php5)$ {
deny all; # 返回

403Forbidden

}

配置超時時間

設定合理的超時引數是防禦慢速攻擊(Slow HTTP DoS Attack)的關鍵措施之一。慢速攻擊利用了HTTP協議的特性,透過緩慢地傳送請求或響應資料來消耗伺服器資源,導致伺服器無法處理正常請求。以下是針對不同層面配置超時時間以防止此類攻擊的方法和示例。
在Nginx中,可以透過調整以下引數來防禦慢速攻擊:
  • client_body_timeout: 設定客戶端與伺服器建立連線後傳送request body的超時時間。
  • client_header_timeout: 設定客戶端向伺服器傳送一個完整的request header的超時時間。
  • send_timeout: 設定服務端向客戶端傳輸資料的超時時間。
  • keepalive_timeout: 設定每個TCP連線最多可以保持多長時間。
  • client_max_body_size: 限制客戶端能夠上傳的最大檔案大小。
  • limit_rate: 限制連線速率,防止客戶端過快地使用頻寬。
下面是一個基本的Nginx配置示例:

http {
# 設定客戶端主體讀取超時時間為

10

client_body_timeout 10s;
# 設定客戶端頭部讀取超時時間為

10

client_header_timeout 10s;
# 設定傳送給客戶端的資料超時時間為

10

send_timeout 10s;
# 設定

Keep

-

Alive

連線的超時時間為

60

keepalive_timeout 60s;
# 設定允許客戶端上傳的最大檔案大小為1M

client_max_body_size 1M;
# 限制每秒傳輸的資料量為100KB

limit_rate 100k;
server {
listen

80

;

server_name example.com;
location / {
# 其他配置...

}

}

}

總結

綜上所述,透過停用不必要的HTTP方法、隱藏版本資訊、設定緩衝區大小限制、遮蔽不受歡迎的爬蟲、限制IP訪問、控制併發連線數及速度、調整超時時間,並採用HTTPS協議與最佳化SSL/TLS策略等措施,可以顯著增強Nginx的安全性。同時,配置安全頭部欄位如Content Security Policy (CSP)有助於防禦跨站指令碼攻擊和其他程式碼注入威脅。確保Nginx及其模組保持最新,遵循最小許可權原則執行服務,並定期審計系統日誌,對於構建堅固的安全防線至關重要。實施這些策略不僅能夠有效抵禦已知威脅,也為應對未知挑戰提供了有力保障。
連結:https://developer.aliyun.com/article/1650977?spm=5176.21213303.J_v8LsmxMG6alneH-O7TCPa.5.4a5f2f3dvsDvvQ&scm=20140722.S_community@@%E6%96%87%E7%AB%A0@@1650977._.ID_1650977-RL_nginx-LOC_search~UND~community~UND~item-OR_ser-PAR1_2150422117395193796102487ec1a7-V_4-P0_4-P1_0
                                                              (版權歸原作者所有,侵刪)


相關文章