请在符合国家法律法规的前提下食用本文!
币安被美国罚款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.mmdb,其中的GeoLite2-ASN.mmdb
可以查找IP段对应的ASN,GeoLite2-Country.mmdb
可以查找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没什么好说的。