63、【Ubuntu】【Gitlab】拉出内网 Web 服务:Gitlab 配置审视(七)

【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除

背景

上篇 blog
【Ubuntu】【Gitlab】拉出内网 Web 服务:Gitlab 配置审视(六)

通过修改本地 hosts 文件,模拟 DNS 行为,演示了在浏览器请求中,Host 是域名[非默认端口]的事实,然后分析了 Nginx 对于 server_name 配置项的匹配规则,下面继续

Nginx 配置审视

回到这个官方文档 How nginx processes a request 的描述

之前 blog 提到,Nginx 只看 HTTP 请求头里的 Host 字段,并且如果没有匹配到 server_name 的话,就会交给 default_server 默认处理器处理,下面就这个 default_server 继续分析

  • 首先第一种情况,对于下面这种,没有指定 default_server 的场景
bash 复制代码
server {
    listen      80;
    server_name example.org www.example.org;
    ...
}

server {
    listen      80;
    server_name example.net www.example.net;
    ...
}

server {
    listen      80;
    server_name example.com www.example.com;
    ...
}

Nginx 会默认使用写在最前面的那个 server 块,也就是

bash 复制代码
server {
    listen      80;
    server_name example.org www.example.org;
    ...
}

这是 Nginx 的标准默认行为,只要没有显示指定 default_server 块,第一个 server 就会被当成兜底的默认站点

  • 第二种场景,也可以显示指定哪个 server 是默认服务器,只要在 listen 指令中加上 default_server 描述参数,比如下面这种情况
bash 复制代码
server {
    listen      80 default_server;
    server_name example.net www.example.net;
    ...
}

此时这个 server 块被明确标记为了 80 端口的默认服务器,即使它不是第一个,即使它的 server_name 是一个普通的站点 example.net,只要其他请求 80 端口的 Host 不匹配任何站点,就会交给它处理

最后总结一下,Nginx 通过 Host 头匹配 server_name,匹配失败时,就会用 default_server 处理请求,这个 default_server 要么是第一个 server 块,要么是用 listen 80 default_server; 显式指定的那个 server 块

在实际使用时,为了避免安全风险,比如别人用 IP 直接访问 Web 服务器而看到某个网站,建议显式定义一个空的 default_server,比如

bash 复制代码
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name "";
    return 444;  # 关闭连接,不返回任何内容
}

这里有两个点:

  • 首先,是定义了两个 default_server
bash 复制代码
listen 80 default_server;
listen [::]:80 default_server;

这里 listen 80; 监听 IPv4 的 80 端口,listen[::]:80; 监听 IPv6 的 80 端口,这里 [::] 是 IPv6 中任意地址的简写,相当于 IPv4 的 0.0.0.0 ,现代操作系统和网络环境同时支持 IPv4 和 IPv6,如果只写 listen 80;,当用户通过 IPv4 访问这个 IP(无效域名)时,可以匹配到这个 default_server,然后关闭连接;但如果用户通过 IPv6 访问时,就会匹配不到,然后 Nginx 用另一个默认 server 处理(绕过了显式指定的 default_server),所以为了全面兜底,必须同时监听 IPv4 和 IPv6,做到完整兼容

  • 然后第二个点,server_name ""; 这里指定 server_name 为空表示匹配空 Host 头(HTTP/1.0 客户端的请求没有 Host 头),或者无效 Host,但更重要的是,表示这里只是个占位符 ,因为这里真正依赖的是 default_server,而不是 server_name,这个 server 块被选中,不是因为 server_name 匹配了某个域名,而是因为它是 default_server,换句话说,无论 Host 是 example.com1.2.3.4,还是 xxx.yyy,还是根本没有,只要没有其他 server 块匹配,Nginx 就会用这个 default_server此时 server_name "" 几乎不起作用,只是语法上必须存在,因为 Nginx 要求每个 server 至少有一个 server_name ,这个 server_name 也可以写成 server_name _;server_name invalid;,效果都一样,因为根本不会靠它来匹配

OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog
【Ubuntu】【Gitlab】拉出内网 Web 服务:Gitlab 配置审视(八)

相关推荐
崔庆才丨静觅15 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606116 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了16 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅16 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅16 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅17 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment17 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅17 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊17 小时前
jwt介绍
前端
爱敲代码的小鱼17 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax