当前位置: 首页 > news >正文

为什么外网主机可以telnet通内网nginx端口,但是http请求失败?

问题是这样的:

我内网主机nginx配置了 域名+80端口,然后防火墙没有配置80端口,但是外网机子去telnet 80端口可以通,用浏览器请求域名不能访问nginx,然后防火墙开了80端口后,浏览器就可以访问nginx了,为什么防火墙没开80端口,telnet可以访问?nginx又不行?

其根本原因在于 TCP连接建立 和 HTTP应用层请求 是两个不同的阶段,而防火墙规则可以精细地控制这两个阶段。

让我们来分解一下整个过程:

1. Telnet 为什么能通?

当您执行 telnet your_domain 80 时,发生了以下事情:

  1. TCP三次握手:Telnet 工具会尝试与您服务器的80端口建立一个原始的 TCP 连接

  2. 防火墙的默认策略:许多防火墙(如 firewalldiptables)的默认策略是 允许出站(OUTPUT)和相关的回包(ESTABLISHED, RELATED)

    • 您的 telnet 请求从外网机器发出,是一个 出站请求

    • 当这个请求到达您的内网服务器时,服务器需要回应这个SYN包来完成三次握手。这个回包属于 与已有连接相关的包(RELATED/ESTABLISHED)

  3. 关键点:在没有明确添加 80/tcp 规则时,防火墙允许了这次TCP连接建立的“回包”。因此,三次握手成功,TCP连接建立。

  4. Telnet 的成功标准:对于 Telnet 来说,只要TCP连接能建立,它就认为“端口是通的”,并显示 Connected to your_domain...。此时,连接已经建立,Telnet 在等待您输入数据(虽然您没输入就退出了)。

简单来说:Telnet 成功只证明了从外网到您服务器80端口的TCP通道是打开的,并且防火墙允许了针对外网请求的“回包”。


2. 浏览器为什么之前不能访问?

当您在浏览器中输入 http://your_domain 并按下回车时,发生了更多事情:

  1. TCP连接建立:和 Telnet 一样,浏览器首先会发起一个到服务器80端口的TCP三次握手。由于上述同样的原因,这一步成功了

  2. 发送HTTP请求:TCP连接建立后,浏览器会通过这个连接,发送一个实际的HTTP请求,例如 GET / HTTP/1.1 Host: your_domain ...

  3. nginx 处理请求:nginx 守护进程监听在80端口,它接收到这个HTTP请求,开始处理。

  4. nginx 发送HTTP响应:nginx 处理完请求后,需要将网页内容(如HTML、CSS等)作为 HTTP响应,通过刚才建立的TCP连接发回给浏览器。

  5. 防火墙的拦截:问题就出在这里!nginx 发送回的数据包,在通过服务器的防火墙时,防火墙会检查规则:

    • 这条从内网服务器发往外部浏览器的HTTP响应数据,属于 新建的出站连接? 不是,它是ESTABLISHED连接的一部分。

    • 但是,防火墙策略需要决定是否允许 从80端口发起的出站流量。虽然默认允许回包,但其规则的严格程度可能有细微差别。

    • 更可能的情况是:在您没有明确添加 80/tcp 规则时,防火墙认为80端口的所有通信(无论是进还是出)都没有被显式允许。虽然它放行了握手包,但对于后续数据传输的管控更加严格,它丢弃了nginx试图发送出的HTTP响应数据包

  6. 浏览器超时:浏览器发送了HTTP请求后,一直在等待服务器的响应。因为响应数据包被防火墙丢弃了,它什么也收不到。等待一段时间后,就会触发超时,显示 “无法访问此网站”、“连接已重置” 或 “ERR_CONNECTION_TIMED_OUT” 等错误。


3. 为什么开了防火墙端口后就一切正常了?

当您在防火墙中明确添加了允许 80/tcp 端口的规则后,您不仅仅是“打开了端口”。您实际上是创建了一条明确的、永久的策略,告诉防火墙:

“允许所有目的地为80端口的传入流量,并且与此连接相关的所有进出流量都应被允许。”

这条规则确保了:

  1. TCP三次握手的SYN包被允许进入。

  2. nginx产生的HTTP响应数据包也能顺利地通过防火墙发回给外部的浏览器。

因此,整个HTTP通信流程就畅通无阻了。

总结与类比

您可以把它想象成一个门卫快递员

  • Telnet(敲门):门外有人敲门(SYN包),门卫听到后,打开门看了一眼又关上了(回SYN-ACK包)。敲门的人知道门后有人(Telnet连接成功),但还没等说话就走了。

  • 浏览器(送货请求):门外的人敲门,门卫开门(TCP握手成功)。门外的人说:“我是快递员,这是给你的包裹(HTTP Request)”。门内的nginx接过包裹准备处理。但当nginx拿着回执单(HTTP Response)要递给门外的快递员时,门卫却拦住了他,不让他递出去(防火墙丢弃数据包)。快递员在门外等不到回执,只好离开(浏览器超时)。

  • 开了防火墙(给门卫指令):门卫得到明确指令:“所有快递相关事务都放行”。于是整个收取包裹、递回回执的过程畅通无阻。

结论:
Telnet测试的是TCP层的连接性,而浏览器访问需要完成完整的HTTP应用层交互。防火墙在没有明确规则时,其默认行为可能允许简单的连接测试,但会阻止更复杂的数据传输。显式地打开端口意味着为整个通信流程提供了完整的允许策略。

http://www.xdnf.cn/news/1466515.html

相关文章:

  • Mysql:由逗号分隔的id组成的varchar联表替换成对应文字
  • Tenda AC20路由器缓冲区溢出漏洞分析
  • iOS 抓包工具有哪些?开发、测试与安全场景的实战选择
  • 软考 系统架构设计师系列知识点之杂项集萃(140)
  • 使用 chromedp 高效爬取 Bing 搜索结果
  • 安装Codex(需要用npm)
  • Chrome 插件开发入门指南:从基础到实践
  • 达梦数据守护集群监视器详解与应用指南
  • vsan高可用:确保可访问性、全部数据迁移,两种类型权衡
  • 软件启动时加配置文件 vs 不加配置文件
  • Go 1.25.1基本包
  • 凌力尔特(LINEAR)滤波器LTC1068的二阶滤波器模块设计
  • STM32 USBx Device HID standalone 移植示例 LAT1466
  • 全球企业内容管理ECM市场规模增长趋势与未来机遇解析
  • (4)什么时候引入Seata‘‘
  • 黄金上门回收小程序开发
  • 多路转接介绍及代码实现
  • Rust 基础语法
  • 设计模式笔记
  • 从技术选型到现场配置:DDC 楼宇自控系统全流程落地方案(2025 版)
  • 织信低代码:用更聪明的方式,把想法变成现实!
  • 多语言Qt Linguist
  • 职场礼仪实训室:健康管理专业人才培养的核心支柱与创新实践
  • Springboot实现国际化(MessageSource)
  • AI Compass前沿速览:Kimi K2、InfinityHuman-AI数字人、3D-AI桌面伴侣、叠叠社–AI虚拟陪伴
  • 查询语言的进化:SQL之后,为什么是GQL?数据世界正在改变
  • 生态 | 华院计算与深至科技达成战略合作,携手推动AI+医学影像算法升级迭代
  • 代码随想录70期day3
  • 算法(keep learning)
  • 外包干了3年,技术退步太明显了。。。。。