Nginx 安全 & 性能优化全套整理

前置知识点

中间件定义

中间件:用于运行指定业务代码、承接客户端与后端程序的服务程序,Nginx 属于 Web 中间件。

补充知识点

  1. Nginx 指定运行用户两种方式:编译时指定--user=www --group=www / 配置文件全局user www;
  2. 系统 1~1024 为特权端口,仅 root 用户可监听;大于 1024 普通用户可直接监听
  3. 查看 CPU 核心数命令

bash

运行

复制代码
top                 # 交互式查看CPU
lscpu               # 完整CPU信息
grep processor /proc/cpuinfo | wc -l  # 统计物理CPU核心总数
  1. worker 进程数量匹配 CPU 核心,推荐worker_processes auto;自动识别 CPU

一、Nginx 17 项优化点(修正错误 + 配套可执行案例)

1. 隐藏 Nginx 版本号(两种方案,修复原笔记版本号笔误)

方案 1:配置文件修改(简单、无需重新编译,生产首选)

nginx

复制代码
http {
    server_tokens off; # 关闭响应头nginx版本号,404页面不展示版本
}

验证命令

bash

运行

复制代码
curl -I 192.168.91.146  # 查看响应头Server字段无版本

方案 2:修改源码永久抹除版本、软件名称(需重新编译)

bash

运行

复制代码
# 进入源码目录
cd /usr/src/nginx-1.20.2
# 编辑版本头文件
vim src/core/nginx.h
# 修改两行内容
#define NGINX_VERSION "0.0.0"       # 自定义虚假版本
#define NGINX_VER "WebServer/" NGINX_VERSION  # 伪装服务名称,不再显示nginx
# 重新编译安装
./configure --prefix=/usr/local/nginx
make && make install
# 重载配置生效
/usr/local/nginx/sbin/nginx -s reload

2. 降权启动 Nginx(普通用户运行,最小权限安全,纠正原笔记错误逻辑)

方式 A:配置文件全局指定运行用户(最简单,推荐)

  1. 创建专用运行用户 www,无登录权限

bash

运行

复制代码
useradd -s /sbin/nologin -M www  # -s禁止登录 -M不创建家目录
  1. nginx.conf 全局添加用户配置

nginx

复制代码
# 放在配置文件最顶部,全局生效
user www www; 
worker_processes auto;
  1. 网站目录、日志目录授权给 www 用户

bash

运行

复制代码
chown -R www:www /usr/local/nginx/html  # 网页目录
chown -R www:www /usr/local/nginx/logs  # 日志目录
chown -R www:www /usr/local/nginx/conf  # 配置目录
  1. 平滑重启生效

bash

运行

复制代码
/usr/local/nginx/sbin/nginx -t  # 校验配置
/usr/local/nginx/sbin/nginx -s reload

方式 B:纯普通用户独立启动(不监听 80/443 特权端口)

bash

运行

复制代码
# 1.创建普通用户test
useradd test
su - test
# 2.创建独立目录存放配置、日志
mkdir -p ~/nginx/{conf,logs,html}
# 3.复制官方默认配置
cp /usr/local/nginx/conf/mime.types ~/nginx/conf/
cp /usr/local/nginx/conf/nginx.conf ~/nginx/conf/
# 4.启动时手动指定配置文件
/usr/local/nginx/sbin/nginx -c ~/nginx/conf/nginx.conf
# 停止
/usr/local/nginx/sbin/nginx -c ~/nginx/conf/nginx.conf -s stop

纠正原笔记错误:普通用户无法监听 80/443 特权端口,只能使用 8080、8090 等高端口

3. 站点目录权限加固 + IP 访问控制

目录权限优化命令

bash

运行

