跳至内容
liuzhen932 的小窝
返回

入门网站搭建六年多了,分享下我的 Nginx (Openresty) 安全规则

0x00 前情提要

自从上次开源 我的 Cloudflare WAF 规则 后,文章收到的反响不错,有读者反馈希望改写成在 Nginx 上可用的规则,所以我决定开源我的 Nginx / OpenResty 规则。

需要说明的是,我的 Nginx 配置并非一蹴而就的完美方案,而是一套经过多次迭代、结合业务场景和实战经验形成的动态防御体系。核心逻辑始终围绕三个关键目标:主动防御、最小化误拦截、以及性能与成本的平衡。

0x01 开源内容

# 敏感路径
map $request_uri $block_sensitive_path {
    default 0;
    "~* ^(/\.git|/\.env|/\.bashrc|/\.bash_history|/config\.php|/\.htaccess|/\.htpasswd|/web\.config|/composer\.(json|lock)|/package(-lock)?\.json|/yarn\.lock|/\.dockerignore|/Dockerfile|/docker-compose.*\.yml|/\.ssh/|/private/|/backup|/dump|/\.DS_Store|/thumbs\.db|/\.vscode/|/\.idea/|/node_modules/|/vendor/|/logs?/|/tmp/|/temp/|/cache/|/\.cache/|/wp-config\.php|/wp-admin/install\.php|/phpinfo\.php|/info\.php|/test\.php|/readme\.txt|/README\.md|/CHANGELOG|/LICENSE|/wp-admin/admin-ajax\.php|/xmlrpc\.php|/wp-login\.php|/wp-includes/wlwmanifest\.xml|/wp-json/wp/v2/users|/phpmyadmin/|/server-info|/server-status)" 1;
}

# 危险扩展
map $request_uri $block_dangerous_ext {
    default 0;
    "~* \.(php\.jpg|php\.png|php\.gif|phtml|php[3457]|asp[x]?|jsp[x]?|exe|bat|cmd|sh|pl|py|rb|cgi)$" 1;
}

# User-Agent
map $http_user_agent $block_bad_ua {
    default 0;
#    "~*(apache|hey|libweb|libwww|masscan|nmap|Page.*Analyzer|PyCurl|python|WPScan|wrk|zmap|lient.*ttp|fuck|netcraft|GPTBot|Google-Extended|CCBot|Omgilibot|PerplexityBot|anthropic-ai|ChatGPT-User|cohere-ai|FacebookBot|Applebot-Extended|OpenAI|DeepSeekBot|SentryBot|Claude-Web|YandexBot|Sogou|360Spider|twitterbot|facebookexternalhit|LinkedInBot|Slackbot|DiscordBot|python-requests|nikto|sqlmap|pangolin|hydra)" 1;
    "Mozilla/5.0" 1;
    "Mozilla/5.0 (compatible)" 1;
    "" 1;
    "undefined" 1;
}

# 特殊 Header
map $http_checkmode $block_itdog {
    "" 0;
    default 1;
}

map $http_zlm_hcm $block_zlm {
    "" 0;
    default 1;
}

map $http_user_agent $block_boce {
    ~*fromBoce 1;
    default 0;
}

map $http_user_agent $block_aliyun {
    ~*chrome/57 1;
    default 0;
}

map $http_user_agent $block_tance {
    ~*guantuservice 1;
    default 0;
}

map $http_user_agent $block_tcptest {
    ~*chrome/94 1;
    default 0;
}

map $http_cf_worker $block_cf_worker {
    "" 0;
    default 1;
}

################################################

# 1. 非标准 UA 格式(非以 "Mozilla/5.0 (" 开头)
map $http_user_agent $bad_ua_format {
    "~*^Mozilla/5\.0\s*\(" 0;
    default 1;
}

# 2. Accept-Encoding 为空 或 仅 identity
map $http_accept_encoding $bad_encoding {
    "" 1;
    "~*\bidentity\b" 1;
    default 0;
}

# 3. Accept-Language 为空
map $http_accept_language $empty_lang {
    "" 1;
    default 0;
}

# 4. 非浏览器却带 X-Requested-With: XMLHttpRequest
map "$http_user_agent|$http_x_requested_with" $fake_ajax {
    "~*(?i)^(?!.*firefox|.*chrome|.*safari|.*edge|.*opera).*\|\s*XMLHttpRequest\s*$" 1;
    default 0;
}

# 5. 非 CDN 却带 X-Cache / CDN-LoopCount
map $http_x_cache $has_x_cache { "" 0; default 1; }
map $http_cdn_loopcount $has_cdn_loop { "" 0; default 1; }

# 6. Trailer 头(非 Firefox)
map "$http_user_agent|$http_trailer" $bad_trailer {
    "~*(?i)trailer.*$" 0; # trailer 为空时不触发
    "~*(?i)^(?!.*firefox).*\|.+" 1;
    default 0;
}

# 7. X-Frame-Options 不应由客户端发送
map $http_x_frame_options $client_sent_xfo { "" 0; default 1; }

# 8. Accept-Charset 不应由现代浏览器以外的客户端发送
map $http_accept_charset $has_accept_charset { "" 0; default 1; }

# 9. Firefox 不应带 Sec-CH-UA
map "$http_user_agent|$http_sec_ch_ua" $firefox_with_sec_ch_ua {
    "~*(?i)firefox.*\|.+" 1;
    default 0;
}


# 是否应返回 444
map "$block_sensitive_path$block_dangerous_ext$block_bad_ua$block_itdog$block_zlm$block_boce$block_aliyun$block_tance$block_tcptest" $should_block_444 {
    ~1 1;
    default 0;
}

# 是否应返回 418

map "$block_cf_worker$bad_ua_format$bad_encoding$empty_lang$fake_ajax$has_x_cache$has_cdn_loop$bad_trailer$client_sent_xfo$has_accept_charset$firefox_with_sec_ch_ua" $should_block_418 {
    ~1 1;
    default 0;
}

0x02 屏蔽拨测

这部分的系列规则用于屏蔽诸如 ITDOG / 炸了么 / 拨测网 / 探测网 / 测速网 等批量请求网站,直接返回 444 关闭连接。

# Netcraft
if ($http_user_agent ~* "netcraft") {
    return 444;
}

# ITDOG
if ($http_checkmode) {
    return 444;
}

# 炸了么
if ($http_zlm_hcm) {
    return 444;
}

# Boce.com
if ($http_user_agent ~* "fromBoce") {
    return 444;
}

# 阿里云拨测
if ($http_user_agent ~* "chrome/57") {
        return 444;
}

# tance.cc
if ($http_user_agent ~* "guantuservice") {
        return 444;
}

# tcptest.cn
if ($http_user_agent ~* "chrome/94") {
        return 444;
}

# Cloudflare Workers
if ($http_cf_worker) {
    return 418;
}

0x03 结语

本文分享了我经过实战验证的 Nginx WAF 分层防御配置方案,核心围绕主动防御、最小化误拦截、性能与成本平衡三大目标。通过分层策略实现动态防御。如有任何问题欢迎留言反馈。


分享这篇文章:

上一篇
ICMP 互联网控制消息协议 Type 和 Code 详解
下一篇
Java 类文件版本标识对照表

人机验证:请刷新页面以加载评论区