1. 项目概述:为什么在 CentOS 7 上配置 Nginx Server Blocks 是运维基本功?
Nginx、Server Blocks、CentOS 7——这三个词组合在一起,不是某个高深莫测的实验课题,而是每天在成千上万台生产服务器上真实发生的“基础生存操作”。我从2013年开始接触 Nginx,最早在阿里云 ECS 上用它跑 PHP 博客,后来在 VMware Workstation Pro 里反复重装 CentOS 7 Minimal 镜像,就为了验证一个最朴素的问题:
当一台物理机或虚拟机只有一套 IP 和端口资源,却要同时托管多个网站(比如 company.com、blog.company.com、api.company.com),怎么让请求精准落到对应的服务目录,且互不干扰?
答案就是 Server Blocks——Nginx 的“虚拟主机”机制。它不像 Apache 的 VirtualHost 那样广为人知,但恰恰是它轻量、高效、配置灵活的特性,让 Nginx 在容器化和微服务架构中成为反向代理与静态服务的首选。你搜到的“vmware虚拟机安装centos 7”“centos 7 minimal 下载”,本质上都是为这个目标打地基:一个干净、可控、无冗余服务的最小化系统环境。而“nginx安装配置”“nginx配置文件详解”“nginx location匹配规则”这些热词,全是在围绕 Server Blocks 这个核心功能展开延伸。它不是炫技,而是刚需——你部署前端项目、配置 FastAPI 后端、做 IPv6 双栈日志分流、甚至给 MQTT 或 WebDAV 加一层路由控制,底层都绕不开 Server Blocks 的路径映射、域名判别与上下文隔离。很多人卡在“nginx启动命令和停止命令”之后就停步了,以为
systemctl start nginx
成功就万事大吉;其实真正的分水岭,是从第一个
server { }
块写进去那一刻开始的。这篇文章不讲抽象原理,只讲我在 CentOS 7 上亲手配过 83 次 Server Blocks 后沉淀下来的实操逻辑、参数取舍依据、以及那些文档里绝不会写的“为什么不能这么写”。
2. 整体设计思路与方案选型:为什么必须用 Server Blocks 而非硬编码 root?
2.1 Server Blocks 不是“可选项”,而是 Nginx 架构的天然表达方式
很多人初学时有个误区:觉得“我只有一个网站,何必搞 Server Blocks?”于是直接在
/etc/nginx/nginx.conf
的
http { }
块里写
root /var/www/html;
,再加几条
location
规则完事。这看似省事,但埋下了三个硬伤:第一,
扩展性归零
——一旦你要加第二个域名,就得把所有配置揉进一个
server
块里,用
if ($host = 'xxx')
做判断,而 Nginx 官方明确警告
if
在
server
上下文中性能差且易出错;第二,
维护成本爆炸
——所有域名共用一套
location
匹配逻辑,改一个规则可能影响全部站点;第三,
安全边界模糊
——不同站点的 SSL 配置、访问控制、日志路径全混在一起,审计时根本分不清谁是谁。Server Blocks 的本质,是把每个域名/端口组合当作一个独立的“服务实例”来管理。它强制你把配置按业务域切分:
server_name example.com;
定义入口,
root /var/www/example;
定义根目录,
access_log /var/log/nginx/example.access.log;
定义日志归属。这种结构天然支持横向扩展,也符合 Linux “一个服务一个配置”的哲学。我在给客户做等保加固时,就靠这套分离式配置快速实现了“不同业务系统日志独立审计、SSL 证书按域名单独轮换、静态资源与 API 接口权限严格隔离”。
2.2 为什么坚持用 CentOS 7 Minimal 而非桌面版或 Ubuntu?
你看到的“台式电脑安装centos 7 系统”“ubuntu安装nginx”这类搜索,背后其实是两种运维思维的分野。Ubuntu 的 apt 仓库更新快,但依赖链复杂,
nginx-full
包可能自带一堆你永远用不到的模块(如 mail 模块),还可能因 systemd 版本差异导致
nginx -t
校验失败;而 CentOS 7 Minimal 是红帽系“最小可行系统”的典范:内核稳定(3.10.0-1160)、glibc 兼容性极强、systemd v219 经过十年生产验证。更重要的是,它的
yum install nginx
安装的是官方 SCL(Software Collections)源提供的 nginx-1.16.1(RHEL/CentOS 7 默认版本),这个版本虽旧,但经过 Red Hat 工程师深度测试,与 SELinux、firewalld、auditd 等安全子系统无缝协同。我曾用 Ubuntu 20.04 部署 Nginx,结果因 AppArmor 策略冲突导致
proxy_pass
到本地 FastAPI 时返回 502,排查三天才发现是
/usr/bin/python3
的 profile 限制了网络连接。而 CentOS 7 Minimal + SELinux enforcing 模式下,只要执行
setsebool -P httpd_can_network_connect 1
一条命令就解决。至于“nginx使用交叉环境编译一直编译失败”,那往往是开发者在 x86_64 主机上强行交叉编译 ARM 版本,忽略了 CentOS 7 的 glibc 版本对新编译器的兼容阈值——这不是 Server Blocks 的问题,而是环境选型失当。
2.3 配置组织策略:/etc/nginx/conf.d/ vs /etc/nginx/sites-enabled/
Nginx 官方默认配置(
/etc/nginx/nginx.conf
)末尾有一行
include /etc/nginx/conf.d/*.conf;
,这是最稳妥的配置加载路径。但很多教程教人用 Debian 风格的
sites-enabled/sites-available
结构,这在 CentOS 7 上需要手动创建符号链接,反而增加出错概率。我的实践是:
所有自定义 Server Blocks 全部放在
/etc/nginx/conf.d/
下,文件名以
.conf
结尾,且按域名命名(如
example.com.conf
)
。原因有三:第一,
conf.d/
是 yum 安装包预设的 include 路径,无需修改主配置;第二,
ls /etc/nginx/conf.d/
一眼可见所有启用的站点,
rm example.com.conf
即刻下线,比
unlink sites-enabled/example.com
更直观;第三,配合 Ansible 自动化时,模板变量直接注入
{{ domain }}.conf
,无需额外处理软链逻辑。至于“centos7 nginx编译依赖”,如果你真需要编译新版 Nginx(比如为修复 CVE-2026-27654 WebDAV 漏洞),必须装齐
gcc pcre-devel openssl-devel zlib-devel
四件套,其中
pcre-devel
决定
location ~* \.(jpg|png)$
这类正则匹配是否生效,
openssl-devel
影响 TLS 1.3 支持,缺一不可——但这属于升级范畴,与 Server Blocks 配置本身无关。
3. 核心细节解析与实操要点:从零搭建一个可上线的 Server Block
3.1 基础环境准备:Minimal 系统的必要加固动作
在 VMware Workstation Pro 中安装 CentOS 7 Minimal 后,别急着装 Nginx。先执行这四步“生存检查”:
-
关闭 NetworkManager,启用传统 network 服务 :
systemctl stop NetworkManager systemctl disable NetworkManager systemctl start network systemctl enable network原因:NetworkManager 在 Minimal 环境下常与 ifconfig 配置冲突,导致
nginx -t报bind() to 0.0.0.0:80 failed,实则是网卡未正确 up。 -
配置防火墙放行 HTTP/HTTPS :
firewall-cmd --permanent --add-service=http firewall-cmd --permanent --add-service=https firewall-cmd --reload注意:
--add-service而非--add-port,因为http服务在 firewalld 中已预定义为tcp:80,且自动适配 IPv4/IPv6 双栈。 -
设置 SELinux 允许 Nginx 访问网络与自定义目录 :
setsebool -P httpd_can_network_connect 1 setsebool -P httpd_read_user_content 1若你的网站根目录不在
/var/www/(比如/home/web/example),还需执行:semanage fcontext -a -t httpd_sys_content_t "/home/web(/.*)?" restorecon -Rv /home/web这是“centos 7 unmount”类问题的常见诱因——SELinux 阻止 Nginx 读取非标准路径。
-
创建标准化网站目录结构 :
mkdir -p /var/www/example.com/{html,logs} chown -R $USER:$USER /var/www/example.com chmod -R 755 /var/www/example.com关键点:
logs目录必须与html同级,否则 Nginx 日志路径配置会跨目录越权。
提示:以上步骤我封装成
centos7-init.sh脚本,在 VMware 克隆新虚拟机后 30 秒内执行完毕。很多“nginx安装失败”问题,根源都在这四步没走完。
3.2 Server Block 配置文件详解:每一行背后的意图
以
example.com.conf
为例,逐行拆解真实生产环境写法:
# /etc/nginx/conf.d/example.com.conf
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
# 日志路径必须绝对,且目录需提前创建
access_log /var/www/example.com/logs/access.log main;
error_log /var/www/example.com/logs/error.log warn;
# root 必须指向 html 子目录,而非父目录
root /var/www/example.com/html;
index index.html index.htm;
# location / 是所有请求的兜底入口
location / {
try_files $uri $uri/ =404;
}
# 静态资源缓存优化(关键!)
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# 防盗链(保护图片等资源)
location ~* \.(jpg|jpeg|png|gif)$ {
valid_referers none blocked server_names *.example.com;
if ($invalid_referer) {
return 403;
}
}
# 伪静态重写(如 WordPress)
location / {
try_files $uri $uri/ /index.php?$args;
}
}
关键参数解析 :
-
listen 80; listen [::]:80;:显式声明 IPv4 和 IPv6 监听,避免仅写listen 80;导致 IPv6 请求被忽略。这是“ipv6 双栈 服务器 nginx 日志”能正常记录的前提。 -
server_name example.com www.example.com;:空格分隔多个域名,Nginx 用哈希表匹配,O(1) 时间复杂度。注意www.必须显式列出,否则www.example.com会 fallback 到 default_server。 -
access_log ... main;:main是 Nginx 预定义日志格式,包含$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"。若需记录 IPv6 地址完整长度,需自定义格式,但main已满足 95% 场景。 -
try_files $uri $uri/ =404;:这是静态服务的核心逻辑。$uri匹配文件(如/about.html),$uri/匹配目录(触发index指令),=404是最终兜底。 绝不能写成try_files $uri /index.html;,否则所有 404 请求都会被重写到首页,SEO 友好性归零。 -
expires 1y;:对静态资源设置一年缓存,减少重复下载。但1y是字符串,Nginx 内部转为秒数(31536000),无需手动计算。
注意:
location ~* \.(jpg|jpeg|png|gif)$这种正则匹配,优先级高于location /,所以防盗链规则能生效。但正则匹配有性能开销,生产环境建议用location前缀匹配替代,如location /images/ { ... }。
3.3 SSL/TLS 配置:Let's Encrypt 免费证书的自动化集成
HTTP 明文传输已成历史。在 CentOS 7 上启用 HTTPS,我坚持用 Certbot + Nginx 插件,而非手动配置证书路径。步骤如下:
-
安装 EPEL 源和 Certbot :
yum install epel-release -y yum install certbot python2-certbot-nginx -y -
生成证书前,确保 80 端口可访问且 DNS 解析正确 :
certbot --nginx -d example.com -d www.example.comCertbot 会自动:
-
检查
server_name是否匹配-d参数; -
在
server { }块中插入临时location /.well-known/acme-challenge/配置; - 调用 Let's Encrypt API 验证域名所有权;
-
生成证书并写入
/etc/letsencrypt/live/example.com/; -
重写原配置,添加
listen 443 ssl http2;和证书路径 。
-
检查
-
证书自动续期 :
Certbot 自动添加 cron 任务(/etc/cron.d/certbot),每天凌晨 2:15 执行certbot renew --quiet --post-hook "systemctl reload nginx"。你只需确认systemctl list-timers | grep certbot显示任务已启用。
关键经验 :
-
Certbot 生成的配置中,
ssl_certificate指向fullchain.pem(证书链),ssl_certificate_key指向privkey.pem(私钥), 绝不能互换 ,否则 Nginx 启动报SSL_CTX_use_PrivateKey_file("...") failed。 -
若需支持老客户端(如 Windows XP IE6),需在
ssl_protocols中保留TLSv1,但会降低安全性;现代环境推荐ssl_protocols TLSv1.2 TLSv1.3;。 - “f5 nginx plus和f5 nginx open source 安全漏洞(cve-2026-27654)”这类高危漏洞,往往需升级 Nginx 版本,但 Certbot 续期不受影响——证书本身与 Nginx 版本无关。
4. 实操过程与核心环节实现:从配置到上线的全流程验证
4.1 配置语法校验与热重载:为什么
nginx -t
必须每次执行?
Nginx 的配置加载机制是“原子性”的:
nginx -t
校验通过后,
systemctl reload nginx
会启动新 worker 进程,旧进程处理完现有连接后退出。但若跳过
-t
直接 reload,错误配置会导致新进程启动失败,Nginx 服务中断。我见过太多人因少打一个分号或引号,
systemctl status nginx
显示
failed
,却不知从何查起。
标准操作流 (必须养成肌肉记忆):
# 1. 编辑配置
vi /etc/nginx/conf.d/example.com.conf
# 2. 语法校验(输出 must be "syntax is ok" and "test is successful")
nginx -t
# 3. 若报错,根据提示定位行号(如 "nginx: [emerg] unknown directive "locaion" in /etc/nginx/conf.d/example.com.conf:12")
# 注意:Nginx 行号从配置文件开头算起,包括注释行
# 4. 校验通过后重载
systemctl reload nginx
# 5. 验证进程状态
ps aux | grep nginx # 应看到 master + worker 进程
netstat -tlnp | grep :80 # 应显示 nginx 监听 80/443
常见
-t
报错场景与速查
:
| 错误信息 | 根本原因 | 修复方法 |
|---|---|---|
nginx: [emerg] "server" directive is not allowed here
|
server { }
块写在了
http { }
外层,或嵌套在另一个
server
内
|
检查大括号层级,用
vim
的
%
键跳转匹配括号
|
nginx: [emerg] invalid number of arguments in "root" directive
|
root
后跟了多个路径,如
root /var/www /html;
|
root
只接受一个绝对路径,末尾不加
/
|
nginx: [emerg] could not build the server_names_hash
|
server_name
域名过多或过长,哈希表溢出
|
在
http { }
块中添加
server_names_hash_bucket_size 64;
|
实操心得:我写了个
nginx-check别名函数,加入~/.bashrc:
alias nginx-check='nginx -t && echo "✅ Config OK" || echo "❌ Check Failed"'
每次保存配置后敲nginx-check,比看长串英文提示快 3 秒。
4.2 网站内容部署与权限验证:
chown
和
chmod
的精确控制
很多人把文件丢进
/var/www/example.com/html/
就以为完事,结果浏览器打开是 403 Forbidden。根源在 Linux 文件权限与 Nginx 用户模型的错配。
Nginx 在 CentOS 7 的默认运行用户是
nginx
(非
www-data
)
,查看方式:
ps aux | grep nginx # 第一列显示运行用户
grep user /etc/nginx/nginx.conf # 显示 user nginx;
因此,网站目录权限必须满足:
-
目录:
drwxr-xr-x(755),即nginx用户可进入(x),可读(r); -
文件:
-rw-r--r--(644),即nginx用户可读(r); -
关键点:
nginx用户不需要写权限(w) ,除非你用 PHP 写日志或上传文件。
标准权限设置命令 :
# 设置目录所有者为当前用户(便于 FTP/SFTP 上传),但赋予 nginx 组读取权
chown -R $USER:nginx /var/www/example.com/html
chmod -R 755 /var/www/example.com/html
find /var/www/example.com/html -type f -exec chmod 644 {} \;
验证是否生效 :
# 切换到 nginx 用户,模拟访问
sudo -u nginx ls -l /var/www/example.com/html/
sudo -u nginx cat /var/www/example.com/html/index.html
若
cat
报
Permission denied
,说明
html
目录或其父目录缺少
x
权限(无法进入)。
注意:“分别设置自建用户和root用户‘密码复杂度’”这类安全策略,与 Nginx 权限无关,但它是整个系统安全的基础。我要求所有生产服务器 root 密码必须满足“最小密码长度为8位,最小字符类型数为4种(大小写字母+数字+特殊符号),同一类最大连续字符数为2”,这通过
/etc/pam.d/system-auth中的pam_pwquality.so模块实现,与 Nginx 配置完全解耦。
4.3 日志分析与问题定位:读懂 Nginx 的“语言”
Nginx 日志是排障的第一手资料。
access.log
记录每一次 HTTP 请求,
error.log
记录内部错误。但很多人只会
tail -f
,却不懂如何从中提取有效信息。
access.log
关键字段解读(main 格式)
:
192.168.1.100 - - [10/Jan/2024:14:23:45 +0000] "GET /api/v1/users HTTP/1.1" 200 1234 "https://example.com/dashboard" "Mozilla/5.0 (X11; Linux x86_64) ..."
-
192.168.1.100:客户端 IP(若经 CDN 或反向代理,需配置real_ip模块); -
"GET /api/v1/users HTTP/1.1":请求方法、URI、协议版本; -
200:HTTP 状态码(2xx 成功,3xx 重定向,4xx 客户端错误,5xx 服务端错误); -
1234:响应体字节数(不含响应头); -
"https://example.com/dashboard":Referer,来源页面; -
"Mozilla/5.0...":User-Agent,客户端类型。
快速定位问题的
awk
命令
:
# 查看最近 100 行 5xx 错误
tail -100 /var/www/example.com/logs/error.log | grep "5[0-9][0-9]"
# 统计各状态码出现次数
awk '{print $9}' /var/www/example.com/logs/access.log | sort | uniq -c | sort -nr
# 查找耗时最长的 10 个请求(需在 log_format 中添加 $request_time)
awk '{print $NF,$0}' /var/www/example.com/logs/access.log | sort -nr | head -10
error.log
典型错误与对策
:
-
connect() failed (111: Connection refused) while connecting to upstream:后端服务(如 FastAPI)未启动或端口错误; -
open() "/var/www/example.com/html/favicon.ico" failed (2: No such file or directory):浏览器自动请求 favicon,但文件不存在,属正常现象,可忽略或放一个空favicon.ico; -
client intended to send too large body:客户端 POST 数据超限,需在server块中加client_max_body_size 10M;。
实操心得:我用
goaccess工具将access.log可视化,执行goaccess /var/www/example.com/logs/access.log -o /var/www/example.com/html/report.html --log-format=COMBINED,生成 HTML 报表,实时监控 PV、UV、热门 URL、爬虫行为。这比手动grep高效十倍。
5. 常见问题与排查技巧实录:那些文档里不会写的坑
5.1 Server Blocks 不生效?90% 是
default_server
搞的鬼
现象:配置了
example.com.conf
,但访问
example.com
却显示 Nginx 默认欢迎页。
根本原因
:Nginx 在
http { }
块中有一个隐式的
server { listen 80 default_server; ... }
,当请求的
Host
头不匹配任何
server_name
时,就会 fallback 到它。而 CentOS 7 的
nginx.conf
默认启用了这个
default_server
。
排查步骤 :
-
nginx -T | grep "listen 80"查看所有监听 80 端口的server块; -
找到带
default_server标记的那个(通常在/etc/nginx/nginx.conf的server { }块里); -
解决方案
:注释掉默认
server块,或将其server_name改为一个不存在的域名(如_),并确保你的example.com.conf中server_name精确匹配 DNS 解析。
注意:
server_name _;是 Nginx 的“通配符”,匹配所有未明确定义的域名,但它不会抢占default_server的地位。真正可靠的做法是删除或禁用默认块。
5.2
location
匹配顺序混乱?理解 Nginx 的匹配优先级
Nginx 的
location
匹配不是按配置文件顺序,而是按
匹配算法优先级
:
-
=精确匹配(最高优先级); -
^~前缀匹配(遇到即停止,不继续正则); -
~~*正则匹配(按配置文件顺序,第一个匹配成功即停止); -
/通用匹配(最低优先级)。
典型陷阱 :
location /api/ {
proxy_pass http://backend;
}
location ~* \.php$ {
fastcgi_pass php-fpm;
}
当请求
/api/user.php
时,会先进入
/api/
块(前缀匹配),而不会走到
.php
正则块。但若写成:
location ~* \.php$ {
fastcgi_pass php-fpm;
}
location /api/ {
proxy_pass http://backend;
}
则
/api/user.php
仍会进入
.php
块,因为正则匹配优先级高于前缀匹配。
正确写法(按业务逻辑分层) :
# 1. 精确匹配 favicon
location = /favicon.ico {
log_not_found off;
expires 1y;
}
# 2. 前缀匹配 API 路径(阻止 .php 被误处理)
location ^~ /api/ {
proxy_pass http://127.0.0.1:8000/;
proxy_set_header Host $host;
}
# 3. 正则匹配静态资源
location ~* \.(jpg|jpeg|png|gif|css|js)$ {
expires 1y;
}
# 4. 最终兜底:PHP 脚本
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
}
5.3 Docker 部署 Nginx 时 Server Blocks 失效?卷挂载权限是元凶
“docker安装nginx并使用”“docker部署nginx”越来越普遍,但很多人把
conf.d/
目录挂载进容器后,发现配置不生效。
根本原因
:Docker 容器内的 Nginx 进程以
nginx
用户(UID 99)运行,而宿主机挂载的配置文件所有者是 root(UID 0)。Linux 的
uid
不同,导致容器内
nginx
用户无法读取配置。
解决方案 :
# 方案1:修改宿主机文件所有者(推荐)
sudo chown -R 99:99 ./nginx-conf/
# 方案2:在 docker run 中指定用户
docker run -d --name nginx \
-v $(pwd)/nginx-conf:/etc/nginx/conf.d \
-u 99:99 \
-p 80:80 nginx
# 方案3:用 docker-compose.yml 显式声明
version: '3'
services:
nginx:
image: nginx
volumes:
- ./nginx-conf:/etc/nginx/conf.d
user: "99:99"
提示:“arm架构下dify离线部署全流程指南”中提到的 Nginx 反向代理,同样适用此原则。ARM 容器镜像中的
nginx用户 UID 也是 99,与 x86_64 一致,无需额外调整。
5.4 IPv6 双栈日志中 IP 地址显示不全?
log_format
需显式支持
“ipv6 双栈 nginx 日志”搜索量上升,但很多人发现
access.log
中 IPv6 地址被截断为
2001:db8::1
,实际应为
2001:db8:0000:0000:0000:0000:0000:0001
。
原因
:Nginx 默认
log_format
使用
$remote_addr
,它对 IPv6 地址做了压缩显示。要记录完整地址,需自定义日志格式:
log_format ipv6 '$remote_addr_full - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
map $remote_addr $remote_addr_full {
~:^([0-9a-fA-F:]+): $remote_addr;
default $remote_addr;
}
但更简单的方法是:
直接使用
$binary_remote_addr
,它以二进制形式记录 IP,长度固定(IPv4 为 4 字节,IPv6 为 16 字节),日志分析工具(如 GoAccess、ELK)可自动解析。
log_format main '$binary_remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
5.5 “nginx配置fastapi”时 502 Bad Gateway?检查
proxy_pass
的斜杠逻辑
FastAPI 服务常运行在
http://127.0.0.1:8000
,Nginx 代理配置如下:
location /api/ {
proxy_pass http://127.0.0.1:8000;
}
结果访问
example.com/api/users
,FastAPI 收到的请求路径是
/api/users
,但 FastAPI 的路由是
/users
,导致 404。
正确写法(注意
proxy_pass
末尾的
/
)
:
location /api/ {
proxy_pass http://127.0.0.1:8000/; # 末尾必须有 /
}
原理:
proxy_pass
末尾有
/
时,Nginx 会
删除
location
匹配的前缀
/api/
,再拼接后端 URL
。即
/api/users
→ 删除
/api/
→
/users
→
http://127.0.0.1:8000/users
。
若
proxy_pass
末尾无
/
,则直接拼接:
/api/users
→
http://127.0.0.1:8000/api/users
,这要求 FastAPI 的路由也带
/api/
前缀。
实操心得:我在部署 12 个 FastAPI 服务时,统一约定所有 API 路由不带
/api/前缀,Nginx 配置强制加/,这样后端代码无需感知代理路径,迁移成本为零。
6. 进阶扩展与安全加固:让 Server Blocks 真正扛住生产流量
6.1 负载均衡与高可用:用 upstream 实现多实例分发
单台 Nginx 服务器是瓶颈。
upstream
模块可将请求分发到多个后端,实现负载均衡。
# /etc/nginx/conf.d/example.com.conf
upstream backend_servers {
# 轮询(默认)
server 192.168.1.101:8000 weight=3;
server 192.168.1.102:8000 weight=1;
# 健康检查(需 nginx-plus 或开源版加 patch)
# check interval=3 rise=2 fall=5 timeout=1;
}
server {
listen 80;
server_name example.com;
location /api/ {
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
权重说明
:
weight=3
表示该服务器接收 3/4 的流量,适合配置更高的机器。
rise=2
表示连续 2 次健康检查成功则恢复服务,
fall=5
表示连续 5 次失败则剔除。
注意:“lvs keepalived nginx搭建”是另一套高可用方案,LVS 在四层(TCP)做负载,Nginx 在七层(HTTP)做应用层分发。两者可结合:LVS 做 VIP 高可用,Nginx 做内容路由。但中小团队直接用 Nginx
upstream更轻量。
6.2 安全加固:针对 CVE-2026-27654 等 WebDAV 漏洞的规避策略
“cve-2026-27654深度解析:nginx webdav高危漏洞原理与修复方案”这类搜索,直指 Nginx 的 WebDAV 模块。该模块若启用,攻击者可利用
COPY
/
MOVE
方法进行路径遍历,读取任意文件。
根本对策
:
禁用 WebDAV 模块
。CentOS 7 的 yum 安装包默认不编译 WebDAV,但若你自行编译过 Nginx,需确认
./configure
未加
--with-http_dav_module
。
双重保险
:在
server
块中显式拒绝 WebDAV 方法:
# 禁用危险 HTTP 方法
if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|OPTIONS|PATCH)$ ) {
return 405;
}
# 或更激进:只允许 GET/HEAD/POST
if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 405;
}
**验证
6802

被折叠的 条评论
为什么被折叠?



