server块必须置于http块内且listen+server_name组合不能冲突;推荐按站点分文件管理,准确配置server_name、root权限、SELinux策略、SSL证书链及监听参数,并用curl和nginx -T验证。

nginx.conf 里 server 块怎么写才生效
直接在 nginx.conf 里加 server 块是常见做法,但容易忽略两个前提:一是该块必须放在 http 块内,二是不能和已有 server 的 listen + server_name 组合冲突。比如本地测试时用了 listen 80 却没配 server_name,Nginx 会把所有未匹配的请求都打到这个默认 server 上,导致其他站点访问异常。
实操建议:
- 每个站点单独建一个配置文件(如
/etc/nginx/sites-available/example.com),用include /etc/nginx/sites-enabled/*;引入,比堆在主配置里更易维护 -
server_name必须写准确:域名、localhost、IP 地址或通配符(如*.example.com)均可,但server_name _;是兜底用的,别误当“通用配置” - 开发环境想用不同端口区分站点?可以,但要确保防火墙放行(如
ufw allow 8081),且浏览器访问时带上端口(http://localhost:8081)
root 路径权限和 SELinux 导致 403 怎么查
配置完 server 块,重启 Nginx 后访问返回 403 Forbidden,90% 是路径权限或 SELinux 拦截。Nginx 工作进程(通常是 www-data 或 nginx 用户)必须对 root 目录有执行(x)权限,才能进入子目录;对文件有读(r)权限才能返回内容。
排查步骤:
- 运行
ls -ld /var/www/example.com,确认目录权限至少是drwxr-xr-x(即其他用户有x) - 检查 Nginx 进程用户:
ps aux | grep nginx,看 worker 进程用的是哪个用户,再用sudo -u nginx ls /var/www/example.com模拟访问 - CentOS/RHEL 系统开启 SELinux 时,需运行
sudo setsebool -P httpd_read_content 1允许 Nginx 读取非标准路径;也可临时用sudo setenforce 0测试是否为 SELinux 导致
HTTPS 站点加 SSL 证书后访问空白或报 ERR_SSL_PROTOCOL_ERROR
加了 ssl_certificate 和 ssl_certificate_key 后页面白屏或浏览器报错,大概率是证书链不全或监听配置遗漏。Nginx 不会自动拼接中间证书,只认你指定的 PEM 文件内容。
关键点:
-
ssl_certificate必须指向包含「域名证书 + 中间证书」的合并文件(顺序:域名证书在前,中间证书在后),不能只放域名证书 - 必须显式声明
listen 443 ssl http2;,缺ssl关键字会导致 Nginx 把 443 当纯 HTTP 端口处理,握手直接失败 - 证书私钥权限必须严格限制:
chmod 600 /etc/nginx/ssl/example.com.key,否则 Nginx 启动会报SSL_CTX_use_PrivateKey_file failed
多个站点共用 80 端口时,server_name 匹配失败的真实原因
明明写了 server_name site1.com; 和 server_name site2.com;,但访问 site2.com 却进了 site1.com 的配置,不是 DNS 问题,而是 Host 请求头没传对。Nginx 完全依赖 HTTP 请求里的 Host 字段做路由,和本地 /etc/hosts 或浏览器地址栏显示无关。
验证方式:
- 用
curl -H "Host: site2.com" http://127.0.0.1直接测试,如果能正确返回 site2 内容,说明配置没问题,问题出在 DNS 解析或浏览器发起的请求 Host 头不对 - Windows/Mac 本地 hosts 修改后,Chrome 有时缓存 DNS,可尝试
chrome://net-internals/#dns清除 DNS 缓存,或换 Firefox 验证 - 用
nginx -t检查语法后,务必systemctl reload nginx(不是 restart),避免 reload 失败导致配置未生效却以为已更新
server_name 匹配逻辑和 root 路径权限的组合问题——它不报具体错误,只给个 404 或 403,得靠 curl -v 和 nginx -T(输出全部生效配置)交叉验证。










