惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
WordPress大学
WordPress大学
云风的 BLOG
云风的 BLOG
Stack Overflow Blog
Stack Overflow Blog
MongoDB | Blog
MongoDB | Blog
腾讯CDC
V
V2EX
Martin Fowler
Martin Fowler
A
About on SuperTechFans
大猫的无限游戏
大猫的无限游戏
Blog — PlanetScale
Blog — PlanetScale
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
酷 壳 – CoolShell
酷 壳 – CoolShell
C
Check Point Blog
博客园 - 【当耐特】
Cisco Talos Blog
Cisco Talos Blog
The Hacker News
The Hacker News
K
Kaspersky official blog
Security Latest
Security Latest
H
Help Net Security
博客园_首页
美团技术团队
Spread Privacy
Spread Privacy
博客园 - 司徒正美
Hugging Face - Blog
Hugging Face - Blog
S
SegmentFault 最新的问题
G
Google Developers Blog
NISL@THU
NISL@THU
爱范儿
爱范儿
I
Intezer
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
N
News and Events Feed by Topic
P
Privacy International News Feed
Application and Cybersecurity Blog
Application and Cybersecurity Blog
S
Security @ Cisco Blogs
Schneier on Security
Schneier on Security
雷峰网
雷峰网
人人都是产品经理
人人都是产品经理
V
Vulnerabilities – Threatpost
W
WeLiveSecurity
P
Palo Alto Networks Blog
G
GRAHAM CLULEY
Hacker News: Ask HN
Hacker News: Ask HN
I
InfoQ
The Cloudflare Blog
F
Full Disclosure
SecWiki News
SecWiki News
宝玉的分享
宝玉的分享
N
Netflix TechBlog - Medium

Mereith's Blog

PVE DataCenter Manager 端口号跳转错误修复 k8s + jenkins + gitlab 触发器 【转载】没有编程生产力这样的东西 【后续】居然被 ddos 了 居然被 ddos 了 Tagger - 让版本标签管理更简单 openclash 开启后端口转发失效 nextjs 启动时执行代码 买了太多VPS不知道干什么,干脆做个网站 juhost Level-1 测评 VMISS CN - Hong Kong VMISS JP - Tokyo - BGP 测评 VMISS CN - Hong Kong - BGP HomeLab 的终点是 最近在做的事情 因为选择艰难症,自己写了一套开源博客系统 手撸一个nodejs分布式爬虫,还要可视化 HomeLab 分享 我的个人工作流——开源项目推荐 动手写一个超简单的编译器 safari 插件开发 Safari Extensions Preferences 按钮无响应 设置移动端软键盘回车按钮文案 nginx proxy manager 非标准端口反代 Host 不对 监控 k8s ingress 自动添加域名 DNS 解析 使用 ingress 注解给 traefik ingress 添加中间件 使用流水线功能为文章添加固定结尾 为 VanBlog 添加一个小挂件 基于React/umi/egg自建博客系统 如何正确停止 NodeJS 子进程 k8s pod 替换策略 让威联通、pve 共享 ups 实现断电关机 Ubuntu 配置 samba 混合云部署k3s集群(基于wireguard) pve 无法启动 grub lvmid not found error antd Password 关闭自动补全 code-server node not found pve no quorum 错误 || 无法登录 pve Cannot Initiate CMAP Service pve 节点删不干净 PVE 指针(鼠标)漂移 pve 重启网络 Proxmox VE 直通显卡 ProxmoxVE (PVE) 7.0 换源升级 用 SOCAT 端口转发 git 无法 pull 仓库refusing to merge unrelated histories 用 vuepress 搭建私人知识库 js 防抖节流中的 this 与箭头函数 Dockerfile 给 Ubuntu 换源 docker 内访问宿主机 docker 删除无用镜像 css 实现展开收起动画 nginx 301 问题 Node.js 流式编程 关于我重写了三次博客项目这件事 css flex 布局超出隐藏 css 隐藏滚动条 css 文字超出隐藏并显示省略号 css 填充 svg 颜色 css 黑白滤镜 nginx 反代丢端口 docker-compose 部署 matomo 分析系统 基于 strapi 开发应用 strapi 关闭 Content Security Policy nginx 反代 rewite url ssh 通过跳板机访问目标机器 Cent os 7 安装 zsh 5.6 以上版本 win11 任务栏不合并 bash 数组操作 vim 修改文件格式为 unix k8s 集群 control-plane-endpoint 主机名 git https 保存密码 Bash 判断命令存在 & 重定向 python 导出项目依赖 cent os 7 安装 gcc 版本 9 System limit for number of file watchers reached cent os 7 安装 git 2.x css 下划线中间向两边滑动效果 linux 挂载 SMB/CIFS linux 清除 ACL windows 命令行安装 inf 驱动 css 文字不可选择 iperf3 网络测速工具 cent os 换源 k8s 1.21.3 从 docker 迁移到 containerd 解决Nginx安装错误:No package nginx available 问题 从pve的硬盘里导出数据 Errors were encountered while processing adguardhome配合clash pve中使用LXC容器安装OMV LXC直通硬盘 nginx反代模版 docker常用开启容器的命令 PVE的LXC容器中安装Docker ProxmoxVE系统分区相关 基于clash搭建旁路网关 Portainer添加节点 linux声卡设置及录音音 OpenWrt用VLAN PVE换源及去掉订阅提示和改端口 adguardhome踩坑
记一次代理转发问题的排查与解决
wanglu@mereith.com (mereith) · 2025-06-19 · via Mereith's Blog

