基本思路
从这篇文章的标题中我们可以看出,这一次的搭建方案主要用到的是 Docker,你可能会很好奇,Docker 跟搭建 4G 代理有什么关系吗?
嗯,关系很大,我们把整件事情梳理一下,先来看看搭建 4G 代理时的基本流程:
- 调用 卡拨 ,拨 成功后会创建一个虚拟 卡。(正常情况下使用这个虚拟 卡就能上 了)
2.在多 卡的情况下,重复第一步,会得到多个虚拟 卡。
3.启动代理服务器,使其使用虚拟 卡作为出 卡,并使用接入内 的实体 卡作为入 卡。
但是呢,有个问题,根据我之前的测试结果来看,目前在 Linux 环境下还没有一个 HTTP 代理服务器是可以做到分别指定出 卡和入 卡的,嗯…这就很麻烦了,因为如果我们无法这么做的话,就会出现类似于下面这样的问题:
- 出 和入 都在虚拟 卡上,使用代理服务器必须要走公 访问。
- 入 为实体 卡,但出 被代理服务器锁定为了某一个,无法利用到多 卡。
嗯…那么不用 HTTP 代理服务器,用那些经常被用来做一些骚操作的 Socks5 代理服务器呢?如果可以指定 卡的话,再用像 Privoxy 之类的工具把 Socks5 代理转成 HTTP 代理就好了。(某知名扶墙软件的 Windows 版本就是这么转的 HTTP 代理)
在经过一番尝试后,我发现虽然有些 Socks5 代理服务器的文档中是说可以指定 卡,但按照说明操作后,似乎并不能直接做到我想要的效果(要么还是锁定在某一个上面、要么上不了 ),所以还是存在一些问题的。可能是需要配合路由表设置来进行操作吧,不过我对 络工程的了解不怎么深,搞了几天也没搞出来,于是乎还得想想别的办法。
这时候,我想到了一个东西——Docker,它可以用来解决这个问题!
因为 Docker 容器被创建后,不管外界的 卡有多少个,容器内部的 卡都只会有一个Docker自己的虚拟 卡(容器间通信用的)和一个本地环回接口(不用管它),而且我们在容器内进行拨 操作时,产生的那个新的虚拟 卡也不会影响到外界或其他容器,这样的话,代理服务器就不需要指定 卡了,直接启动就能跑!
那么现在整个流程就跑通了,进入实际操作环节看看吧!
系统方面
这个 Docker 版的搭建方式,系统方面的选择很多,由于我使用的样例设备是树莓派,所以这里就选择使用了 Raspbian(树莓派专属版 Debian)。如果你使用的是其他设备的话,直接选择一个自己常用的系统就好。
那么准备好之后的第一步当然是先下载并安装 Docker,这里我直接使用 Docker 官方提供的一键安装脚本来进行安装:
curl -fsSL https://get.docker.com -o get-docker.shsudo sh get-docker.sh# 出自官方文档:https://docs.docker.com/install/linux/docker-ce/debian/#install-using-the-convenience-script
这个一键安装脚本理论上来讲所有 Linux 发行版都可以使用,毕竟已经出来很长时间了,如果不行的话请自行使用搜索引擎查找相关资料。
装好 Docker 之后,你有两个选择:
- 进入体验模式,了解一下具体操作细节是怎么样的。
启动容器
体验的话,我们就直接这么启动一个 Docker 容器吧,执行以下命令:
sudo docker run -it --rm --privileged -p 3128:3128 ubuntu:18.04 bash
上面这条命令的意思是,启动一个内部系统为 Ubuntu18.04 的容器,并进入容器内部的 Shell 执行 bash 命令,如果退出 bash 就自动销毁容器;然后映射容器内的端口3128到外界,映射出来的外界端口也是3128;最后 privileged参数是开启特权模式,用于将 卡设备映射进容器内。
如果下载镜像很慢的话,可以搜一下“Docker 加速器”,也可以直接扶墙。
测试一下 卡是否正常
进入容器内部后,我们可以执行一下 ls /dev/ttyUSB* 看一下 卡有没有正常被识别出来(在容器外也是一样的,因为开了特权模式),如果是和我买的同一款 4G 卡的话,在只插入一张 卡的情况下你会看到4个 ttyUSB 设备。
不同 4G 卡和硬件组合可能会有差异,请以实际情况为准。
如果你可以看到4?4G 卡个数个 ttyUSB 设备的话,就说明没有问题,可以开始下一步了。
拨 上
接下来要做的就是拨 了,拨 方面可以选择使用 Wvdial 这种工具,也可以选择使用像 Fanconn 这样的商家提供的拨 脚本(直接调用 PPPD),使用起来的效果会有一些区别。如果商家没有提供拨 脚本的话,就用 Wvdial 吧,它能自动生成配置,上手即用。
我这边的话,由于 Fanconn 的技术人员直接提供了个拨 脚本,那我就用这个脚本了,Wvdial 的文档 上有很多很详尽的,这里就不再多提,需要的朋友自行搜索即可。
如果你用的是 Fanconn 的这个拨 脚本(怎么弄进容器内就不用我说了吧?),那么直接在 apt install ppp 安装好拨 工具之后,用 chmod +x quectel-pppd.sh 给拨 脚本加个运行权限,然后 ./quectel-pppd.sh /dev/ttyUSB3 即可。
拨 时使用的 /dev/ttyUSB3 是指 4G 卡的第四个通信端口,文档中的解释为:ttyUSB3→For PPP connections or AT command communication,翻译一下就是用于 PPP 连接或 AT 命令通信。
拨 之后用 ifconfig 之类的工具即可看到类似下图中的状态:
可以看到,如前文所述,现在有三个 卡,一个是 Docker 自己的、一个是本地环回接口(这个不用管)、一个是拨 产生的虚拟 卡。
如果不是在 Docker 容器内使用的话,还会有个 wwan0(或其他名字),那个是 4G 卡本体。
测试是否能正常上
现在如果你用 curl 的 –interface 参数指定虚拟 卡进行请求的话(如:curl –interface ppp0 https://ip.cn),是已经可以请求成功的了,IP 也会是你所使用的 SIM 卡对应的运营商分配的。
由于 Docker 的镜像通常都是极度精简的,所以 Ubuntu 镜像里并没有预装像 net-tools、iputils-ping、vim、curl 之类的这些包,需要自行安装。所以如果你发现 ifconfig、ping、curl、vim 用不了,不要惊慌,这是正常现象,执行 apt install 包名 命令安装即可。
如果你无法直接请求成功的话,就可能是 DNS 解析出问题了,可以尝试 ping 一个公 IP(如:ping 1.1.1.1)和一个域名(如:ping ip.cn),如果 IP 能 ping 通但域名会 DNS 解析失败的话,就可以确认是 DNS 设置问题了。
4G 拨 时如果出现 DNS 设置问题,通常是因为拨 工具没有正常地将运营商返回的 DNS 服务器设置写入到配置中,我们可以手动配置一下(你要强制指定某一个 DNS 也可以):
# 以下为阿里云的公共DNSecho 'nameserver 223.5.5.5' >> /etc/resolv.confecho 'nameserver 223.6.6.6' >> /etc/resolv.conf
在 Docker 容器中,这个 /etc/resolv.conf 文件可能还会有两条内容,是容器本身所需要的,建议不要删除/覆盖,否则会出现容器间无法使用容器名互相通信的情况。
启动代理服务器
那么在测试拨 后确实可以通过 4G 卡上 了之后,我们就可以把代理服务器启动了,这里我使用的是 TinyProxy。
测试发现,Squid 对资源的占用更大一些,不利于多 卡情况下的使用,会影响到 4G 卡的数量上限。
先 apt install tinyproxy 一波,然后 vim
/etc/tinyproxy/tinyproxy.conf 修改一下配置。
要修改的配置主要有:
改完之后保存一波,然后就可以直接执行 tinyproxy 启动了…吗?
等等,还有一个操作要做!那就是将默认路由指向到虚拟 卡上,很简单,执行以下命令即可:
route del -net 0.0.0.0 eth0route add -net 0.0.0.0 ppp0
这两条命令的意思是:先将默认的、指向 eth0 这个 卡的上 路由删除,然后添加一个同样的、指向 ppp0 这个 卡的路由。
改完默认路由后的效果就是,即使你不使用 curl 的 –interface 参数,也能直接使用 4G 卡上 了。
如果没有改默认路由的话,在不指定 卡的情况下,4G 卡并不会被使用到,因为默认路由指向的是 Docker 自身的虚拟 卡,那个 卡通向你原本的内 环境。也就是说,IP 不会变!
那么现在,你可以执行 tinyproxy 启动代理服务器了。
测试代理服务器
好了,代理服务器应该已经正常启动了,现在我们可以在另一个设备上尝试连接那个容器中的代理服务器,看看是否能正常通过它使用 4G 卡上 。
例如我这里树莓派分配到的IP是:192.168.137.66,那么我就可以用这样的 curl 命令或 Python 代码进行测试:
curl:
curl "https://ip.cn"curl -x "192.168.137.66:3128" "https://ip.cn"
Python:
import requestsresp = requests.get("https://ip.cn", proxies={"https": "http://192.168.137.66:3128"})no_proxy_resp = requests.get("https://ip.cn")print(resp.text)print(no_proxy_resp.text)
测试出来的结果应该与前面在容器内部测试时的一致,在使用代理后 IP 就变成了运营商分配的基站 IP。
更换 IP
那么最核心的问题来了,怎么更换 IP 呢?
其实和使用那些拨 VPS 架设代理服务器一样,我们只需要重新拨个 就能换 IP 了,直接 kill 掉 pppd 进程就可以让它断开拨 ,断开后重新执行一遍拨 脚本就是重新拨 了。
断开拨 方面 Fanconn 的技术人员也提供了一个脚本,同样在 chmod +x quectel-ppp-kill 赋予运行权限之后,执行 ./quectel-ppp-kill 就可以了。
但需要注意的是,蜂窝 络的拨 在断开后,IP 仍然会保留一段时间(具体多久不清楚,可能跟连接的基站也有关系),所以我们需要强制性地让 卡重新搜 。
冷门小知识:手机上开启关闭飞行模式的效果就是重新搜 ,通常只是关闭“移动数据”的话,效果是与断开拨 一致的。
怎么做呢?很简单,就两行命令:
AT+CFUN=0AT+CFUN=1
但注意哦,这是 AT 命令,不是 Linux 下的 Shell 命令,AT 命令是一种调制解调器命令语言,我们如果需要将它执行起来,需要这么做:
echo "AT+CFUN=0" > /dev/ttyUSB2# 中间间隔1秒左右echo "AT+CFUN=1" > /dev/ttyUSB2
这里使用的 /dev/ttyUSB2 是指 4G 卡的第三个通信端口,文档中的解释为:ttyUSB2→For AT command communication,与第四个通信端口类似,只是它不能用于 PPP 连接、只能用于 AT 命令通信而已。
不同样使用第四个通信端口的原因是那个端口有被占用的可能性,直接区分开最稳妥,本来 卡也就是提供了两个 AT 命令通信渠道的。
在使 卡重新搜 后的几秒至十几/几十秒内的时间里,你无法正常拨 ,需要等待它初始化完成后才可以拨 成功,具体等待时间以信 强度为准,我测试的时候通常5秒以内就可以了。
所以如果你在断开后一直拨 失败,不妨过一会儿再试。
总结
那么现在操作流程也跑通了,我们也了解到了整个的内部细节,最后要做的就是把每个 卡都分别分配一个容器,这样我们就能实现文章开头所提到的——“使用虚拟 卡作为出 卡,并使用接入内 的实体 卡作为入 卡”的效果了。
实际操作起来的话,就是把指定 卡的部分给配置化,然后在启动容器的时候传入就好了,使用 Docker 的容器环境变量相关设置可以很轻松地实现这个功能。
最后,我们可以以这个思路,构建一个 docker-compose 模板,模板的核心内容一是做个简易的4G 卡容器集群,二是启动个 Squid,用来聚合代理服务器,这样我们使用的时候只需要指定一个代理服务器就能随机更换了,操作起来更加方便。
评价
最后的最后,我给这个搭建方式打个评价吧。
这个搭建方式并不完美,因为变量太多,而且很多地方肯定不如系统级原生支持的那么稳定,长期使用可能会出现各种奇奇怪怪的问题。
然后 Docker 的资源占用其实挺高的,会浪费相当多的内存在启动容器上,如果只是两三个 卡还好,如果数量大一点的话,像树莓派2B 这种小内存的设备根本就扛不住。
另外代理服务器本身对资源的消耗也是比较高的,高频调用下对树莓派2B 的小 CPU 压力还是蛮大的,即使我对它的 CPU 进行了超频,在并发测试时也还是会出现轻松打满 CPU 的情况。
但是!截止目前,我还有两种基于路由器系统的搭建方案没写出来!所以…敬请期待后续的其他搭建方案(斜眼笑)。
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!