复制代码
chmod -R 755 /usr/local/nginx/html  # 目录仅读写执行所有者,其他只读
chmod -R 644 /usr/local/nginx/html/* # 文件禁止执行权限,防木马
chown -R www:www /usr/local/nginx/html

IP 访问控制配置案例

nginx

复制代码
location /admin {
    allow 192.168.91.0/24; # 允许内网网段
    deny all;               # 拒绝所有外网IP
}

4. 事件处理模型优化(Linux 使用 epoll 异步非阻塞)

nginx

复制代码
events {
    use epoll; # Linux专属高性能IO模型,Windows使用select
    worker_connections 20480;
}

5. 静态资源缓存优化(expires 缓存,Cookie 作用补充)

Cookie 作用:HTTP 无状态,Cookie 存储用户身份、会话信息,浏览器自动携带至服务端

nginx

复制代码
# 匹配图片、js、css静态资源,浏览器缓存7天
location ~* \.(jpg|png|gif|js|css|ico)$ {
    root /usr/local/nginx/html/static;
    expires 7d; # 缓存7天,减少重复请求
    add_header Cache-Control "public, no-transform";
}

6. Nginx 日志按天自动切割(shell 脚本定时执行)

切割脚本 cut_nginx_log.sh

bash

运行

复制代码
#!/bin/bash
# 日志存放目录
LOG_PATH="/usr/local/nginx/logs"
# 按日期重命名日志
mv ${LOG_PATH}/access.log ${LOG_PATH}/access_$(date +%Y%m%d).log
mv ${LOG_PATH}/error.log ${LOG_PATH}/error_$(date +%Y%m%d).log
# 发送信号重新生成空日志文件
/usr/local/nginx/sbin/nginx -s reopen

授权 + 定时任务

bash

运行

复制代码
chmod +x cut_nginx_log.sh
# 添加定时任务,每日0点执行
crontab -e
# 添加内容
0 0 * * * /root/cut_nginx_log.sh

7. 连接超时、长连接优化配置

nginx

复制代码
http {
    keepalive_timeout 65; # 长连接65秒无请求自动断开
    client_header_timeout 10; # 请求头超时10秒,防慢速攻击
    client_body_timeout 10;  # 请求体上传超时10秒
    send_timeout 10;         # 响应发送超时
}

8. CPU 亲和性绑定(worker 进程绑定 CPU 核心,减少切换损耗)

案例 1:4 核 CPU 一一绑定

nginx

复制代码
worker_processes 4;
# 4个二进制位分别对应4个CPU核心0/1/2/3
worker_cpu_affinity 0001 0010 0100 1000;

案例 2:4 核 CPU 两两绑定

nginx

复制代码
worker_processes 2;
worker_cpu_affinity 1010 0101;

案例 3:高版本 Nginx 自动绑定(推荐)

nginx

复制代码
worker_processes auto;
worker_cpu_affinity auto;

9. 优化单进程最大并发连接 worker_connections

配置文件

nginx

复制代码
events {
    worker_connections 20480; # 单进程最大并发连接
}

配套系统优化(缺一不可)

bash

运行

复制代码
ulimit -n 65535 # 临时修改单进程文件句柄
# 永久修改
echo "* soft nofile 65535" >> /etc/security/limits.conf
echo "* hard nofile 65535" >> /etc/security/limits.conf

10. 单进程最大打开文件数 worker_rlimit_nofile

写在全局 http 上方,单进程最大文件句柄限制

nginx

复制代码
worker_rlimit_nofile 65535; # 必须和系统ulimit -n数值一致
events {
    worker_connections 20480;
}

11. Linux 内核 TCP 参数优化(/etc/sysctl.conf)

bash

运行

复制代码
# 编辑内核配置
vim /etc/sysctl.conf
# 添加以下内容
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
net.core.somaxconn = 4096
# 生效内核配置
sysctl -p

12. 开启高效零拷贝传输 sendfile

nginx

复制代码
http {
    sendfile on; # 开启零拷贝,静态文件不经过用户态,提升传输速度
    tcp_nopush on; # 数据包合并发送,减少网络交互
}

13. 限制文件上传大小 client_max_body_size

nginx

复制代码
http {
    client_max_body_size 10m; # 全局限制单文件最大10MB
}
# 单独站点限制
server {
    client_max_body_size 50m;
}

14. Gzip 网页压缩(节省带宽,加速页面加载)

nginx

复制代码
http {
    gzip on; # 开启压缩
    gzip_min_length 1k; # 大于1KB文件才压缩
    gzip_types text/plain text/css application/javascript image/jpeg image/png; # 压缩资源类型
    gzip_vary on;
}

15. 图片资源防盗链(防止别人盗用图片消耗流量)

nginx

复制代码
location ~* \.(jpg|png|gif)$ {
    root html/static;
    expires 7d;
    valid_referers none blocked www.test.com; # 允许本站域名访问
    if ($invalid_referer) {
        return 403; # 非法盗链返回403禁止访问
    }
}

16. 防恶意爬虫拦截

nginx

复制代码
if ($http_user_agent ~* "scrapy|curl|wget|python") {
    return 403; # 拦截爬虫UA
}

17. 网站基础访问认证(账号密码登录站点)

1. 生成密码文件

bash

运行

复制代码
yum install httpd-tools -y
htpasswd -c /usr/local/nginx/conf/auth_pass admin # 创建用户admin,输入密码

2. nginx 配置

nginx

复制代码
location /admin {
    auth_basic "请输入后台账号密码";
    auth_basic_user_file /usr/local/nginx/conf/auth_pass;
}

二、Nginx 平滑升级完整操作步骤(纠正原笔记流程错误,逐条带注释)

  1. 上传新版本源码包,解压进入目录

bash

运行

复制代码
cd /usr/src
wget https://nginx.org/download/nginx-1.26.2.tar.gz
tar xf nginx-1.26.2.tar.gz
cd nginx-1.26.2
  1. 预编译,和旧版本编译参数保持完全一致

bash

运行

复制代码
# nginx -V 查看旧编译参数,复制--prefix等全部参数
./configure --prefix=/usr/local/nginx --with-http_stub_status_module
  1. 仅编译,不要执行 make install(覆盖旧程序会中断服务)

bash

运行

复制代码
make # 只编译,不安装
  1. 备份旧 nginx 二进制程序,替换新程序

bash

运行

复制代码
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old  # 备份旧程序
cp objs/nginx /usr/local/nginx/sbin/nginx # 新二进制覆盖旧程序
/usr/local/nginx/sbin/nginx -t # 校验新版本兼容旧配置
  1. 发送 USR2 信号,启动新 master 进程,新旧进程共存

bash

运行

复制代码
kill -USR2 $(cat /usr/local/nginx/logs/nginx.pid)
# 此时同时存在新旧两套master+worker,新请求全部走新版本
  1. 确认新版本访问无报错,发送 WINCH 信号关闭旧 master 的 worker 子进程

bash

运行

复制代码
kill -WINCH $(cat /usr/local/nginx/logs/nginx.pid.oldbin)
# 旧worker进程逐步退出,旧master进程保留不退出,用于回滚
  1. 业务稳定运行一段时间后,彻底关闭旧 master 进程

bash

运行

复制代码
kill -QUIT $(cat /usr/local/nginx/logs/nginx.pid.oldbin)

回滚方案(升级出问题执行)

bash

运行

复制代码
cp /usr/local/nginx/sbin/nginx.old /usr/local/nginx/sbin/nginx
kill -QUIT $(cat /usr/local/nginx/logs/nginx.pid)
/usr/local/nginx/sbin/nginx

三、DDOS 洪水攻击、肉鸡名词解释

  1. 肉鸡:被黑客植入木马、远程控制的服务器 / 个人电脑,批量组成攻击集群
  2. DDOS 洪水攻击:利用海量肉鸡同时向目标服务器发送大量无效请求,耗尽服务器带宽、CPU、连接资源,正常用户无法访问网站