CentOS 7下Nginx Server Blocks实战配置指南

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。先执行这四步“生存检查”:

  1. 关闭 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。

  2. 配置防火墙放行 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 双栈。

  3. 设置 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 读取非标准路径。

  4. 创建标准化网站目录结构

    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 插件,而非手动配置证书路径。步骤如下:

  1. 安装 EPEL 源和 Certbot

    yum install epel-release -y
    yum install certbot python2-certbot-nginx -y
    
  2. 生成证书前,确保 80 端口可访问且 DNS 解析正确

    certbot --nginx -d example.com -d www.example.com
    

    Certbot 会自动:

    • 检查 server_name 是否匹配 -d 参数;
    • server { } 块中插入临时 location /.well-known/acme-challenge/ 配置;
    • 调用 Let's Encrypt API 验证域名所有权;
    • 生成证书并写入 /etc/letsencrypt/live/example.com/
    • 重写原配置,添加 listen 443 ssl http2; 和证书路径
  3. 证书自动续期
    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

排查步骤

  1. nginx -T | grep "listen 80" 查看所有监听 80 端口的 server 块;
  2. 找到带 default_server 标记的那个(通常在 /etc/nginx/nginx.conf server { } 块里);
  3. 解决方案 :注释掉默认 server 块,或将其 server_name 改为一个不存在的域名(如 _ ),并确保你的 example.com.conf server_name 精确匹配 DNS 解析。

注意: server_name _; 是 Nginx 的“通配符”,匹配所有未明确定义的域名,但它不会抢占 default_server 的地位。真正可靠的做法是删除或禁用默认块。

5.2 location 匹配顺序混乱?理解 Nginx 的匹配优先级

Nginx 的 location 匹配不是按配置文件顺序,而是按 匹配算法优先级

  1. = 精确匹配(最高优先级);
  2. ^~ 前缀匹配(遇到即停止,不继续正则);
  3. ~ ~* 正则匹配(按配置文件顺序,第一个匹配成功即停止);
  4. / 通用匹配(最低优先级)。

典型陷阱

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;
}

**验证

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值