越是喧闹,越是孤独。越是寂寞,越是丰富
The more noisy, the more lonely. The more lonely, the more rich
越是喧闹,越是孤独。越是寂寞,越是丰富
The more noisy, the more lonely. The more lonely, the more rich
在今年4月份的时候,我写过一篇文章,通过做一个工具来访问ChatGPT:
历时半年多时间,这个工具使用起来一直相对稳定,主要是因为我的Azure虚拟机公网IP并没有被OpenAI封锁,因此只要确保服务器上的代理程序TinyProxy处于正常运行状态,那么使用起来就不会有什么问题。
随着对使用场景的要求逐渐提高,我对该工具也陆续做了一些迭代和优化,同时尝试搭建了V-P-N,最终实现在所有主流设备上均可顺畅访问ChatGPT。
以下是本文的主要内容:
1、为浏览器配置独立代理设置
2、免除需要输入密码的交互环节
3、将工具做成App
4、搭建V-P-N服务并实现在所有设备上访问
01
—
为浏览器配置独立代理设置
这个工具的大致原理是,建立SSH Tunnel后,将127.0.0.1:8888配置到系统的网络代理设置中。结果就是,本机所有的http/https请求都将会走代理,如果此时访问百度、京东等国内网站时,网络也需要通过海外服务器绕一圈而造成网速较慢,而且还消耗宝贵的流量额度,很不划算。为解决这个问题,多数成熟的TZ具备了分流功能,能根据所请求的目标站点自动判断是否走代理。但我想到了一种更简便的方式,与其自己实现自动分流的逻辑,不如直接使用两个浏览器,而为其中一个浏览器配置代理。
谷歌/Edge浏览器默认使用的是操作系统的网络代理设置,但是有一个Chrome插件——Proxy SwitchySharp,可以进行自定义代理配置:
安装上这个插件后,可添加一种情景模式,这里起名为ChatGPT,将127.0.0.1和8888配置为HTTP代理和HTTPS代理,如下图所示:
这样在地址栏右侧将出现该插件的代理配置菜单,选择刚创建的“ChatGPT”这一项后,浏览器将会使用127.0.0.1:8888作为代理来上网,此时适合访问ChatGPT等wall外网站。若选择“直接连接”,则不使用任何代理;若选择“使用系统代理设置”,则将走系统网络代理。
基于此,我将工具进行了修改,之前按S键将同时创建ssh tunnel并修改系统网络代理,我增加了一个选项,按R键仅创建ssh tunnel而不修改系统代理,然后通过Proxy SwitchySharp插件来使用这个tunnel进行上网,其他不需要走代理的站点我用Edge浏览器来访问。
这样相当于从物理层面实现了分流,ssh tunnel进程仅会被Chrome浏览器使用,不会影响其他程序的联网。
02
—
免除需要输入密码的交互环节
这个工具目前在Windows和MacOS系统上分别以.bat和.command文件形式存在,并不是常见的.exe可执行程序,对于不熟悉此文件类型的用户会带来一定的不便,而且为了后续建立ssh tunnel不再输入密码,首次安装工具时需要先将本地密钥拷贝到远程服务器,而此操作是需要输入密码的。由于操作系统的终端工具(Terminal/命令提示符)主要是面向专业人员,对于输入密码的操作都是静默的,即看不到任何输入提示,无法获得输入反馈,容易导致密码输入不正确,从而需要清理并重装,比较麻烦。因此我想了一种解决办法,省去用户输入密码的步骤,直接让本机与服务器建立信任。
办法就是——代理。没错,在本机和远程服务器(Azure虚拟机)之间增加一个中间服务器(例如我的阿里云虚拟机),我先提前让阿里云和Azure建立信任,然后在阿里云上暴露一个API,供本机发起HTTP请求将密钥传输过来,然后阿里云将这个密钥拷贝到Azure。这样一来,用户与Azure也就建立信任了,而整个过程用户无需输入密码了。大概流程图如下:
要实现此流程,需要对工具进行修改,将原本直接拷贝密钥的方式改为发起http请求,此步骤可通过curl命令实现,同时用perl命令对参数内容进行urlencode:
public_key=$(cat ~/.ssh/id_rsa.pub | perl -MURI::Escape -ne 'print uri_escape($_)')
response=$(curl --noproxy "*" -s -X POST -d "key=$public_key" https://path/to/upload_key)
同时在阿里云搭建一个http server,这里我使用的python Flask,在接收到客户端传输的密钥后,通过subprocess执行命令,写入到远端azure机器上:
ssh_key = urllib.parse.unquote(request.form['key'])
command = f'echo "{ssh_key}" | ssh {proxy_server} "cat >> ~/.ssh/authorized_keys"'
subprocess.run(command, shell=True, check=True)
至此,密码输入交互步骤就可以免除,减少了用户的操作成本。但是这毕竟是个命令行工具,能否做成真正的App呢?
03
—
将工具做成App
我尝试过将这个工具做成两种App形式,Android App和Mac App。
在5月初,ChatGPT还没有发布安卓版的app之前,我尝试了在Android开发中建立SSH tunnel并通过使用此代理的WebView来访问ChatGPT网页版。其中,创建tunnel可以使用com.jcraft.jsch.Session类,设置代理可通过ProxyConfig类来实现。这样相当于是一个内置代理的手机网页版ChatGPT,不完美但也能凑活用。
创建ssh tunnel的主要代码如下:
JSch jsch = new JSch();
session = jsch.getSession(sshUser, sshHost, sshPort);
session.setPassword(sshPassword);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
session.setPortForwardingL(localPort, remoteHost, remotePort);
设置代理的主要代码如下:
//设置代理
ProxyConfig proxyConfig = new ProxyConfig.Builder()
.addProxyRule("http://127.0.0.1:8888")
.addDirect().build();
ProxyController.getInstance().setProxyOverride(proxyConfig, new Executor() {
public void execute(Runnable command) {
webview.loadUrl("https://chat.openai.com/");
}
}, new Runnable() {
public void run() {
// do nothing
}
});
最终,Android App界面如下:
但是在尝试iOS开发时,发现没有一个合适的库能够创建SSH Tunnel,所以暂时没办法做出来相应的iPhone App。
最近又尝试了开发MacOS App,通过XCode,使用Swift+StoryBoard开发了一个简单的窗口界面,包含开启和关闭按钮,将工具中的各个命令转化为Swift的Process类来实现,最终做成了一个简单的Mac版App,可在苹果电脑上独立运行,可以一键开启和关闭代理。下面是开发环境的截图和程序运行截图:
至于Windows桌面App目前还没有尝试,如果开发的话应该会使用Visual Studio和C++来实现了。但现在看来已经没有必要了,因为我找到了终极的解决方案——V-P-N。
04
—
搭建V-P-N服务并实现在所有设备上访问
ChatGPT的网页版和手机App在功能上还是有些差异,手机端可以使用语音交互,网页端目前没有。所以用Webview套壳的方式无法体验到ChatGPT的语音对话功能,另外由于某些安全机制,通过Android app建立的SSH tunnel只能在应用内使用,无法设置到系统网络代理中,所以官方的ChatGPT app无法通过这个tunnel进行网络访问。于是我开始寻找其他办法。
我发现LD工具在PC上也是走的代理,但是在手机上却是创建的V-P-N。于是我就想,既然在Azure上能搭建Tinyproxy代理工具,是不是也能够搭建V-P-N服务呢?问了ChatGPT,它给出了肯定的回答,有开源的OpenV-P-N软件可以用,于是迫不及待地开始行动!
恰逢最近ChatGPT推出了重大更新,其中之一就是用户自定义GPT。为了让它能更好的协助我搭建V-P-N服务,我创建了一个GPT,起名为V-P-N
Helper,描述和指令如下:
接下来在GPT的帮助下,我一步一步完成了在Azure上搭建OpenV-P-N Server的过程,然后在安卓Google Play中下载了OpenV-P-N Connect和ChatGPT,将证书配置文件(.ovpn文件)导入到OpenV-P-N中后,顺利连接成功,顶部状态栏出现了“V-P-N”标记,ChatGPT App可以正常登录并使用啦!
这是OpenV-P-N App连接V-P-N成功后的截图:
需要注意的是,国内安卓手机通常可以启用Google Play,但是访问Google Play是需要TZ的,网上的OpenV-P-N apk安装包的下载地址通常也是需要TZ的,如果暂时没有TZ可用,可以找我要OpenV-P-N的apk包。等安装好OpenV-P-N并建立V-P-N连接后,再通过Google Play下载ChatGPT App即可。
如果是iPhone手机,操作步骤稍有不同。首先,需要一个地区不在CN大陆的Apple ID,可以注册一个新的,也可以将现有的ID更改所在地区(例如更改为美国地区)。之后打开App Store才能搜索到ChatGPT和OpenV-P-N。
iOS版的OpenV-P-N在导入证书时,不支持直接从“文件”选取证书文件导入的方式,而是支持以下两种方式:
图中说的第一种方式,我没有试过,我采用的是从Macbook将.ovpn文件隔空投送到iPhone,当手机收到并打开该文件,会自动导入到OpenV-P-N中。另一种方式就是图中说的第二种,收到一封包含.ovpn附件的邮件,下载附件后选择打开方式为OpenV-P-N即可。
最后,我又下载了OpenV-P-N的Mac版与Windows版,经测试都可以成功连接。唯一不足的是,Windows版的OpenV-P-N连接后访问ChatGPT可能会出现被拒绝的提示,Mac版暂未发现问题。所以为了安全起见,在Windows上还是以代理工具访问较为稳妥。
至此,所有设备(Windows、Mac、Android、iOS)均可以顺利访问ChatGPT了。以上全部内容就是终极解决方案,有需要帮助的小伙伴们可以随时联系我,也欢迎大家批评指正~
(全文完)