请在符合国家法律法规的前提下食用本文!
币安被美国罚款 43 亿美元!CEO 辞职!
虽然币安很早以前就禁止美国用户注册,但是现在币安的 API 也开始限制美国 IP 了,导致我的机器人从宣布罚款第二天开始就无法正常使用。直到今天,我终于忍无可忍,决定想办法绕过这个限制。
环境介绍
简单描述一下我的机器人:
1 | 用户 -> Discord -> 托管在Cloudflare Worker上的Discord Bot -> 币安API |
换句话说,无论用户来自哪里,币安收到的 API 请求都是通过 Cloudflare Worker 发出的。而由于 Discord 服务器主要位于美国,因此到达 Cloudflare Edge 的地域也几乎都是美国,所以币安理所应当认为这些请求都是来自美国的。
所以很简单,我需要找到一个办法,可以让 Cloudflare Worker 发出的请求看起来像是来自其他国家的。
解决方案 1
虽然其原理我依然有点一知半解,但经过一整天的测试,终于成功复现了作者说明的方法。以下是步骤:
假如我们有一个 Cloudflare Worker,承担核心的 API 功能,名字是demoworker,代码如下:
1 | export default { |
同时,我们有一个域名,假如是logiconsole.com
创建一个代理 Worker
首先,我们需要创建一个代理 Worker,就叫demoworkerproxy好了。代码如下:
1 | async function proxy(request) { |
先不用管上面代码的含义,后面会解释。但记住logiconsole.com
是我自己的域名,到时候要改成你的域名。
创建 Worker Routes
然后,我们需要创建两个 Worker Routes,分别指向上面的两个 Worker,如下图所示:
注意把域名改成自己的域名。
创建 DNS A 记录
接下来,我们需要创建两个 DNS A 记录,分别指向两个 Worker Routes。这里要注意,通常我们会直接在 Worker 的 Triggers 中添加 Custom Domain,让 Cloudflare 自动帮我们创建类型是 Worker 的 DNS 记录,但是这里我们需要手动创建 A 记录,并且将 IP 地址设置为任意一个 Cloudflare Warp 的 IP 地址,如下图所示:
图中的188.114.96.3
就是一个 Cloudflare Warp 的 IP 地址,你也可以自己去找其他能用的 IP。可以看到,我还添加了一个twdemoworkerproxy
的记录,对应的 IP 地址8.39.126.5
同样是一个 Cloudflare Warp 的 IP 地址,但是位于台湾。
解释
当有一个请求访问demoworkerproxy.logiconsole.com
时,由于该域名被指向了 Cloudflare 的网络,且设置了 Worker Routes,所以它被指向了demoworkerproxy这个 Worker。通过这段代码:
1 | addEventListener("fetch", (event) => { |
Worker 会先判断请求的来源地区,如果是美国或者中国,就会走forceRegion
方法。(把中国也加进来是方便本地测试)
1 | async function forceRegion(request) { |
forceRegion
的方法简单来说,就是在请求中添加cf:{resolveOverride: 'twdemoworkerproxy.logiconsole.com'}
,再原封不动向自己发送一遍请求。由于resolveOverride
的存在,Cloudflare 会去解析twdemoworkerproxy.logiconsole.com
这个域名,而这个域名指向的是 Cloudflare 在台湾的机房 IP,且同样通过*demoworkerproxy.logiconsole.com/*
这个 Worker Route 指向了demoworkerproxy。所以 Cloudflare 会通过台湾的机房再请求一次demoworkerproxy。又因为twdemoworkerproxy.logiconsole.com
和demoworkerproxy.logiconsole.com
处于同一个域名下,所以请求中的所有信息都会被透明地传递下来。
接下来,我们打开 Worker 的日志,并且访问demoworkerproxy.logiconsole.com
,可以看到如下日志:
其中较早的信息如下:
很明显是我本地的 IP 地址,而较晚的信息如下:
注意 headers 中的访问来源信息已经不是中国了(但居然是英国,在我之前的测试中,应该统一都是台湾的信息。可能是 IP 信息乱了),而’colo’这个值变成了TPE
,即台北机场的代码。
既然访问来源已经不是 US 或者 CN 了,那么就不会再走forceRegion
方法,而是走proxy
方法,也就是直接向demoworker发送请求,即正常访问原本的 API 了。
查找不同地区 Cloudflare 的 IP 段
首先,可以通过这个地址下载最新的 geolite 数据库,其中的GeoLite2-ASN
可以查找 IP 段对应的 ASN,GeoLite2-Country
可以查找 IP 段对应的国家。只要找到 ASN 为 13335、组织是 CLOUDFLARENET 的 IP 段,就是 Cloudflare 的 IP 段了。接下来和国家的 IP 段互相对应,就能找到不同地区的 Cloudflare IP 段了。
另外,Linux 下可以通过nmap -n -sP {IP段}
这个命令扫描该 IP 段下所有可用的 IP 地址。
万万没想到
然而用了这个方法之后,我发现我的机器人依然无法正常工作。经过反复测试验证后,我才不得不承认,币安貌似是把 Cloudflare 所有的 IP 段都给封了……
解决方案 2
既然方案 1 行不通,那就只能来简单粗暴的了:找个机房,写一个简单的代理脚本,把所有的请求都转发到该机房,再由该机房转发到币安。这样,币安就会认为所有的请求都是来自该机房了。
没什么好说的,直接上仓库:
https://github.com/dale0525/binance-server.git
经过反复衡量采用了 Docker 方案,方便在不同机房迁移。在 Docker 前面加一个反向代理即可,如果实在偷懒,直接访问 IP:端口也是可以的。
另外,推荐一个开源的运维管理面板:1Panel
比宝塔透明,并且至少 SSL 证书续签从来没遇到问题。
总结
本文其实主要是记录一下 Cloudflare Worker 强制指定机房的方法,毕竟方案 2 没什么好说的。