近期计划启用整个团队的chatgpt4.0。现实情况决定了我们需要chatgpt4.0却不是频繁需要,所以当下的需求实现上变成了:
- 团队中的每位成员都可以在不爬梯子的情况下使用chatgpt
- 4.0的费用是20刀/月,我们希望将整个团队的费用控制在这个当量下
- 4.0有请求频率限制,我们希望能够充分的利用好这一限制,让每位成员都有使用的资格,但却不过渡使用从而触发限额。
而上述过程的第1步,则需要当前搭建本地chatgpt的服务器可以愉快的连接openapi的接口地址,而本文的主旨在于解决这个本地chatgpt的网络问题。
反向代理
网上有很多帖子在讲,如何购买国外的云服务器,然后配置nginx做为反向代理的问题。这种方案简单可行,还可以通知防火墙来提供反代的安全问题。
VPN
我们使用 VPN 技术来解决这一问题,来把本地的服务器完全模拟在外网环境中。由于服务器本身就像是在外网环境中一样,所以用这种方式其实可以规避很多小的问题。而访问chatgpt的api接口当然也不在话下了。
在此,我们使用更简单(尚可以发布)的wireguard来完成 VPN 的搭建过程。
服务端
远端服务端需要自己解决或是有一些 VPN 的运营商。在此我们以ubuntu为例:
首先是通过su
来切成root
用户,然后安装wireguard
:
# apt install wireguard
安装完成后,但有两个命令可用,分别为:wg
及wg-quick
此时先使用wg
生成一个密钥对:
# wg genkey | tee privatekey | wg pubkey > publickey
此时将生成私钥privatekey
及公钥 publickey
。
然后来到/etc/wireguard
使用nano wg0.conf
来创建一个wireguard
配置文件,内容如下:
[Interface]
PrivateKey = 这里换成privatekey的内容
Address = 10.10.8.1/24
ListenPort = 5128
DNS = 1.1.1.1,8.8.8.8
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
简单解释一下:
- PrivateKey 私钥内容
- Address 当前wireguard服务端地址及分配的对端IP范围
- ListenPort 监听端口号
- DNS DNS地址
- PostUp wg接口启用时,向iptables中添加一些转发的命令,这样对端发起的请求,便可以通过本服务端进行转发了
- PostDown wg接口停用时,将前面添加的记录删除掉
为了使用服务端可以对客户端的连接进行转发,还需要启用转发功能:
# nano /etc/sysctl.conf
在文件中找到#net.ipv4.ip_forward=1
并把前面的注释去掉,如果并没有这行,则直接在文件中添加一行:net.ipv4.ip_forward=1
。保存文件后,执行:
# sysctl -p
使其改更生效。
最后启动wg
:
# wg-quick up wg0
客户端
在客户端使用的操作系统仍然为稳定的FreeBSD
,安装wireguard
如下:
首先使用su
命令切换到root
用户,然后运行命令:
# pkg install wireguard
接着创建一个文件夹:
# mkdir -p /usr/local/etc/wireguard
# cd /usr/local/etc/wireguard
然后同样创建一对密钥对:
# wg genkey | tee privatekey | wg pubkey > publickey
在这个文件夹中执行ee wg0.conf
创建一个配置文件,内容如下:
[Interface]
Address = 10.10.8.100/24
PrivateKey = 这里换成privatekey的内容
由于做为客户端出现,所以配置比较简单。仅仅配置了本端的ip地址及私钥。
PEER
wireguard其实是弱化了客户端与服务端的概念的,即每个安装了wireguard的主机,即可以是客户端也可以是服务端,也就是说它们是对等端的关系。这种对等的关系往往体现在两个主机可以直接通讯的前提下,但由于我们当前的客户端处于 NAT 下,所以才有了服务端与对等端的概念。而在配置中,则需要在客户端处增加配置Endpoint
。
通讯双方还可以设置PreSharedKey
即预设共享密钥
来增强安全性,这样以来在第一次通讯时,双方传输的即为加密数据。
在客户端与服务端使用wg genpsk
来生成这一共享密钥
。
首先进行服务端的peer配置,编辑服务端配置文件/etc/wireguard/wg0.conf
,添加以下配置:
[peer]
PublicKey = 这里使用客户端publickey的内容
AllowedIPs = 10.10.8.100/32
PreSharedKey = 这里使用刚刚生成的共享密钥的内容
上述配置中 10.10.8.100
为客户端在前面配置的IP地址。
客户端的配置相对复杂一些,同样编辑客户配置文件,增加配置如下:
[Peer]
PublicKey = 客户端publickey的内容
Endpoint = 服务端公网IP:5128
AllowedIPs = 这里的地址后面给
PreSharedKey = 这里使用刚刚生成的共享密钥的内容(与服务端的相同)
PersistentKeepalive = 25
上面的AllowedIPs
有点讲究,这里的内容需要先打开 https://www.procustodibus.com/blog/2021/03/wireguard-allowedips-calculator/ 然后通过输入:走 VPN 通道的地址以及不走 VPN 通道的地址来生成,比如:
请将上图中的192.168.0.0/16
替换为自己的实际情况,如果你需要将所以的流量都通过 VPN 进行转发,那么也可以这样:
其中把1.2.3.4
换成服务端的公网 IP 地址。
原则上即使不在AllowedIPs中排除公网IP地址,其实也应该是没有问题的。但是如果需要进行定制化的生成AllowedIPs,则必须将服务端的地址加入到 Disabllowed IPs,然后进行运算。
最后点击运算:
则会得到我们需要的 AllowedIPs,将得到的值复制到配置文件中即可。
启动
在服务端与客户端分别执行 wg-quick up wg0
,即可完成启动。此时在客户端使用curl cip.cc
,如果显示为服务端的公网 IP,那么恭喜你已经成功了。
在freebsd系统下,还可以向 /etc/rc.conf
添加:
wireguard_enable="YES"
wireguard_interfaces="wg0"
来完成开机自启动。
在ubuntu系统下,则可以通过:
sudo systemctl enable wg-quick@wg0.service
sudo systemctl daemon-reload
设置wireguard的开机自启动。
chatgpt测试
执行:
curl 'https://api.openai.com/v1/chat/completions?path=v1' -H 'authority: api.openai.com' -H 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7' -H 'accept-language: en-GB,en;q=0.9,zh-CN;q=0.8,zh;q=0.7' -H 'cache-control: max-age=0' -H 'sec-ch-ua: "Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"' -H 'sec-ch-ua-mobile: ?0' -H 'sec-ch-ua-platform: "macOS"' -H 'sec-fetch-dest: document' -H 'sec-fetch-mode: navigate' -H 'sec-fetch-site: none' -H 'sec-fetch-user: ?1' -H 'upgrade-insecure-requests: 1' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' --compressed
成功返回:
{
"error": {
"message": "You didn't provide an API key. You need to provide your API key in an Authorization header using Bearer auth (i.e. Authorization: Bearer YOUR_KEY), or as the password field (with blank username) if you're accessing the API from your browser and are prompted for a username and password. You can obtain an API key from https://platform.openai.com/account/api-keys.",
"type": "invalid_request_error",
"param": null,
"code": null
}
}
说明当前网络已经成功的对接到chatgpt
.
总结
本文阐述一种使用 VPN 技术达到了本地主机拥有外网环境的实现方案。相较于反向代理方案,该方案在实现难度上更大,但相对也更安全。
同时,该方案还适用于:设置在测试或打包时需要外网的机器人的网络环境。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。