请注意,本文编写于 351 天前,最后修改于 351 天前,其中某些信息可能已经过时。

背景

最近我遇到了一个看似简单,但实际上颇为棘手的网络问题。事情是这样的:

我在国内工作,手上有一个海外的HTTP代理服务,格式是 http://username:password@proxy.example.com:31212。由于众所周知的原因,这个代理在国内是直接访问不了的。不过,我还有一台位于海外的VPS服务器(IP:x.x.x.x),国内是可以正常访问的。

我的想法很简单:既然我能访问海外VPS,VPS能访问代理,那我就在VPS上搭建一个转发服务,让流量走这样的路径:

本地电脑(中国) → 海外VPS → HTTP代理 → 目标网站

听起来是不是很合理?我当时也是这么想的。

初次尝试

验证代理可用性

首先,我SSH登录到海外VPS上,写了个简单的Python脚本测试代理是否正常:

import asyncio import aiohttp async def test_proxy(): proxy = "http://username:password@proxy.example.com:31212" async with aiohttp.ClientSession() as session: async with session.get( url="http://www.google.com", headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" }, proxy=proxy, ) as response: print(f"Status: {response.status}") print(f"Response length: {len(await response.text())}") asyncio.run(test_proxy())

运行结果:完全正常!代理是可用的。

搭建转发服务

接下来,我尝试了多种转发方案:

  1. Python脚本转发:写了个简单的HTTP转发服务
  2. Gost工具:使用了专业的代理转发工具
  3. 其他各种转发工具

然而,奇怪的事情发生了...

诡异的现象

当我在本地通过这些转发服务访问时,全部失败!错误信息都是:


更诡异的是,我发现了一个规律:

  • ❌ 当我的电脑不使用任何代理,直接访问VPS上的转发服务时 → 失败
  • ✅ 当我的电脑使用透明代理(如Shadowsocks)时,再访问VPS上的转发服务 → 成功

这就很奇怪了。按理说,如果是转发服务的问题,那应该一直都不能用才对。为什么使用了透明代理就能工作呢?

问题分析

经过一番思考和查阅资料,我终于明白了问题所在:GFW的深度包检测(DPI)

原理解析

当我们从国内直接访问海外服务器时,所有的数据包都会经过GFW。GFW不仅仅是简单地封锁IP或域名,它还会进行深度包检测,分析数据包的内容和模式。

对于HTTP代理来说,有几个明显的特征:

  1. CONNECT方法:HTTP代理在建立HTTPS连接时,会发送明文的CONNECT请求
  2. 特定的请求头:如Proxy-Authorization
  3. 流量模式:代理流量有其特定的模式

当GFW检测到这些特征时,它会认为这是一个代理连接,然后主动发送RST包来断开连接。这就是为什么我们会收到"Connection reset by peer"的错误。

为什么透明代理可以工作?

当使用Shadowsocks等透明代理时,我们的流量已经被加密和混淆了。GFW看到的只是一堆加密数据,无法识别出里面包含的HTTP代理协议特征,所以就不会干扰连接。

这就像是:

  • 直接转发 = 透明的玻璃箱子运输违禁品
  • 透明代理后转发 = 不透明的铁箱子运输违禁品

最终解决方案

在尝试了各种复杂的转发方案后,我意识到:与其在应用层做各种转发和伪装,不如直接在网络层解决问题

最终我采用了一个简单粗暴但非常有效的方案:

1. 在VPS上部署 sing-box

直接在海外VPS上使用 sing-box 搭建了一个 VLESS 节点。sing-box 是一个强大的网络代理平台,支持多种协议,而 VLESS 是一个轻量级的代理协议,具有良好的性能和安全性。

配置非常简单,sing-box 可以直接配置上游代理,这样就形成了:

本地 → VLESS加密隧道 → VPS上的sing-box → HTTP代理 → 目标网站

2. 本地使用 Clash 的 TUN 模式

在本地电脑上,我使用 Clash 配置了 VLESS 节点,并开启了 TUN 模式。TUN 模式是一种透明代理模式,它会在系统层面创建一个虚拟网卡,所有的网络流量都会经过这个虚拟网卡。

这样做的好处是:

  • 完全透明:应用程序完全感知不到代理的存在
  • 全局生效:所有的网络请求都会自动走代理
  • 无需修改代码:原来的代码一行都不用改

3. 代码层面的解放

配置好之后,我的Python代码可以直接这样写:

import aiohttp import asyncio async def fetch_youtube(): # 直接用代理,clash 已经接管了系统流量,会自动绕到中转节点的。 proxy = "http://user:passj@proxy.example.com:31212" async with aiohttp.ClientSession() as session: async with session.get("https://www.youtube.com",proxy=proxy) as response: print(f"Status: {response.status}") print(f"Title found: {'YouTube' in await response.text()}") asyncio.run(fetch_youtube())

可能的其他方案

方案一:SSH隧道

SSH是一个非常常见的服务器管理协议,不容易被封锁。我们可以利用SSH的端口转发功能:

在VPS上运行HTTP转发服务(监听本地端口) 在本地建立SSH隧道:

ssh -N -L 8080:localhost:8888 root@your-vps-ip

这样,访问本地的8080端口就相当于访问VPS上的8888端口,而且所有流量都是通过SSH加密的。

方案二:gost/nodepass/realm 加密隧道

使用专业的工具,进行加密隧道转发。

方案三:国内找一个 server,与国外中转服务器组成加密隧道

国内的网络是没有 gfw 的,如果我有多台中转服务器,就是想在代码里精确控制,灵活搭配,而且还得用 http 代理。

那么可以找一个国内的中转服务器,与国外的若干个中转服务器组成加密隧道或者 vps(wireguard、tailscale、gost 等),然后在国内搭建 http 代理转发,流量在国内的中转节点加密后到国外的中转节点,然后再到海外的代理服务器。

总结

这次经历让我深刻理解了几个道理:

  1. 问题要从根源解决:与其在应用层做各种复杂的转发和伪装,不如直接在网络层用成熟的方案
  2. 工具选择很重要:sing-box + Clash 的组合非常强大,既有良好的加密特性,又有优秀的易用性
  3. 透明代理是最优雅的方案:TUN模式让所有应用都能无感知地使用代理,极大地提升了开发体验

最重要的是,这个方案让我可以专注于业务逻辑,而不是纠结于网络问题。代码该怎么写就怎么写,就像没有任何网络限制一样。

有时候,最简单的方案反而是最好的方案。与其绕来绕去,不如一步到位!