前言
在高并发、大流量的互联网时代,Web服务器的性能和安全性直接关系到用户体验和业务稳定性。Nginx作为高性能Web服务器的代表,通过合理的优化配置可以发挥出极致性能,同时通过完善的安全配置可以有效抵御各种网络攻击。
本文将深入探讨Nginx的性能优化和安全配置,从内核参数调整到应用层优化,从基础安全防护到高级安全策略,帮助你打造一个既高性能又安全的Web服务器环境。
一、Nginx性能优化详解
1.1 工作进程优化
工作进程数配置
# =============================================
# 工作进程优化配置
# =============================================
# 工作进程数设置
# auto:自动设置为CPU核心数
# 生产环境建议设置为CPU核心数或核心数x2
worker_processes auto;
# 工作进程CPU亲和性绑定
# auto:自动绑定CPU核心,提高缓存命中率
# 手动绑定示例:worker_cpu_affinity 0001 0010 0100 1000;
worker_cpu_affinity auto;
# 工作进程优先级设置
# 范围:-20到19,数值越低优先级越高
# worker_priority -5;
# 工作进程的最大文件描述符数量
# 建议设置为65535或更高
worker_rlimit_nofile 65535;
# 工作进程信号处理
worker_shutdown_timeout 10s;
配置说明:
worker_processes auto
:自动根据CPU核心数设置工作进程数worker_cpu_affinity auto
:自动将工作进程绑定到特定CPU核心worker_rlimit_nofile
:限制单个工作进程能打开的最大文件数
工作进程优化建议
CPU核心数判断:
# 查看CPU核心数
nproc
# 或
cat /proc/cpuinfo | grep processor | wc -l
# 查看CPU信息
lscpu
优化策略:
- CPU密集型应用:
worker_processes
设置为CPU核心数 - I/O密集型应用:
worker_processes
设置为CPU核心数×2 - 混合型应用:
worker_processes
设置为CPU核心数×1.5
1.2 事件模型优化
事件模型配置
# =============================================
# 事件模型优化配置
# =============================================
events {
# 单个工作进程允许的最大连接数
# 理论最大值 = worker_processes * worker_connections
# 建议设置为65535
worker_connections 65535;
# 事件驱动模型选择
# Linux推荐使用epoll
# FreeBSD推荐使用kqueue
# Solaris推荐使用eventport
use epoll;
# 是否允许同时接受多个连接
# 提高连接处理效率,建议开启
multi_accept on;
# 工作进程是否可以同时接受多个连接
# 提高并发处理能力
accept_mutex on;
# 接受连接的超时时间
accept_mutex_delay 500ms;
# 是否使用异步文件I/O
# 需要编译时启用 --with-file-aio
aio on;
# 是否使用sendfile系统调用
# 高效传输文件,建议开启
sendfile on;
# 是否使用TCP_NOPUSH套接字选项
# 在sendfile开启时有效,减少网络包数量
tcp_nopush on;
# 是否使用TCP_NODELAY套接字选项
# 禁用Nagle算法,减少网络延迟
tcp_nodelay on;
# 连接超时时间
# 单位:秒
keepalive_timeout 65;
# 单个连接的最大请求数
keepalive_requests 1000;
# 隐藏Nginx版本信息
server_tokens off;
}
事件模型说明:
epoll
:Linux下最高效的事件模型,支持大量连接kqueue
:FreeBSD下的事件模型,性能优秀eventport
:Solaris下的事件模型select
:通用事件模型,性能较差
事件模型选择建议
# 检查系统支持的事件模型
nginx -V 2>&1 | grep -o -- '--with-.*_module'
# 查看系统信息
uname -a
cat /etc/os-release
不同系统的推荐配置:
- Linux系统:
use epoll;
- FreeBSD系统:
use kqueue;
- Solaris系统:
use eventport;
- 通用配置:不设置,让Nginx自动选择
1.3 连接优化
连接参数配置
# =============================================
# 连接优化配置
# =============================================
http {
# =============================================
# 基本连接优化
# =============================================
# 客户端请求头缓冲区大小
client_header_buffer_size 4k;
# 大客户端请求头缓冲区数量和大小
large_client_header_buffers 8 4k;
# 客户端请求体缓冲区大小
client_body_buffer_size 128k;
# 客户端请求体最大大小
client_max_body_size 50m;
# 客户端连接超时时间
client_header_timeout 30s;
client_body_timeout 30s;
# 发送响应超时时间
send_timeout 30s;
# 保持连接超时时间
keepalive_timeout 65s;
# 单个长连接的最大请求数
keepalive_requests 1000;
# 重置超时连接
reset_timedout_connection on;
# =============================================
# 上游服务器连接优化
# =============================================
# 上游服务器连接超时
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# FastCGI连接超时
fastcgi_connect_timeout 60s;
fastcgi_send_timeout 60s;
fastcgi_read_timeout 60s;
# uWSGI连接超时
uwsgi_connect_timeout 60s;
uwsgi_send_timeout 60s;
uwsgi_read_timeout 60s;
# SCGI连接超时
scgi_connect_timeout 60s;
scgi_send_timeout 60s;
scgi_read_timeout 60s;
# =============================================
# 内存优化
# =============================================
# 输出缓冲区大小
output_buffers 2 32k;
# 推迟发送响应头
postpone_output 1460;
# 限制请求处理速率
limit_rate 1024k;
limit_rate_after 500k;
}
连接优化说明:
client_header_buffer_size
:客户端请求头缓冲区大小client_body_buffer_size
:客户端请求体缓冲区大小client_max_body_size
:客户端请求体最大大小keepalive_timeout
:长连接超时时间reset_timedout_connection
:重置超时连接
1.4 缓存优化
文件缓存配置
# =============================================
# 文件缓存优化配置
# =============================================
http {
# =============================================
# 文件缓存配置
# =============================================
# 开启文件缓存
open_file_cache max=100000 inactive=20s;
# 文件缓存有效时间
open_file_cache_valid 30s;
# 文件缓存最小使用次数
open_file_cache_min_uses 2;
# 是否缓存文件错误信息
open_file_cache_errors on;
# =============================================
# 代理缓存配置
# =============================================
# 代理缓存路径配置
proxy_cache_path /usr/local/nginx/proxy_cache
levels=1:2
keys_zone=proxy_cache:10m
inactive=60m
max_size=10g
use_temp_path=off;
# 代理缓存临时文件路径
proxy_temp_path /usr/local/nginx/proxy_temp;
# 代理缓存级别
proxy_cache_levels 1:2;
# 代理缓存键
proxy_cache_key $scheme$request_method$host$request_uri;
# 代理缓存有效期
proxy_cache_valid 200 302 10m;
proxy_cache_valid 301 1h;
proxy_cache_valid 404 1m;
proxy_cache_valid 500 502 503 504 0s;
# 代理缓存使用策略
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
# 代理缓存锁定
proxy_cache_lock on;
proxy_cache_lock_timeout 5s;
# 代理缓存绕过
proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment;
proxy_no_cache $cookie_nocache $arg_nocache $arg_comment;
# =============================================
# FastCGI缓存配置
# =============================================
# FastCGI缓存路径
fastcgi_cache_path /usr/local/nginx/fastcgi_cache
levels=1:2
keys_zone=fastcgi_cache:10m
inactive=60m
max_size=5g
use_temp_path=off;
# FastCGI缓存键
fastcgi_cache_key $scheme$request_method$host$request_uri;
# FastCGI缓存有效期
fastcgi_cache_valid 200 302 10m;
fastcgi_cache_valid 301 1h;
fastcgi_cache_valid 404 1m;
# FastCGI缓存使用策略
fastcgi_cache_use_stale error timeout invalid_header http_500 http_503;
# FastCGI缓存绕过
fastcgi_cache_bypass $cookie_nocache $arg_nocache;
fastcgi_no_cache $cookie_nocache $arg_nocache;
}
缓存优化说明:
open_file_cache
:文件描述符缓存,提高文件访问性能proxy_cache_path
:代理缓存路径配置fastcgi_cache_path
:FastCGI缓存路径配置proxy_cache_valid
:代理缓存有效期配置fastcgi_cache_valid
:FastCGI缓存有效期配置
缓存策略配置
# =============================================
# 缓存策略配置
# =============================================
http {
# =============================================
# 缓存条件变量
# =============================================
# 定义缓存条件变量
map $request_method $no_cache_method {
POST 1;
PUT 1;
DELETE 1;
PATCH 1;
default 0;
}
map $cookie_user_token $no_cache_auth {
default 0;
"~*" 1;
}
map $arg_nocache $no_cache_arg {
default 0;
"1" 1;
"true" 1;
}
# =============================================
# 静态资源缓存
# =============================================
server {
listen 80;
server_name cache.example.com;
# 静态资源缓存配置
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|eot|svg)$ {
# 浏览器缓存
expires 30d;
add_header Cache-Control "public, no-transform";
# 代理缓存
proxy_cache proxy_cache;
proxy_cache_valid 200 302 7d;
proxy_cache_valid 404 1h;
proxy_cache_key $scheme$request_method$host$request_uri;
# 缓存状态
add_header X-Proxy-Cache $upstream_cache_status;
# 关闭访问日志
access_log off;
}
# =============================================
# 动态内容缓存
# =============================================
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
# 动态内容缓存
proxy_cache proxy_cache;
proxy_cache_valid 200 302 5m;
proxy_cache_valid 404 1m;
proxy_cache_key $scheme$request_method$host$request_uri;
# 条件缓存
proxy_no_cache $no_cache_method $no_cache_auth $no_cache_arg;
proxy_cache_bypass $no_cache_method $no_cache_auth $no_cache_arg;
# 缓存状态
add_header X-Proxy-Cache $upstream_cache_status;
}
}
}
1.5 压缩优化
Gzip压缩配置
# =============================================
# Gzip压缩优化配置
# =============================================
http {
# =============================================
# 基础Gzip配置
# =============================================
# 是否开启Gzip压缩
gzip on;
# 启用Gzip压缩的最小文件大小
gzip_min_length 1k;
# Gzip压缩缓冲区大小
gzip_buffers 4 16k;
# Gzip压缩版本
gzip_http_version 1.1;
# Gzip压缩级别(1-9)
# 1: 压缩速度最快,压缩率最低
# 9: 压缩速度最慢,压缩率最高
# 建议设置为6
gzip_comp_level 6;
# 需要压缩的MIME类型
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/x-javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;
# 是否在响应头中添加Vary: Accept-Encoding
gzip_vary on;
# 禁用IE6的Gzip压缩
gzip_disable "MSIE [1-6]\.";
# =============================================
# 高级Gzip配置
# =============================================
# 启用Gzip静态压缩
gzip_static on;
# Gzip压缩比例
gzip_proxied any;
# Gzip压缩的最小HTTP版本
gzip_http_version 1.1;
# =============================================
# Brotli压缩配置(需要额外模块)
# =============================================
# 启用Brotli压缩
# brotli on;
# Brotli压缩级别(0-11)
# brotli_comp_level 6;
# Brotli压缩的最小文件大小
# brotli_min_length 1k;
# Brotli压缩类型
# brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}
压缩优化说明:
gzip on
:开启Gzip压缩gzip_comp_level
:压缩级别,建议设置为6gzip_types
:需要压缩的MIME类型gzip_min_length
:压缩的最小文件大小gzip_vary on
:添加Vary头信息
1.6 系统级优化
内核参数优化
# =============================================
# 内核参数优化配置
# 添加到 /etc/sysctl.conf
# =============================================
# 文件描述符限制
fs.file-max = 1000000
# 网络连接优化
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.ip_local_port_range = 10000 65000
# 内存优化
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
# 网络安全优化
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
应用内核参数:
# 应用内核参数
sysctl -p
# 验证参数是否生效
sysctl -a | grep file-max
sysctl -a | grep somaxconn
系统限制优化
# =============================================
# 系统限制优化配置
# 添加到 /etc/security/limits.conf
# =============================================
# 文件描述符限制
* soft nofile 65535
* hard nofile 65535
nginx soft nofile 65535
nginx hard nofile 65535
# 进程数限制
* soft nproc 65535
* hard nproc 65535
nginx soft nproc 65535
nginx hard nproc 65535
# 内存限制
* soft as unlimited
* hard as unlimited
nginx soft as unlimited
nginx hard as unlimited
Systemd服务优化
# =============================================
# Systemd服务优化配置
# 创建 /etc/systemd/system/nginx.service.d/limits.conf
# =============================================
[Service]
LimitNOFILE=65535
LimitNPROC=65535
LimitAS=infinity
LimitMEMLOCK=infinity
重新加载Systemd配置:
# 重新加载Systemd配置
systemctl daemon-reload
# 重启Nginx服务
systemctl restart nginx
# 验证限制是否生效
cat /proc/$(pgrep nginx)/limits | grep "Max open files"
二、Nginx安全配置详解
2.1 基础安全配置
隐藏版本信息
# =============================================
# 基础安全配置
# =============================================
http {
# 隐藏Nginx版本信息
server_tokens off;
# 隐藏PHP版本信息(如果使用PHP)
fastcgi_hide_header X-Powered-By;
# 隐藏服务器信息
more_clear_headers Server;
# =============================================
# 安全头配置
# =============================================
# 防止点击劫持
add_header X-Frame-Options "SAMEORIGIN" always;
# 防止XSS攻击
add_header X-XSS-Protection "1; mode=block" always;
# 防止MIME类型嗅探
add_header X-Content-Type-Options "nosniff" always;
# 内容安全策略
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; connect-src 'self'; frame-src 'self';" always;
# 引用策略
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# 权限策略
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()" always;
}
安全头说明:
X-Frame-Options
:防止点击劫持攻击X-XSS-Protection
:启用XSS过滤器X-Content-Type-Options
:防止MIME类型嗅探Content-Security-Policy
:内容安全策略Referrer-Policy
:引用策略Permissions-Policy
:权限策略
敏感信息隐藏
# =============================================
# 敏感信息隐藏配置
# =============================================
http {
# 隐藏Nginx版本信息
server_tokens off;
# 隐藏PHP版本信息
fastcgi_hide_header X-Powered-By;
# 隐藏服务器信息
proxy_hide_header X-Powered-By;
proxy_hide_header X-Version;
proxy_hide_header X-AspNet-Version;
proxy_hide_header X-Drupal-Cache;
proxy_hide_header X-Generator;
# 隐藏错误信息中的服务器信息
fastcgi_intercept_errors on;
fastcgi_hide_header X-Powered-By;
# 自定义错误页面
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
# 禁止访问Nginx状态页面
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
}
}
2.2 访问控制
IP访问控制
# =============================================
# IP访问控制配置
# =============================================
http {
# =============================================
# 全局访问控制
# =============================================
# 允许的IP列表
allow 127.0.0.1;
allow 192.168.1.0/24;
allow 10.0.0.0/8;
# 拒绝所有其他IP
deny all;
# =============================================
# 站点访问控制
# =============================================
server {
listen 80;
server_name secure.example.com;
# 管理后台访问控制
location /admin/ {
# 只允许内网IP访问
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
# 基本认证
auth_basic "Admin Area";
auth_basic_user_file /usr/local/nginx/conf/htpasswd.admin;
# 尝试访问文件
try_files $uri $uri/ /admin/index.html;
}
# API访问控制
location /api/ {
# 限制请求频率
limit_req zone=api_limit burst=20 nodelay;
# 只允许特定IP访问
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
# 代理到后端
proxy_pass http://backend;
proxy_set_header Host $host;
}
# 静态资源访问控制
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
# 允许所有IP访问静态资源
allow all;
# 设置缓存
expires 7d;
add_header Cache-Control "public, no-transform";
# 关闭访问日志
access_log off;
}
}
}
请求频率限制
# =============================================
# 请求频率限制配置
# =============================================
http {
# =============================================
# 请求频率限制定义
# =============================================
# 定义API请求限制区域
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
# 定义登录请求限制区域
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/m;
# 定义下载请求限制区域
limit_req_zone $binary_remote_addr zone=download_limit:10m rate=2r/s;
# 定义连接限制区域
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
# =============================================
# 请求频率限制应用
# =============================================
server {
listen 80;
server_name rate-limit.example.com;
# API请求限制
location /api/ {
# 应用请求限制
limit_req zone=api_limit burst=20 nodelay;
# 应用连接限制
limit_conn conn_limit 100;
# 代理到后端
proxy_pass http://backend;
proxy_set_header Host $host;
# 添加限制信息到响应头
add_header X-RateLimit-Limit 10;
add_header X-RateLimit-Remaining 10;
add_header X-RateLimit-Reset 60;
}
# 登录请求限制
location /login {
# 应用登录请求限制
limit_req zone=login_limit burst=3 nodelay;
# 处理登录请求
proxy_pass http://backend/login;
proxy_set_header Host $host;
}
# 下载请求限制
location /download/ {
# 应用下载请求限制
limit_req zone=download_limit burst=5 nodelay;
# 应用连接限制
limit_conn conn_limit 5;
# 设置下载速度限制
limit_rate 1024k;
limit_rate_after 500k;
# 处理下载请求
proxy_pass http://backend/download;
proxy_set_header Host $host;
}
# =============================================
# 限制错误处理
# =============================================
# 请求过多错误页面
error_page 429 /429.html;
location = /429.html {
internal;
root /usr/local/nginx/html;
}
# 连接过多错误页面
error_page 503 /503.html;
location = /503.html {
internal;
root /usr/local/nginx/html;
}
}
}
请求频率限制说明:
limit_req_zone
:定义请求限制区域limit_req
:应用请求限制limit_conn_zone
:定义连接限制区域limit_conn
:应用连接限制limit_rate
:限制下载速度
2.3 SSL/TLS安全配置
SSL安全配置
# =============================================
# SSL/TLS安全配置
# =============================================
server {
# 监听443端口(HTTPS)
listen 443 ssl http2;
listen [::]:443 ssl http2;
# 服务器名称
server_name secure.example.com;
# SSL证书配置
ssl_certificate /usr/local/nginx/conf/ssl/secure.example.com.crt;
ssl_certificate_key /usr/local/nginx/conf/ssl/secure.example.com.key;
# SSL证书链
ssl_trusted_certificate /usr/local/nginx/conf/ssl/chain.pem;
# =============================================
# SSL协议配置
# =============================================
# 启用的SSL协议版本
ssl_protocols TLSv1.2 TLSv1.3;
# 禁用不安全的SSL协议
# ssl_protocols TLSv1.2 TLSv1.3;
# =============================================
# SSL加密套件配置
# =============================================
# SSL加密套件
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384;
# 优先使用服务器加密套件
ssl_prefer_server_ciphers on;
# 禁用不安全的加密套件
ssl_ciphers "!aNULL:!MD5:!DSS:!3DES:!RC4:!SEED:!IDEA:!PSK:!SRP:!EXP";
# =============================================
# SSL会话配置
# =============================================
# SSL会话缓存
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets on;
# SSL会话票据密钥
ssl_session_ticket_key /usr/local/nginx/conf/ssl/session_ticket.key;
# =============================================
# SSL高级配置
# =============================================
# OCSP装订
ssl_stapling on;
ssl_stapling_verify on;
ssl_stapling_file /usr/local/nginx/conf/ssl/stapling.ocsp;
# OCSP响应超时
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# SSL双向认证(可选)
# ssl_client_certificate /usr/local/nginx/conf/ssl/client_ca.crt;
# ssl_verify_client on;
# ssl_verify_depth 2;
# =============================================
# HSTS配置
# =============================================
# 严格传输安全
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# =============================================
# 安全头配置
# =============================================
# 防止点击劫持
add_header X-Frame-Options "SAMEORIGIN" always;
# 防止XSS攻击
add_header X-XSS-Protection "1; mode=block" always;
# 防止MIME类型嗅探
add_header X-Content-Type-Options "nosniff" always;
# 内容安全策略
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https:; frame-src 'self';" always;
# =============================================
# SSL相关代理配置
# =============================================
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-SSL $ssl_protocol;
proxy_set_header X-Forwarded-SSL-Cipher $ssl_cipher;
proxy_set_header X-Forwarded-SSL-Session $ssl_session_id;
# 设置HTTPS参数
proxy_set_header HTTPS on;
proxy_set_header HTTP_SCHEME https;
}
}
# =============================================
# HTTP重定向到HTTPS
# =============================================
server {
listen 80;
listen [::]:80;
server_name secure.example.com;
# 重定向到HTTPS
return 301 https://$server_name$request_uri;
}
SSL安全配置说明:
ssl_protocols
:启用安全的SSL协议版本ssl_ciphers
:配置安全的加密套件ssl_prefer_server_ciphers
:优先使用服务器加密套件ssl_stapling
:启用OCSP装订Strict-Transport-Security
:启用HSTS
2.4 防攻击配置
防SQL注入
# =============================================
# 防SQL注入配置
# =============================================
http {
# =============================================
# SQL注入检测规则
# =============================================
# 检测SQL注入关键字
if ($args ~* "union.*select.*\(") {
return 403;
}
if ($args ~* "union.*all.*select") {
return 403;
}
if ($args ~* "concat.*\(") {
return 403;
}
if ($args ~* "base64_") {
return 403;
}
if ($args ~* "/etc/passwd") {
return 403;
}
if ($args ~* "proc/self/environ") {
return 403;
}
if ($args ~* "select.*from") {
return 403;
}
if ($args ~* "insert.*into") {
return 403;
}
if ($args ~* "delete.*from") {
return 403;
}
if ($args ~* "update.*set") {
return 403;
}
if ($args ~* "drop.*table") {
return 403;
}
if ($args ~* "alter.*table") {
return 403;
}
if ($args ~* "create.*table") {
return 403;
}
# =============================================
# 文件包含攻击检测
# =============================================
if ($args ~* "local.*include") {
return 403;
}
if ($args ~* "remote.*include") {
return 403;
}
if ($args ~* "php://filter") {
return 403;
}
if ($args ~* "data://") {
return 403;
}
if ($args ~* "expect://") {
return 403;
}
# =============================================
# 命令注入检测
# =============================================
if ($args ~* "cmd|sh|system|exec|passthru|shell_exec|proc_open|popen") {
return 403;
}
if ($args ~* "\.\./") {
return 403;
}
if ($args ~* "<script") {
return 403;
}
if ($args ~* "javascript:") {
return 403;
}
if ($args ~* "vbscript:") {
return 403;
}
if ($args ~* "onload=") {
return 403;
}
if ($args ~* "onerror=") {
return 403;
}
}
防XSS攻击
# =============================================
# 防XSS攻击配置
# =============================================
http {
# =============================================
# XSS攻击检测规则
# =============================================
# 检测XSS攻击特征
if ($args ~* "<script") {
return 403;
}
if ($args ~* "javascript:") {
return 403;
}
if ($args ~* "vbscript:") {
return 403;
}
if ($args ~* "onload=") {
return 403;
}
if ($args ~* "onerror=") {
return 403;
}
if ($args ~* "onclick=") {
return 403;
}
if ($args ~* "onfocus=") {
return 403;
}
if ($args ~* "onblur=") {
return 403;
}
if ($args ~* "onchange=") {
return 403;
}
if ($args ~* "onsubmit=") {
return 403;
}
if ($args ~* "onreset=") {
return 403;
}
if ($args ~* "onselect=") {
return 403;
}
if ($args ~* "onunload=") {
return 403;
}
if ($args ~* "ondblclick=") {
return 403;
}
if ($args ~* "onkeydown=") {
return 403;
}
if ($args ~* "onkeypress=") {
return 403;
}
if ($args ~* "onkeyup=") {
return 403;
}
if ($args ~* "onmousedown=") {
return 403;
}
if ($args ~* "onmouseup=") {
return 403;
}
if ($args ~* "onmouseover=") {
return 403;
}
if ($args ~* "onmouseout=") {
return 403;
}
if ($args ~* "onmousemove=") {
return 403;
}
# =============================================
# XSS防护头配置
# =============================================
# 防止XSS攻击
add_header X-XSS-Protection "1; mode=block" always;
# 内容安全策略
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https:; frame-src 'self'; object-src 'none';" always;
# 防止MIME类型嗅探
add_header X-Content-Type-Options "nosniff" always;
}
防CC攻击
# =============================================
# 防CC攻击配置
# =============================================
http {
# =============================================
# CC攻击防护定义
# =============================================
# 定义请求限制区域
limit_req_zone $binary_remote_addr zone=cc_limit:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=cc_strict:10m rate=5r/m;
# 定义连接限制区域
limit_conn_zone $binary_remote_addr zone=cc_conn:10m;
# =============================================
# CC攻击防护应用
# =============================================
server {
listen 80;
server_name cc-protection.example.com;
# 全局请求限制
limit_req zone=cc_limit burst=20 nodelay;
limit_conn cc_conn 100;
# 敏感路径严格限制
location /admin/ {
limit_req zone=cc_strict burst=3 nodelay;
limit_conn cc_conn 5;
# IP白名单
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
# 基本认证
auth_basic "Admin Area";
auth_basic_user_file /usr/local/nginx/conf/htpasswd.admin;
}
# 登录页面严格限制
location /login {
limit_req zone=cc_strict burst=3 nodelay;
limit_conn cc_conn 3;
# 检测异常登录行为
if ($http_user_agent ~* "bot|spider|crawler") {
return 403;
}
# 代理到后端
proxy_pass http://backend/login;
proxy_set_header Host $host;
}
# API接口限制
location /api/ {
limit_req zone=cc_limit burst=10 nodelay;
limit_conn cc_conn 50;
# 检测异常请求
if ($request_method !~ ^(GET|POST|PUT|DELETE|OPTIONS)$) {
return 405;
}
# 代理到后端
proxy_pass http://backend;
proxy_set_header Host $host;
}
# =============================================
# User-Agent过滤
# =============================================
# 恶意User-Agent过滤
if ($http_user_agent ~* "bot|spider|crawler|scraper") {
return 403;
}
if ($http_user_agent ~* "curl|wget|python-requests") {
return 403;
}
if ($http_user_agent ~* "nikto|nmap|sqlmap") {
return 403;
}
# =============================================
# 请求方法限制
# =============================================
# 限制请求方法
if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 405;
}
# =============================================
# 错误处理
# =============================================
# 请求过多错误页面
error_page 429 /429.html;
location = /429.html {
internal;
root /usr/local/nginx/html;
}
# 连接过多错误页面
error_page 503 /503.html;
location = /503.html {
internal;
root /usr/local/nginx/html;
}
}
}
2.5 日志安全配置
安全日志配置
# =============================================
# 日志安全配置
# =============================================
http {
# =============================================
# 日志格式定义
# =============================================
# 标准日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 安全日志格式
log_format security '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';
# JSON格式日志(便于ELK分析)
log_format json escape=json '{'
'"timestamp": "$time_iso8601",'
'"remote_addr": "$remote_addr",'
'"remote_user": "$remote_user",'
'"request": "$request",'
'"status": $status,'
'"body_bytes_sent": $body_bytes_sent,'
'"http_referer": "$http_referer",'
'"http_user_agent": "$http_user_agent",'
'"http_x_forwarded_for": "$http_x_forwarded_for",'
'"request_time": $request_time,'
'"upstream_connect_time": "$upstream_connect_time",'
'"upstream_header_time": "$upstream_header_time",'
'"upstream_response_time": "$upstream_response_time"'
'}';
# =============================================
# 访问日志配置
# =============================================
# 全局访问日志
access_log /var/log/nginx/access.log main;
# 安全访问日志
access_log /var/log/nginx/security.log security;
# JSON格式访问日志
access_log /var/log/nginx/access.json.log json;
# =============================================
# 错误日志配置
# =============================================
# 错误日志级别和路径
error_log /var/log/nginx/error.log warn;
# 安全错误日志
error_log /var/log/nginx/security_error.log crit;
# =============================================
# 站点日志配置
# =============================================
server {
listen 80;
server_name log-security.example.com;
# 站点访问日志
access_log /var/log/nginx/log-security.example.com.access.log main;
# 站点错误日志
error_log /var/log/nginx/log-security.example.com.error.log warn;
# =============================================
# 敏感路径日志配置
# =============================================
# 管理后台详细日志
location /admin/ {
access_log /var/log/nginx/admin.access.log security;
# 记录所有请求头
log_format admin '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'"$http_cookie" "$http_authorization"';
access_log /var/log/nginx/admin.detailed.log admin;
}
# API接口详细日志
location /api/ {
access_log /var/log/nginx/api.access.log security;
# 记录API详细信息
log_format api '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time" '
'req_body="$request_body"';
access_log /var/log/nginx/api.detailed.log api;
}
# 静态资源简单日志
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
access_log off;
}
# =============================================
# 错误页面日志
# =============================================
# 4xx错误日志
error_page 400 401 403 404 /4xx.html;
location = /4xx.html {
internal;
root /usr/local/nginx/html;
# 记录4xx错误
access_log /var/log/nginx/4xx_errors.log security;
}
# 5xx错误日志
error_page 500 502 503 504 /5xx.html;
location = /5xx.html {
internal;
root /usr/local/nginx/html;
# 记录5xx错误
access_log /var/log/nginx/5xx_errors.log security;
}
}
}
日志轮转配置
# =============================================
# 日志轮转配置
# 创建 /etc/logrotate.d/nginx
# =============================================
/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 644 nginx nginx
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
# =============================================
# 安全日志轮转配置
# =============================================
/var/log/nginx/security*.log {
daily
missingok
rotate 90
compress
delaycompress
notifempty
create 640 nginx nginx
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
2.6 系统安全配置
文件系统安全
# =============================================
# 文件系统安全配置
# =============================================
# 设置Nginx相关目录权限
chown -R root:root /usr/local/nginx
chmod -R 755 /usr/local/nginx
# 设置网站目录权限
chown -R nginx:nginx /usr/local/nginx/html
chmod -R 755 /usr/local/nginx/html
# 设置日志目录权限
chown -R nginx:nginx /var/log/nginx
chmod -R 750 /var/log/nginx
# 设置配置文件权限
chmod 640 /usr/local/nginx/conf/*.conf
chmod 600 /usr/local/nginx/conf/ssl/*.key
chmod 644 /usr/local/nginx/conf/ssl/*.crt
# 设置临时目录权限
chmod 750 /usr/local/nginx/proxy_temp
chmod 750 /usr/local/nginx/fastcgi_temp
chmod 750 /usr/local/nginx/client_body_temp
# 设置运行用户权限
usermod -s /sbin/nologin nginx
usermod -L nginx
防火墙配置
# =============================================
# 防火墙配置
# =============================================
# 开放HTTP端口
firewall-cmd --permanent --add-service=http
# 开放HTTPS端口
firewall-cmd --permanent --add-service=https
# 开放SSH端口(仅内网)
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept'
# 限制Nginx状态页面访问
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="80" accept'
# 阻止恶意IP
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="恶意IP地址" reject'
# 重新加载防火墙配置
firewall-cmd --reload
# 查看防火墙规则
firewall-cmd --list-all
SELinux配置
# =============================================
# SELinux配置
# =============================================
# 检查SELinux状态
sestatus
# 设置SELinux为宽松模式(临时)
setenforce 0
# 设置SELinux为宽松模式(永久)
sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config
# 安装SELinux管理工具
yum install policycoreutils-python -y
# 添加Nginx相关SELinux规则
semanage fcontext -a -t httpd_sys_content_t "/usr/local/nginx/html(/.*)?"
restorecon -Rv /usr/local/nginx/html
semanage fcontext -a -t httpd_log_t "/var/log/nginx(/.*)?"
restorecon -Rv /var/log/nginx
semanage fcontext -a -t httpd_config_t "/usr/local/nginx/conf(/.*)?"
restorecon -Rv /usr/local/nginx/conf
# 允许Nginx网络连接
setsebool -P httpd_can_network_connect 1
setsebool -P httpd_can_network_relay 1
setsebool -P httpd_execmem 1
setsebool -P httpd_tty_comm 1
三、性能监控与调优
3.1 性能监控配置
状态监控配置
# =============================================
# 性能监控配置
# =============================================
http {
# =============================================
# 状态监控配置
# =============================================
# 状态页面配置
server {
listen 80;
server_name monitor.example.com;
# Nginx状态页面
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
}
# 请求监控页面
location /request_status {
# 显示请求处理状态
add_header Content-Type "application/json";
return 200 '{
"active_connections": $connections_active,
"reading": $connections_reading,
"writing": $connections_writing,
"waiting": $connections_waiting
}';
access_log off;
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
}
# 系统负载监控
location /system_load {
# 显示系统负载信息
add_header Content-Type "application/json";
return 200 '{
"loadavg": "$loadavg",
"cpu_usage": "$cpu_usage",
"memory_usage": "$memory_usage"
}';
access_log off;
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
}
}
}
性能监控脚本
# =============================================
# 性能监控脚本
# 创建 /usr/local/nginx/scripts/monitor.sh
# =============================================
#!/bin/bash
# Nginx性能监控脚本
# 用法:./monitor.sh
NGINX_STATUS_URL="http://localhost/nginx_status"
LOG_FILE="/var/log/nginx/performance.log"
ALERT_THRESHOLD=1000
# 获取Nginx状态
get_nginx_status() {
curl -s $NGINX_STATUS_URL
}
# 解析Nginx状态
parse_nginx_status() {
local status=$(get_nginx_status)
local active_connections=$(echo "$status" | grep "Active connections" | awk '{print $3}')
local accepts=$(echo "$status" | awk 'NR==3 {print $1}')
local handled=$(echo "$status" | awk 'NR==3 {print $2}')
local requests=$(echo "$status" | awk 'NR==3 {print $3}')
local reading=$(echo "$status" | awk 'NR==4 {print $2}')
local writing=$(echo "$status" | awk 'NR==4 {print $4}')
local waiting=$(echo "$status" | awk 'NR==4 {print $6}')
echo "Active connections: $active_connections"
echo "Accepts: $accepts"
echo "Handled: $handled"
echo "Requests: $requests"
echo "Reading: $reading"
echo "Writing: $writing"
echo "Waiting: $waiting"
# 检查是否超过阈值
if [ "$active_connections" -gt "$ALERT_THRESHOLD" ]; then
echo "WARNING: Active connections exceed threshold: $active_connections > $ALERT_THRESHOLD"
# 发送告警(可以集成邮件、短信等)
echo "Alert: High active connections detected" | mail -s "Nginx Alert" admin@example.com
fi
}
# 获取系统负载
get_system_load() {
local loadavg=$(cat /proc/loadavg | awk '{print $1" "$2" "$3}')
local cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
local memory_usage=$(free -m | grep "Mem:" | awk '{printf "%.2f", $3/$2*100}')
echo "System Load: $loadavg"
echo "CPU Usage: $cpu_usage%"
echo "Memory Usage: $memory_usage%"
}
# 记录性能数据
log_performance() {
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
local status=$(get_nginx_status)
local active_connections=$(echo "$status" | grep "Active connections" | awk '{print $3}')
local loadavg=$(cat /proc/loadavg | awk '{print $1}')
local cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
local memory_usage=$(free -m | grep "Mem:" | awk '{printf "%.2f", $3/$2*100}')
echo "$timestamp, $active_connections, $loadavg, $cpu_usage, $memory_usage" >> $LOG_FILE
}
# 主函数
main() {
echo "=== Nginx Performance Monitor ==="
echo "Timestamp: $(date)"
echo ""
echo "Nginx Status:"
parse_nginx_status
echo ""
echo "System Load:"
get_system_load
echo ""
echo "Logging performance data..."
log_performance
echo "Monitoring completed."
}
# 执行主函数
main
3.2 性能调优建议
基于监控数据的调优
# =============================================
# 性能调优建议脚本
# 创建 /usr/local/nginx/scripts/tune.sh
# =============================================
#!/bin/bash
# Nginx性能调优建议脚本
# 用法:./tune.sh
# 获取系统信息
get_system_info() {
echo "=== System Information ==="
echo "CPU Cores: $(nproc)"
echo "Memory: $(free -h | grep "Mem:" | awk '{print $2}')"
echo "Load Average: $(cat /proc/loadavg | awk '{print $1" "$2" "$3}')"
echo ""
}
# 获取Nginx状态
get_nginx_stats() {
echo "=== Nginx Statistics ==="
curl -s http://localhost/nginx_status
echo ""
}
# 分析性能瓶颈
analyze_performance() {
echo "=== Performance Analysis ==="
# 获取活跃连接数
local active_connections=$(curl -s http://localhost/nginx_status | grep "Active connections" | awk '{print $3}')
echo "Active connections: $active_connections"
# 获取系统负载
local load1=$(cat /proc/loadavg | awk '{print $1}')
local cpu_cores=$(nproc)
local load_per_core=$(echo "$load1 / $cpu_cores" | bc -l)
echo "Load per core: $load_per_core"
# 获取内存使用率
local memory_usage=$(free -m | grep "Mem:" | awk '{printf "%.2f", $3/$2*100}')
echo "Memory usage: $memory_usage%"
# 分析建议
echo ""
echo "=== Tuning Recommendations ==="
# 连接数建议
if [ "$active_connections" -gt 1000 ]; then
echo "1. Increase worker_connections: recommend 65535"
echo "2. Consider adding more worker processes"
fi
# 负载建议
if (( $(echo "$load_per_core > 1.0" | bc -l) )); then
echo "3. High load detected: consider optimizing application or adding more servers"
fi
# 内存建议
if (( $(echo "$memory_usage > 80" | bc -l) )); then
echo "4. High memory usage: check for memory leaks or optimize caching"
fi
echo ""
}
# 生成优化配置
generate_optimized_config() {
echo "=== Optimized Configuration ==="
# 获取CPU核心数
local cpu_cores=$(nproc)
# 生成优化配置
cat << EOF
# Optimized Nginx Configuration
# Generated on $(date)
worker_processes $cpu_cores;
worker_cpu_affinity auto;
worker_rlimit_nofile 65535;
events {
worker_connections 65535;
use epoll;
multi_accept on;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 1000;
client_body_buffer_size 128k;
client_max_body_size 50m;
gzip on;
gzip_comp_level 6;
gzip_min_length 1k;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
open_file_cache max=100000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
}
EOF
}
# 主函数
main() {
echo "Nginx Performance Tuning Assistant"
echo "=================================="
echo ""
get_system_info
get_nginx_stats
analyze_performance
generate_optimized_config
echo "Tuning analysis completed."
echo "Please review the recommendations and apply them carefully."
}
# 执行主函数
main
性能优化关键点:
- 合理配置工作进程和连接数
- 选择合适的事件模型
- 启用缓存和压缩
- 优化系统内核参数
- 监控和调优性能瓶颈
安全配置关键点:
- 隐藏敏感信息
- 配置安全头信息
- 启用SSL/TLS加密
- 实施访问控制
- 防护常见攻击
- 安全日志管理
通过本文的学习,你应该能够独立完成Nginx的性能优化和安全配置,打造一个既高性能又安全的Web服务器环境。记住,性能优化和安全配置是一个持续的过程,需要根据实际运行情况进行不断调整和优化。