10 分钟学废了 ChatGPT 网络代理

Mars的博客 / 2023-05-07 / 原文

一、背景

从开年到现在 ChatGPT 一直很火,各种 AI 产品层出不穷,每天逛 Twitter 看都看不过来。他们是学生、程序员、创业者还有科研人员,分别在各自的领域里面以特有的方式表达着对类 ChatGPT 产品的关注和想法。

笔者愚见,既没有机器学习的知识储备也没有财力购买 A100,因此较多关注的都是一些热门资讯和产品:

  • 微软会议产品 Teams Premium,将由 GPT-3.5 自动生成会议纪要 https://hub.baai.ac.cn/view/23767
  • OpenAI 发布 ChatGPT 背后的模型 gpt-3.5-turbo https://openai.com/blog/introducing-chatgpt-and-whisper-apis
  • OpenAI 发布 whisper API 语音识别 https://openai.com/blog/introducing-chatgpt-and-whisper-apis
  • 基于 GPT-3.5 模型的 Chrome 划词翻译插件 https://github.com/yetone/openai-translator
  • OpenAI 发布 GPT-4 模型 https://openai.com/product/gpt-4
  • 类似 GitHub Copilot 的代码编辑器 https://www.cursor.so/
  • Microsoft 365 Copilot https://www.youtube.com/watch?v=S7xTBa93TX8

最开始只是凑个热闹,可一段时间使用下来,发现离不开了,每个月各种订阅费用加起来还不少。拿常用的来看,ChatGPT 已经可以替代搜索引擎了,同时 GPT-4 回答的质量非常高,就像一位大佬坐在旁边,随时向他提问;写代码用 Github Copilot 简直不要太舒服,自动提示的代码真的很卧槽。Chrome 划词翻译插件几乎每天必用,使用体验非常 nice,翻译质量很高。

”只有极少数的天才能够写出大模型的算法,只有极少数的公司有财力训练模型,大多数从业者都是从应用层调用 API”

任何一个开发者都可以轻松将这些 API 能力集成到产品中,强烈的产品成就感让一群人不分白天黑夜探索着对新一轮技术革命的畅想,无数的市场机会等待挖掘,只需要 ChatGPT 这一小酌盐巴,可以让产品发生颠覆性的改变。

在 GPT-4 出来后,国内用户想要好好上个网就更难了,除了 GFW 历史根源问题,在 OpenAI 官方的风控策略下出现了封 IP、信用卡封号段的重重困难。不仅是普通用户,连 Twitter 上好几万粉丝的大佬也需要靠海外朋友的信用卡来帮忙支付。另外,只有开通了 ChatGPT Plus 才能使用 GPT-4 并且每三个小时最多只能发送 25 条消息,如果想使用 GPT-4 的 API,需要加入 waitlist 等待内测邀请,一时间 GPT-4 API 的内测资格成了很多开发者求之不得的稀有品。

在这篇文章里面,笔者不想讨论如何注册 ChatGPT 账号、如何开通国际信用卡,相信大家查一查网络资料,应该可以很容易获得这方面的内容。本文探讨的是笔者一直以来就想研究的课题 “网络代理”,作为一个技术开发者,一个每天在用的工具,却不知其实现原理实在惭愧。另外,发现近期国内用户对网络代理的需求格外旺盛,借此机会,本文将围绕如何在国内使用 ChatGPT 入手开始,从浅入深的探讨一下网络代理的技术原理。

二、什么是网络代理

在介绍网络代理之前,首先需要知道什么是网络请求:是指计算机、手机等设备通过互联网与其他设备或服务器进行通信的过程。简单来说,当您在设备上浏览网页或使用在线应用程序时,您的设备会向互联网上的其他计算机或服务器发送请求,然后等待响应。这个过程就像是在餐厅点菜:您告诉服务员您想要什么(发送请求),然后等待他们为您准备餐点并送到您的桌子上(接收响应)。

2.1 网络审查

上面是一个简化的网络请求过程,在大多数情况下是没有问题的,但是当访问国外的一些网站(比如:Google、油管、推特)时,就会因为 GFW 这堵墙的存在而导致网络请求无法到达目标服务器,从而无法获得数据响应。

任何事物的存在必有其存在的合理性,在此不对 GFW 发表任何评价,本文讨论的是网路代理技术,而不是教大家如何FQ。

