通过ip访问nginx的服务时,被第一个server重定向了,通过设置default_server解决这个问题

📅 发布时间:2026/7/5 8:11:28 👁️ 浏览次数:
通过ip访问nginx的服务时,被第一个server重定向了,通过设置default_server解决这个问题
Nginx default_server 指令完全指南概述在 Nginx 配置中default_server是一个非常重要但经常被忽视的参数。它用于指定当请求的 Host 头无法匹配任何server_name时应该使用哪个 server 块来处理请求。基本概念什么是 default_serverdefault_server是listen指令的一个参数用于标记某个 server 块为默认服务器。当 Nginx 收到一个请求但该请求的 Host 头或IP地址访问无法匹配任何已配置的server_name时就会使用标记为default_server的 server 块来处理。为什么需要 default_server在实际应用中经常会遇到以下场景IP地址直接访问用户通过 IP 地址而不是域名访问服务器错误的域名用户输入了错误的域名或未配置的域名恶意扫描黑客通过 IP 扫描尝试探测服务器DNS配置错误域名解析配置错误导致Host头不匹配如果没有明确指定default_serverNginx 会使用监听该端口的第一个server 块作为默认服务器这可能导致意外的行为。语法listen port [default_server];常见用法# HTTP (端口 80) listen 80 default_server; # HTTPS (端口 443) listen 443 ssl default_server; # 同时指定监听地址和端口 listen 192.168.1.100:80 default_server; # IPv6 listen [::]:80 default_server;实际应用场景场景 1防止域名劫持重定向问题场景假设您的 Nginx 配置如下http { # 第一个 server 块 - 域名重定向 server { listen 80; server_name example.com; return 301 https://example.com$request_uri; } # 第二个 server 块 - 实际服务 server { listen 80; server_name localhost; root /var/www/html; index index.html; } }当用户通过 IP 地址访问如http://192.168.1.100/时由于没有匹配的server_nameNginx 会使用第一个 server 块导致被重定向到https://example.com这显然不是我们想要的结果。解决方案http { # 域名重定向 server { listen 80; server_name example.com; return 301 https://example.com$request_uri; } # 设置为默认服务器 server { listen 80 default_server; server_name localhost; root /var/www/html; index index.html; } }场景 2安全防护 - 拒绝未知域名访问出于安全考虑您可能希望拒绝所有未明确配置的域名访问http { # 默认拒绝访问 server { listen 80 default_server; listen [::]:80 default_server; server_name _; # 返回 444 表示直接关闭连接 return 444; } # 您的实际网站 server { listen 80; server_name example.com www.example.com; root /var/www/example; index index.html; } }场景 3提供友好的错误页面为未知域名提供一个友好的提示页面http { # 默认服务器 - 显示友好提示 server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /var/www/default; location / { return 200 您访问的域名未在本服务器配置。\n; add_header Content-Type text/plain; charsetutf-8; } } # 实际网站 server { listen 80; server_name example.com; root /var/www/example; } }场景 4多域名多服务器环境在托管多个网站的服务器上明确指定默认服务器可以避免配置错误http { # 网站 A server { listen 80; server_name site-a.com www.site-a.com; root /var/www/site-a; } # 网站 B server { listen 80; server_name site-b.com www.site-b.com; root /var/www/site-b; } # 开发测试环境 - 默认服务器 server { listen 80 default_server; server_name localhost; root /var/www/dev; location / { index index.html; } } }工作原理Nginx 匹配顺序当 Nginx 接收到一个 HTTP 请求时会按以下顺序匹配 server 块精确匹配完全匹配server_name通配符匹配使用通配符的server_name如*.example.com正则表达式匹配使用正则表达式的server_name默认服务器如果以上都不匹配使用default_server第一个 server 块如果没有指定default_server使用该端口的第一个 server 块验证当前配置可以通过以下命令查看 Nginx 如何处理不同的 Host 头# 测试通过 IP 访问 curl -H Host: 192.168.1.100 http://192.168.1.100/ # 测试未配置的域名 curl -H Host: unknown-domain.com http://192.168.1.100/ # 查看 Nginx 的请求日志 tail -f /var/log/nginx/access.log重要注意事项1. 每个端口只能有一个 default_server# ❌ 错误同一个端口不能有多个 default_server server { listen 80 default_server; server_name example1.com; } server { listen 80 default_server; # 这会报错 server_name example2.com; }如果尝试这样配置Nginx 会报错nginx: [emerg] duplicate default server for 0.0.0.0:802. 不同端口可以有不同的 default_server# ✅ 正确不同端口可以各有一个 default_server server { listen 80 default_server; server_name localhost; } server { listen 443 ssl default_server; server_name localhost; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; }3. IPv4 和 IPv6 需要分别指定server { listen 80 default_server; # IPv4 listen [::]:80 default_server; # IPv6 server_name localhost; }4. SSL/TLS 配置注意事项HTTPS 的 default_server 需要提供有效的 SSL 证书server { listen 443 ssl default_server; server_name _; # 即使是默认服务器也需要证书 ssl_certificate /etc/nginx/ssl/default.crt; ssl_certificate_key /etc/nginx/ssl/default.key; # 可以使用自签名证书 return 444; }最佳实践1. 总是明确指定 default_server不要依赖 Nginx 的隐式行为使用第一个 server 块应该明确指定server { listen 80 default_server; server_name _; return 444; # 拒绝未配置的域名 }2. 使用下划线作为占位符server_name _;是一个特殊值表示捕获所有不匹配的域名server { listen 80 default_server; server_name _; # 下划线表示占位符不代表实际域名 return 444; }3. 在配置文件顶部定义 default_server将 default_server 放在配置文件的前面使配置结构更清晰http { # 首先定义默认服务器 server { listen 80 default_server; listen [::]:80 default_server; server_name _; return 444; } # 然后是具体的网站配置 server { listen 80; server_name example.com; # ... } }4. 分离 HTTP 和 HTTPS 的 default_server# HTTP 默认服务器 server { listen 80 default_server; listen [::]:80 default_server; server_name _; # 可以选择重定向到 HTTPS 或直接拒绝 return 301 https://$host$request_uri; } # HTTPS 默认服务器 server { listen 443 ssl default_server; listen [::]:443 ssl default_server; server_name _; ssl_certificate /etc/nginx/ssl/default.crt; ssl_certificate_key /etc/nginx/ssl/default.key; return 444; }5. 记录日志用于调试server { listen 80 default_server; server_name _; # 记录访问日志便于发现异常流量 access_log /var/log/nginx/default-access.log; error_log /var/log/nginx/default-error.log; return 444; }实战案例案例开发环境配置http { # 生产环境 - 正式域名 server { listen 80; server_name example.com www.example.com; root /var/www/production; location / { index index.html; } } # 测试环境 - 子域名 server { listen 80; server_name test.example.com; root /var/www/testing; } # 开发环境 - 默认服务器通过 IP 访问 server { listen 80 default_server; server_name localhost; root /var/www/development; # 显示服务器信息仅开发环境 add_header X-Server-Type Development; location / { autoindex on; # 开启目录浏览 } } }案例安全加固配置http { # 默认拒绝未知请求 server { listen 80 default_server; listen [::]:80 default_server; listen 443 ssl default_server; listen [::]:443 ssl default_server; server_name _; # 自签名证书用于 HTTPS ssl_certificate /etc/nginx/ssl/dummy.crt; ssl_certificate_key /etc/nginx/ssl/dummy.key; # 记录可疑访问 access_log /var/log/nginx/suspicious.log; # 返回最小化响应 return 444; } # 真实网站配置 server { listen 80; listen [::]:80; server_name example.com www.example.com; # 强制 HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name example.com www.example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; root /var/www/example; index index.html; } }调试技巧1. 测试配置是否生效# 检查配置语法 nginx -t # 重新加载配置 nginx -s reload # 测试不同的 Host 头 curl -H Host: example.com http://your-server-ip/ curl -H Host: unknown.com http://your-server-ip/ curl http://your-server-ip/ # 使用 IP 直接访问2. 查看当前监听端口# 查看 Nginx 监听的端口 netstat -tlnp | grep nginx # 或使用 ss 命令 ss -tlnp | grep nginx3. 查看 Nginx 错误日志# 实时查看错误日志 tail -f /var/log/nginx/error.log # 查看最近的错误 tail -n 100 /var/log/nginx/error.log常见错误及解决方案错误 1重复的 default_server错误信息nginx: [emerg] duplicate default server for 0.0.0.0:80 in /etc/nginx/sites-enabled/site.conf:10原因同一个端口配置了多个default_server解决方案检查所有配置文件确保每个端口只有一个default_server# 搜索所有 default_server 配置 grep -r default_server /etc/nginx/错误 2SSL 证书问题错误信息nginx: [emerg] SSL_CTX_use_certificate_chain_file() failed原因HTTPS 的 default_server 没有配置有效的证书解决方案为 default_server 提供证书可以是自签名证书# 生成自签名证书 openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout /etc/nginx/ssl/default.key \ -out /etc/nginx/ssl/default.crt错误 3配置未生效问题修改了配置但 default_server 行为未改变解决方案# 1. 检查配置语法 nginx -t # 2. 如果语法正确重新加载配置 nginx -s reload # 3. 如果还是不行重启 Nginx systemctl restart nginx # 4. 清除浏览器缓存后重试性能考虑使用default_server本身对性能影响很小但可以通过以下方式优化1. 减少不必要的处理server { listen 80 default_server; server_name _; # 直接关闭连接不做任何处理 return 444; }2. 限制连接速率# 定义限速区域 limit_req_zone $binary_remote_addr zonedefault_limit:10m rate10r/s; server { listen 80 default_server; server_name _; # 应用限速 limit_req zonedefault_limit burst20; return 444; }总结default_server是 Nginx 配置中的重要参数它可以防止配置错误避免意外使用错误的 server 块提升安全性拒绝未知域名的访问请求改善用户体验为未配置的域名提供友好提示简化调试明确的默认行为使问题更容易定位关键要点每个端口只能有一个default_serverIPv4 和 IPv6 需要分别指定HTTPS default_server 需要提供 SSL 证书建议明确指定而不是依赖隐式行为使用server_name _作为占位符推荐配置模板http { # HTTP 默认服务器 server { listen 80 default_server; listen [::]:80 default_server; server_name _; return 444; } # HTTPS 默认服务器 server { listen 443 ssl default_server; listen [::]:443 ssl default_server; server_name _; ssl_certificate /etc/nginx/ssl/default.crt; ssl_certificate_key /etc/nginx/ssl/default.key; return 444; } # 您的实际网站配置 server { listen 80; listen [::]:80; server_name example.com www.example.com; # ... } }正确使用default_server可以让您的 Nginx 配置更加健壮、安全和易于维护。参考资料Nginx 官方文档 - ngx_http_core_moduleNginx 官方文档 - Server names