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 配置审视(八)

相关推荐
jinxinyuuuus2 小时前
vsGPU:硬件参数的数据仓库设计、ETL流程与前端OLAP分析
前端·数据仓库·etl
暴躁的菜鸡2 小时前
Ubuntu22.04安装postgresql16.8
ubuntu·postgresql
Evan芙2 小时前
Nginx 平滑升级
数据库·nginx·ubuntu
小信丶2 小时前
解决 pnpm dev 报错:系统禁止运行脚本的问题
前端·vue.js·windows·npm
૮・ﻌ・3 小时前
Vue3:组合式API、Vue3.3新特性、Pinia
前端·javascript·vue3
前端不太难3 小时前
RN + TypeScript 项目越写越乱?如何规范架构?
前端·javascript·typescript
神算大模型APi--天枢6463 小时前
全栈自主可控:国产算力平台重塑大模型后端开发与部署生态
大数据·前端·人工智能·架构·硬件架构
苏打水com3 小时前
第十五篇:Day43-45 前端性能优化进阶——从“可用”到“极致”(对标职场“高并发场景优化”需求)
前端·css·vue·html·js
@大迁世界3 小时前
08.CSS if() 函数
前端·css