先了解下 GFW 是如何对中国大陆的互联网进行审查和过滤,技术原理主要包括以下几个方面:

  • IP 地址封锁:GFW 通过封锁特定的 IP 地址来限制用户访问境外的某些网站。当用户尝试访问被封锁的 IP 地址时,GFW 会阻止该请求,导致用户无法访问目标网站。
  • DNS 污染:GFW 通过干扰 DNS(域名系统)查询来限制对特定网站的访问。当用户尝试访问被审查的网站时,GFW 会返回错误的 IP 地址(被称为“污染”),使用户无法找到正确的服务器。
  • 关键词过滤:GFW 可以对网络数据包进行实时监控和分析,识别出包含特定关键词的数据包。当 GFW 检测到包含敏感词汇的数据包时,它会中断数据传输,使用户无法收到包含敏感信息的内容。
  • 深度包检测(DPI):GFW 利用深度包检测技术,对网络数据包的内容进行深入分析。这使得 GFW 能够识别出使用加密和隧道技术来绕过审查的流量,并采取相应措施阻止这些流量。
  • 流量限制和连接重置:当 GFW 发现用户在访问被审查的内容时,它可能会限制用户的网络速度,或者强制重置用户的连接,使其无法继续访问目标网站。
  • 证书伪造和中间人攻击:GFW 还可能使用伪造的安全证书和中间人攻击技术,对加密的 HTTPS 连接进行解密和篡改。这使得 GFW 能够窃听和审查用户在加密连接上的通信内容。

回到FQ,平常说的梯子指的就是 “网络代理(Proxy)”:可以理解为互联网世界里的中间人。当你使用网络代理时,你的请求(比如浏览网页、发送邮件等)会先经过这个中间人,然后再转发到目标服务器(比如网站服务器)。同样地,目标服务器的响应也会先返回给这个中间人,然后再由其转发给你。这个过程就像是在餐厅里,服务员代替你去点餐和拿菜,然后再把菜端给你。

有人可能有疑问,FQ不应该从墙上面翻过去吗,为啥看着像是从墙里面穿过去的。可以理解为这并不是一堵密不透风的墙,而是一个有很多城门的墙,出入的人员只要经过了城门守卫的检查,是可以正常出入的。基于这条规则,代理可以将数据伪装成健康的流量用来逃过网络审查,等到了城外之后,再以相同的方式伪装进入城内。

2.2 使用场景

网络代理在许多不同的场景中具有实际应用价值。以下是一些常见的网络代理使用场景:

  • 绕过地理限制:一些网站和在线服务会对特定地区的用户进行限制。网络代理可以帮助用户伪装自己的地理位置,绕过这些限制,访问受限制的内容。
  • 保护隐私和安全:通过使用网络代理,用户可以隐藏自己的真实 IP 地址,提高在线隐私。此外,网络代理还可以作为防火墙,过滤恶意网站和网络攻击,提高网络安全。
  • 访问受审查的内容:在一些国家和地区,政府可能会对互联网进行审查,限制用户访问特定内容。通过使用网络代理,用户可以绕过审查,获取受限制的信息。
  • 内容过滤和访问控制:在企业和学校等组织环境中,网络代理可以用于实现内容过滤和访问控制。管理员可以通过代理服务器屏蔽不合适的网站,限制员工或学生访问特定内容,确保网络环境的安全和合规。
  • 负载均衡和性能优化:在企业和数据中心环境中,网络代理可以用于实现负载均衡,将用户请求分配给多个服务器,提高服务的可用性和性能。此外,代理服务器还可以对网站内容进行缓存,减少带宽消耗,提高访问速度。

2.3 浏览器代理

假设你已经搭建了代理服务器或者购买某机场的节点,那么只需要在计算机、手机等设备上配置代理服务器即可,因不同品牌的设备配置代理的差异较大,在此不做赘述,请自查配置文档。作为演示,稍后将多次使用到 Chrome 浏览器上的 SwitchyOmega 代理扩展程序,能快速方便配置代理协议及规则进行代理访问。

当代理客户端的代理规则设置为系统代理时,访问国内网站会很慢,所以一般会把这些代理客户端的代理规则设置为绕过局域网和大陆,但当我们访问某些国外网站时,如访问油管、推特时则必须使用全局代理规则,频繁的手动切换代理模式十分麻烦。

