Nginx 基本配置语法与防护

Nginx 是一款高性能的 Web 服务器和反向代理服务器,配置文件层次分明,灵活度高。本文将简要介绍 Nginx 的配置结构。

基本结构

Nginx 的配置文件一般位于 /etc/nginx/nginx.conf,其层次关系可概括为一棵「配置语法树」:

1
2
3
4
5
6
7
main                # 全局区,影响所有 worker
├─ events { } # 事件驱动模型配置
└─ http { } # HTTP 层公共配置
├─ upstream { } # 后端服务器池(反向代理/负载均衡)
├─ server { } # 虚拟主机(按域名/端口区分站点)
│ └─ location { } # URI/路径匹配规则
└─ include /etc/nginx/conf.d/*.conf;
  • main 区(全局区)

定义用户、worker 数量、pid 文件位置

例如:

1
2
3
user www-data;
worker_processes auto;
pid /run/nginx.pid;
  • events 区(事件驱动模型)

设置连接处理模型、worker 最大连接数

例如:

1
2
3
events {
worker_connections 1024;
}
  • http 区(HTTP 层)

管理所有 HTTP 相关配置
可定义:
server(虚拟主机)主机可以配置多个
upstream(负载均衡)

公共的 log_format、gzip、mime.types

  • server 区(虚拟主机)

区分不同域名或端口的站点

常见配置:

1
2
3
4
5
6
server {
listen 443 ssl;
server_name www.example.com;
root /var/www/example;
index index.html;
}
  • location 区(请求路由规则)

精确/正则匹配 URL 路径,配置在server 区内

示例:

1
2
3
4
5
6
7
location /api {
proxy_pass http://127.0.0.1:5000;
}

location ~* \.(jpg|png|gif)$ {
root /var/www/static;
}

防护应对记录

在实际运维中,网站可能频繁被异常爬虫访问,造成带宽占用、日志刷屏,甚至影响正常访问。小站所有资源都是开源的,暂时没针对禁止此类访问处理。前不久某天,在日志中看到有异常访问,爬取了.git文件,可能会导致一些影响,增加了以下配置。

  • 敏感目录(如.git)
    日志如下:

创建 /etc/nginx/snippets/deny.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# /etc/nginx/snippets/deny.conf
location ~ /\.git {
deny all;
return 403;
}

location ~ /\.(svn|hg|bzr|DS_Store) {
deny all;
return 403;
}

location ~* \.(bak|backup|swp|sql|sqlite|log|conf|ini|env|old|zip|tar|gz)$ {
deny all;
return 403;
}

在server 区域中添加

1
2
include /etc/nginx/snippets/deny.conf;

  • 拦截恶意扫描工具

日志如下:

可以利用 User-Agent 过滤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 异常请求行拦截
map $request_method $bad_method {
default 0;
~^(GET|POST|HEAD|PUT|DELETE|PATCH|OPTIONS)$ 0;
~.* 1;
}

# 扫描路径黑名单(正则,大小写不敏感)

map $uri $scan_path {
default 0;
~*"/(tesla|xbrain|fork|ez|goat|abcd|we|va|des|gif|inc|hook|ext|jquery|file\d*|wp-filemanager|xmlrpc\.php|wp-config\.php|phpmyadmin|\.env)$" 1;
}

# zgrab 拦截
map $http_user_agent $block_ua {
default 0;
~*zgrab 1;
}


# server {}区添加
if ($block_ua) { return 403; }
if ($bad_method) { return 405; }
if ($scan_path) {
access_log off;# 增加日志优化
log_not_found off;
return 403; }

  • 防止爬虫访问
    日志一般有“Spider”“bot”字样
    1
    2
    3
    4
    5
    6
    7
    8
    # 爬虫类型可以通过日志查看 例如
    map $http_user_agent $badbot {
    default 0;
    ~*(Baiduspider|360Spider|Sogou) 1;
    }

    # server {}区添加
    if ($badbot) { return 403; }
    因为nginx配置会直接访问conf.d目录下的配置文件,可以编辑成一个maps.conf
    如/etc/nginx/conf.d/maps.conf,这样就更方便维护
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 常见拦截
# 1. 只允许常见 HTTP 方法
map $request_method $bad_method {
default 1;
~^(GET|POST|HEAD|PUT|DELETE|PATCH|OPTIONS)$ 0;
}

# 2. 扫描路径黑名单
map $uri $scan_path {
default 0;
~*"/(tesla|xbrain|fork|ez|goat|abcd|we|va|des|gif|inc|hook|ext|jquery|file\d*|wp-filemanager|xmlrpc\.php|wp-config\.php|phpmyadmin|\.env)$" 1;
}

# 3. UA 黑名单(例如 zgrab 扫描器)
map $http_user_agent $block_ua {
default 0;
~*zgrab 1;
}

而在之前创建的deny.conf文件中添加以下内容:

1
2
3
4
if ($block_ua)   { return 403; }
if ($bad_method) { return 405; }
if ($scan_path) { return 403; }