关于 copilot 转发的一些技术细节

我与copilot的故事

我是从copilot免费公测就开始使用的,中间收费后用过一段时间学生包,去年10月才开始做copilot激活器的,一开始也只是自己和几个朋友一起用(那时候还没了解到cocopilot这个东西),后来传到网上陆续有几十个用户,都是来白嫖的,少有付费的,我也不懂推广一直没啥用户。

然后今年1月份开始陆续有一两个淘宝卖家找到我,要代理卖我的软件。我给的模式都是他们自己维护号池,我只提供和维护服务器和软件,原本想着成本并不高,所以给他们的价格也很便宜,不过后面算上我投入的精力,真的是亏惨了:joy:

年后 github 风控越来越严重,导致代理商家的号池经常被清空 。虽然我一开始就知道下发token的模式会有被盗用的风险,但是一直没太在意。直到大概3月25号,也多亏有个代理了解到真的有很多盗用的,参考:https://linux.do/t/topic/28126 我才决定开始搞现在这个代理转发的模式。

转发模式优点

  1. 可以防盗刷,我们可以限制用户并发的方式防止盗刷
  2. 合理调度,我们可以更加合理得分数用户的请求到不同的github账号,加上盗刷减少,可以更好地规避github封号

转发模式缺点

  1. 更大的服务器资源占用,以前平均一个用户十几分钟下发一次token就行了,现在变成敲几下键盘就是一次请求,数据量也比之前更大
  2. 代码经过我的服务器,原本代码只会暴露给github, 现在还会暴露给我

说搞就搞,从3月25号开始,大概熬夜了一个星期,把这个模式走通。

正片开始

首先从最好搞的 vscode 开始

  1. 用vscode自己攻克自己 code ~/.vscode/extensions/github.copilot-1.176.0
  2. 打开文件夹中的 dist/extensions.js 使用 prettier 美化一下代码
  3. 创建一个 .vscode/launch.json ,然后打个断点,就可以 f5 开始调试了
    {
    	"version": "0.2.0",
    	"configurations": [
    		{
    			"args": [
    				"--extensionDevelopmentPath=${workspaceFolder}"
    			],
    			"name": "Launch Extension",
    			"outFiles": [
    				"${workspaceFolder}/out/**/*.js"
    			],
    			"request": "launch",
    			"type": "extensionHost"
    		}
    	]
    }
    
  4. 一番摸索发现插件使用的 tls.connect 方法校验了证书,所以就算我信任了 charles 的证书也不能抓包,把它 hook 掉
    process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
    const tls = require("tls");
    const _connect = tls.connect;
    function wrappedConnect(port, host, options, secureConnectListener) {
    	if (typeof port === "object") {
    		options = port;
    		secureConnectListener = host;
    	} else if (typeof host === "object") {
    		options = host;
    		options.port = port;
    		secureConnectListener = options;
    	} else {
    		options = options || {};
    		options.port = port;
    		options.host = host;
    	}
    	console.log("xxx", options);
    	options.rejectUnauthorized = false; // 验证不通过也别报错
    	return _connect(options, secureConnectListener);
    }
    tls.connect = wrappedConnect;
    
  5. 后面就顺利抓到 chat 和 代码补全的请求啦
  6. 抓到请求后就是拦截和转发了, 试试拦截https的request方法
    [https, http].forEach((module) => {
    	module.request = (function (fn) {
    		console.log(`request: ${url.host}${url.pathname}`);
    		return function (url, opts) {
    			if (
    				["api.github.com", "api.githubcopilot.com", "copilot-proxy.githubusercontent.com"].indexOf(
    					url.host
    				) >= 0
    			) {
    				url.host = "xxx.micosoft.icu";
    				if (opts) {
    					opts.headers = {
    						...opts.headers,
    						host: url.host,
    						authorization: 'token ' + process.env.GITHUB_TOKEN,
    					};
    				}
    			}
    			return fn.apply(this, arguments);
    		};
    	})(module.request);
    });
    
  7. 结果不行啊,只拦截到一些无关紧要的请求,又是一番断点分析后发现他是用的 http2 发起的请求 :sob:,http2 拦截起来太麻烦了,不如不让他用 http2 吧,于是在 hook tls.connect的代码中加上
    if (options.ALPNProtocols) {
    	options.ALPNProtocols = options.ALPNProtocols.filter((protocol) => protocol !== "h2");
    }
    
  8. 至此请求拦截的工作就基本完成了,后面就是写代码来找到插件并 hook 插件就行啦。

总结:当然这只是其中我认为比较好的一种修改插件的方式哈,相比直接去修改 extensions.js 中间的代码,这种 hook 的方式维护起来更方便

然后是 RStudio,Vim, HBuilder, Qt 之流

  1. 下载安装好插件后,发现跟 vscode 大差不差,只是入口文件从 extensions.js 变成了 agent.js,有了vscode的经验, 用同样的方式一把梭,没一会就搞定了。

最后是 JetBrains 和 Visual Studio

  1. 一开始看见 copilot-agent-win.exe 这玩意我也是懵逼的,但是。。。诶,这图标不是 nodejs 的图标吗?
    image
  2. 于是我开始搜索将 nodejs 代码打包为 exe 的方法,就找到了它 pkg - npm
  3. 再进一步一看,这不js源码不和 copilot-agent-win.exe 在一起的吗
  4. 既然这么良心,就按照 hook RStudio 的方式把 dist 目录的源码修改后,重新用pkg打包成 copilot-agent-win.exe 就行啦
42 个赞

copilot配置里一直有一个debug proxy可以设置反代地址,很早就可以设置。虽然这样闭环之后token不会泄露,但我一直没用这个参数,就是不想代码什么的过我的服务器。以后应该也不会用,因为本来就一个token最多10人,没有必要搞这么麻烦。

7 个赞

搞七捻三软件开发

技术流,佩服

会经过服务器,细思极恐

皇说你要是说这个我就不困了╰:sunglasses:

他原始的token不是cocopilot的那种,是ghu的,会被其他商家盗用,这样就不止10个人了,容易被封。弄个转发又有记录代码的嫌疑。用cocopilot的话加点限制基本能防token盗用,也不会记录代码

狠刑啊

不如上好点的检测手段

厉害

不需要盗用ghu,只要是直连github,必然会下发通过 /copilot_internal/v2/token 兑换的 token,只需要盗用这个token就可以了。
这个模式我确实想不到什么办法可以检测盗用的

2 个赞

号商马上跟进

可以模仿论坛cocopilot,感觉cocopilot更好

mark一下,学习

思路很好,通过全权代理,在服务器换上GitHub token,跟openai镜像转发一个道理。这样来看应该不会被GitHub封号了

牛牛牛

6666

厉害啊

cocopilot只适合少数人一起拼车, 人多很容易被封号, 不符合他们号商的需求.

1 个赞

大佬,我买过独角兽:unicorn:,这个是你自营还是代理?给人家赚钱还不如给你赚。。。

2 个赞