这时候使用 SwitchyOmega 来配置代理,就显得十分方便了,在情景模式中把需要通过全局模式访问的网站配置好,当访问这些网站时,会自动切换成通过代理服务器访问,其余网站则不通过代理服务器来访问,免去手动切换代理模式的烦恼。

从 Chrome 应用商店在线安装,如果您无法从该链接在线安装,可以去以上官网下载地址下载适用 Chrome 或基于 Chromium 的浏览器的最新稳定版本安装包,下载后缀名为 .crx 的文件。在 Chrome 地址栏输入 chrome://extensions 打开扩展程序,拖动 .crx 后缀的安装文件到扩展程序中进行安装。

三、网络代理原理

首先我们看下一个普通用户想要好好上个网,需要做哪些工作

第一步,如果自建梯则需要购买服务器,然后搭建相关代理服务;如果用机场就简单了,买一个节点账号就可以;

第二步,客户端设置,在本地设备(手机、电脑)安装代理软件 Clash、Shadow***、Gost 等,然后配置服务器和代理规则;

第三步,开启系统全局代理或者应用程序配置代理,例如 Chrome 插件 SwitchyOmega 的代理设置。

经过上面简单的三步安装配置过后,正常情况下,在浏览器上输入 www.google.com 的网址应该可以顺利打开,是不是很简单。作为一个技术开发者,更让人着迷的应该是这个过程的背后,那么下面就跟随我的视角一步步分析,一个数据包是如何到达大洋彼岸的。

3.1 HTTP 协议

这里默认读者对 HTTP 协议有一些了解,就不对 TCP/IP 四层模型进行展开了。假设在一个没有墙的年代,浏览器上访问 www.google.com 网址,会经过 DNS 域名解析查询 www.google.com 域名的 IP 地址,然后客户端与目标服务器建立 TCP 连接传输数据。

TCP 协议位于传输层,HTTP 协议位于应用层,HTTP 协议负责定义请求和响应的格式和行为,而 TCP 协议则负责在两台计算机之间建立稳定的连接,确保数据的可靠传输。浏览器向服务器发送 HTTP 请求,服务器根据请求内容返回相应的资源。请求和响应都包含头部 Header 和主体 Body。头部包含有关请求或响应的元数据,如请求方法、内容类型、缓存策略等,主体包含实际的数据内容。

原本一个简单的网络请求在墙出现了以后,发生了改变,首先 DNS 被污染,www.google.com 的域名进行 DNS 解析时,将返回一个不正确的 IP 地址。即使我们修改本地设备的 hosts 文件,强制解析域名到指定的服务器,还会因为 GFW 的 IP 地址封锁,使得我们的请求无法到达目标服务器。这时想要上网访问被阻塞的站点,就需要借助代理服务器。

3.2 代理服务器

一群聪明的人想到 GFW 的工作原理,通过连接一台符合 GFW 认为合理的服务器作为中转来替代客户端请求。

代理服务器(Proxy Server)工作原理:在浏览器中设置好 Proxy Server 后,你使用浏览器访问所有 www 站点的请求都不会直接发给目的主机,而是先发给代理服务器,代理服务器接受了客户的请求以后,由代理服务器向目的主机发出请求,并接受目的主机的数据,存于代理服务器的硬盘中,然后再由代理服务器将客户要求的数据发给客户。

Tunneling TCP based protocols through Web proxy servers 隧道代理。它通过 HTTP 协议正文部分 Body 完成通讯,以 HTTP 的方式实现任意基于 TCP 的应用层协议代理。这种代理使用 HTTP 的 CONNECT 方法建立连接,

func (p *Pxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
	fmt.Printf("Received request %s %s %s\n", req.Method, req.Host, req.RemoteAddr)
	if req.Method != "CONNECT" {
		rw.WriteHeader(http.StatusMethodNotAllowed)
		rw.Write([]byte("This is a http tunnel proxy, only CONNECT method is allowed."))
		return
	}
	host := req.URL.Host
	hij, ok := rw.(http.Hijacker)
	if !ok {
		panic("HTTP Server does not support hijacking")
	}
	// 劫持连接
	client, _, err := hij.Hijack()
	if err != nil {
		return
	}
	// 建立目标服务器连接
	server, err := net.Dial("tcp", host)
	if err != nil {
		return
	}
	client.Write([]byte("HTTP/1.1 200 Connection Established\r\n\r\n"))
	// 转发数据
	go io.Copy(server, client)
	io.Copy(client, server)
}

到这里,可能有朋友会问,我们只需要搭建代理服务器,然后客户端配置代理服务器就可以了,为啥还需要在本地安装代理软件,第二步是不是多余的。别着急,我们回顾下 GFW 还有一项流量审查的技术叫做深度包检测,国内的普通用户上网必须要经过三大运营商(移动、电信、联通)骨干网到达国际出口,请求传输的数据内容会被检测,想要顺利到达代理服务器,还需要将数据进行加密伪装。

将请求数据加密在设备上以及很多应用程序 APP 中是不被支持的,另一方面加密的数据需要足够隐蔽,因为 GFW 也在不断升级,封锁能力在逐渐加强,常见的加密协议有明显的流量特征被 GFW 查到的风险很高,所以我们需要借助代理软件(Shadow、V2ra、Clash 等)进行流量加密,GFW 因为探测不到具有特别明显特征的这个流量,所以就会放行到达远程代理服务器。

3.3 代理客户端

本地安装代理软件,打开客户端会在本地后台启动一个进程同时监听一个端口,然后应用程序配置代理 127.0.0.1:7890(示例)

思考,本地的请求数据是如何通过 127.0.0.1:7890 的代理客户端发送到代理服务器?

具体的网络请求过程:

  • 首先 chrome 浏览器建立与本地 127.0.0.1:7890 代理服务器的连接,发送数据加密请求;
  • 然后本地代理服务器,经过 DNS 解析通过骨干网到达国际出口连接远程代理服务器,发送加密数据;
  • 远程代理服务器接收并解密数据,然后发送给 google 得到响应,然后以同样原理相反路径将数据发送回来。

四、ChatGPT 代理配置

从严格意义上讲FQ访问被禁止的网页或服务涉嫌违法,违法行为如何处罚要根据具体的情节和危害程度来定,一般而言对于绝大多数FQ用户来说,如果只是浏览信息,并没有危害的FQ行为一般不予处罚。

Openai 官方公布了 API 支持访问的 国家和地区,国内用户可以选择购买受支持的国家和地区的服务器或者购买切换对应的机场节点,来支持访问 ChatGPT 或调用 Openai API。从实际使用上,官方对 Openai API 的风控粒度比 ChatGPT 的要宽松许多。

目前 GPT-4 API 已经大面积放开内测了,使用感受上,回答质量和 ChatGPT 差不多。不过,使用 API 应用场景更广,可以集成到自己的产品,也可以使用开源项目自己搭建聊天类的应用。下面是几种 Openai API 配置代理的经验以供参考

  • 使用 Cloudflare Workers 代理

    https://github.com/noobnooc/noobnooc/discussions/9

    https://github.com/barretlee/cloudflare-proxy

  • 配置 nginx 反向代理

  • 开源项目 ChatGPT Web(内置代理)

    https://github.com/Chanzhaoyu/chatgpt-web

另外,自建梯子需要一定的技术能力,成本和门槛都比机场要高,在安全性方面会比较好一些。

五、参考文章

  • 详解代理自动配置 PAC:https://www.barretlee.com/blog/2016/08/25/pac-file/
  • SwitchyOmega 源码分析,使用的是 chrome.proxy 实现:https://developer.chrome.com/docs/extensions/reference/proxy/
  • Tauri macOS (WKWebView) 不支持设置 http 代理:https://github.com/tauri-apps/tauri/issues/4263
  • Chrome 的 PAC 代理配置方法:https://jerry.red/79/chrome-的-pac-代理配置方法
  • 耗子叔 - **上网:https://github.com/haoel/haoel.github.io
  • nginx 支持 keep alive 长连接 https://skyao.gitbooks.io/learning-nginx/content/documentation/keep_alive.html
  • HTTP 隧道代理原理和实现 https://cizixs.com/2017/03/22/http-tunnel-proxy-and-golang-implementation/
  • GFW 原理 和 Shadow/V2r 又是如何突破封锁的? https://www.youtube.com/watch?v=k80cu16M-rw
  • FQ是不是犯罪?会不会被抓?【硬核FQ系列】第八期 https://www.youtube.com/watch?v=mIif-7U2tEU