当你需要固定抓取某个某网站内容时,降低抓取速度防止IP被封是第一要做的事情。但有的时候,你又必须提升你的抓取速度的时候,就需要来伪装你的IP了。第一想到的当然是免费代理,但是免费代理质量及其不靠谱,几乎等于无法使用。可以购买付费代理,没有用过付费代理,据说质量也不是很稳定,需要一套代理定时检测系统。这是一种解决方案,本文给出的是另一种解决方案,通过拨号VPS来获得不同IP。
拨号vps
买一台可拨号的vps,这样理论上你就有无限的IP地址。其实当你知道了拨号vps,那么伪装IP这事其实就可以认为结束了,后面只是你用什么方案来使用它了。
方案一
将抓取服务直接部署到拨号vps上,从架构上说,我们会需要多个代理服务,但我们服务并不需要多个,而且在拨号期间,服务器不可用,显然不是一个好方案。
方案二
拨号vps作为代理服务器,抓取服务仍然在业务服务器上,走代理进行抓取,这应该是比较合理的方案。
因为拨号vps需要定时更新IP,抓取服务如何正确知道当前拨号vps的IP地址?这里就有很多方法可以达到这个目的。
拨号vps每次拨号完成以后,将IP地址写入公共读取的地方,抓取服务每次从公共读取的地方拿到当前代理服务。
比如,每次拨号完成后,拨号vps访问业务服务器的一个接口,接口将传过来的IP放到redis/mysql之类的,抓取服务每次从这里拿。
这是一个蛮简单实用的方案,只要你有2台拨号vps,取到第1个代理不能用(可能在拨号中,IP更新比及时),再去取第2个代理。
这个方案加了很多与业务无关的代码,对使用方不透明。
本文要讨论的是,利用wireguard的特性,将拨号vps和代理服务器组成一个内网,通过固定的内网IP进行访问,从而对应用方屏蔽了动态IP这件事。
wireguard
介绍
- 简单,速度快,udp包
- 密钥路由:每个网络接口都有一对公钥和私钥,所以支持IP漫游
安装
根据官方文档很容易安装(https://www.wireguard.com/install/)
我的系统是centos7
$ sudo curl -Lo /etc/yum.repos.d/wireguard.repo https://copr.fedorainfracloud.org/coprs/jdoss/wireguard/repo/epel-7/jdoss-wireguard-epel-7.repo
$ sudo yum install epel-release
$ sudo yum install wireguard-dkms wireguard-tools
安装完需要重启机器,否则会提示“modprobe: FATAL: Module wireguard not found”
在文件/etc/sysctl.conf中添加 net.ipv4.ip_forward = 1
有大牛提供了centos7一键安装的脚本https://www.atrandys.com/2018/886.html,本人没有测试过,看代理应该work的,有兴趣的可以测试一下
配置
假设现在我们有2台机器,1台业务ecs + 1台拨号vps
-
分别生成2台机器所需要的密钥对
wg genkey | tee sprivatekey | wg pubkey > spublickey wg genkey | tee cprivatekey | wg pubkey > cpublickey
sprivatekey + spublickey 用于业务ecs
cprivatekey + cpublickey 用于拨号vps
-
修改配置文件
$ mkdir /etc/wireguard/ $ vim /etc/wireguard/wg0.conf
-
业务ecs的配置如下:
[Interface] Address = 10.100.0.2/24 ListenPort = 20326 PrivateKey = {sprivatekey} 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 [Peer] PublicKey = {cpublickey} AllowedIPs = 10.100.0.6/32
业务ecs作为server节点
配置文件分2部分,[Interface]和[peer]
-
[Interface]
可以理解为每一个wiregurad结点都需要表明自己的身份的配置Address - 本结点的内网IP,这个完全可以自己定义 ListenPort - 监听的端口号 PrivateKey - 本结点的私密,在这里只要把上面sprivatekey copy进来就行了 PostUp - wireguard启动起来后执行的命令 PostDown - 这2句话复制黏贴就行了
-
[peer]
PublicKey - 另一个节点的公钥 AllowedIPs - 另一个节点的IP地址
一个配置文件可以有多个[peer],记录了需要和自己进行通讯的节点,因此在本接口发送请求包的时候可以作为路由表,将数据发送到对应IP的结点上;当有需要接受到,可以将解密后的包比较IP,看是否符合。
-
特别注意需要开启端口防火墙
firewall-cmd --zone=public --add-port={port}/udp --permanent
-
拨号vps的配置如下:
[Interface] Address = 10.100.0.6/24 PrivateKey = {cprivatekey} DNS = 223.5.5.5 [Peer] PublicKey = {spublickey} AllowedIPs = 10.100.0.2/32 Endpoint = xxx.xxx.xxx.xxx:20326 PersistentKeepalive = 25
拨号vps作为client端
同样的作为一个节点,vps的配置节点也包含2部分
-
[Interface]
这里可以不用设置监听的端口 DNS 设置为正常的DNS就行
-
[peer]
PublicKey - 另一个节点的公钥 Endpoint - server对外的公网IP及监听的端口号 AllowedIPs - 这里也可以设置为 0.0.0.0/0, ::/0, 表示转发所有流量 PersistentKeepalive - 每隔多久去检查连接
以上我们2台机器的配置都准备好了,下面开始启动服务
-
启动
利用命令工具wg-quick来操作
wg-quick up wg0 - 启动
wg-quick down wg0 - 停止
当启动完成后,执行 wg 命令可以查看当前wireguard的状态
在业务ecs上执行wg命令,可以看到
interface: wg0
public key: [***********server public key***********]
private key: (hidden)
listening port: 20326
peer: [***********client public key***********]
endpoint: xxx.xxx.xxx.xxx:49292
allowed ips: 10.100.0.6/32
latest handshake: 1 minute, 54 seconds ago
transfer: 39.95 KiB received, 56.32 KiB sent
在拨号vps上执行wg命令,可以看到
interface: wg0
public key: [***********client public key***********]
private key: (hidden)
listening port: 49292
peer: [***********server public key***********]
endpoint: xxx.xxx.xxx.xxx:20326
allowed ips: 10.100.0.2/32
latest handshake: 14 seconds ago
transfer: 2.12 KiB received, 1.64 KiB sent
persistent keepalive: every 25 seconds
当我们启动完2台机器上的wireguard之后,他们就能通过内网IP互连了
在业务ecs上执行ping操作
[root@server ~]# ping 10.100.0.6
PING 10.100.0.6 (10.100.0.6) 56(84) bytes of data.
64 bytes from 10.100.0.6: icmp_seq=1 ttl=64 time=27.9 ms
64 bytes from 10.100.0.6: icmp_seq=2 ttl=64 time=79.1 ms
64 bytes from 10.100.0.6: icmp_seq=3 ttl=64 time=18.2 ms
在拨号vps上执行ping
[root@adsl ~]# ping 10.100.0.2
PING 10.100.0.2 (10.100.0.2) 56(84) bytes of data.
64 bytes from 10.100.0.2: icmp_seq=1 ttl=64 time=17.8 ms
64 bytes from 10.100.0.2: icmp_seq=2 ttl=64 time=28.5 ms
自此,我们在2台机器上分别启动了wireguard,并且已经互通了。
此时可以手动在拨号vps上执行拨号命令改变其IP,然后在2台机器上分别再执行相同的ping命令,可以看到2台机器仍然能根据wg0网卡上的内网IP连通,因此拨号vps的IP变化完全被屏蔽。
下一步我们就需要在拨号vps上搭代理服务器,业务ecs上通过代理服务上网。可选择的代理服务非常多,这个就看个人选择了,这里选择squid作为代理服务器。
squid
安装
yum -y install squid
配置
配置文件在/etc/squid/squid.conf
acl wg src 10.100.0.2/32
http_access allow wg
http_port 3129
via off
forwarded_for delete
- 大部分参数选择了默认配置,如果有缓存需要,可以自己再修改配置。
- 这里限制了可访问代理的IP,在本配置中限定了单一IP(10.100.0.2),也可以限定网络断 10.100.0.0/24,或者 all
- 最后2句话是设置代理为匿名代理(>3.1版本)
启动
systemctl start squid
此时代理服务器已经启动完毕,我们在业务ecs上通过该代理访问网页了。
[root@server ~]# all_proxy=http://10.100.0.6:3129 curl ip.me5.us
xxx.xxx.xxx.xxx
可以看到从ecs访问网页的IP地址为拨号vps的IP。
如果我们在拨号vps机器上进行拨号操作,仍然可以通过这个代理IP进行访问。
[root@server ~]# all_proxy=http://10.100.0.6:3129 curl ip.me5.us
xxx.xxx.xxx.xxx
对于一般的抓取应用,此时已经可以运行了,可以设置在拨号vps上设置定时任务,比如每小时启动一次。
代理服务在IP拨号的过程中是不可用的,所以我们很有可能会有2台代理服务。如何选择当前可work的代理服务呢?这里在2台拨号代理上面架了一层haproxy,用于负载均衡。
haproxy
介绍
haproxy 提供高可用性、负载均衡,当其代理的后端服务器出现故障, haproxy 会自动将该服务器摘除,故障恢复后再自动将该服务器加入。
为了测试haproxy,我们另外找了一台拨号vps作为wireguard网络的client节点。
在该机器上:
- 安装wireguard并进行配置,设定IP为 10.100.0.3
- 安装squid进行配置
在业务ecs上添加新的peer,此时server端挂载了2个client
[root@server ~]# wg
interface: wg0
public key: [***********server public key***********]
private key: (hidden)
listening port: 20326
peer: [***********client public key***********]
endpoint: xxx.xxx.xxx.xxx:49292
allowed ips: 10.100.0.6/32
latest handshake: 1 minute, 22 seconds ago
transfer: 78.26 KiB received, 99.64 KiB sent
peer: [***********client public key***********]
endpoint: xxx.xxx.xxx.xxx:53837
allowed ips: 10.100.0.3/32
latest handshake: 1 minute, 50 seconds ago
transfer: 35.48 KiB received, 57.26 KiB sent
测试新机器代理服务
[root@server ~]# all_proxy=http://10.100.0.3:3129 curl ip.me5.us
xxx.xxx.xxx.xxx
安装
在业务ecs机器上安装haproxy
yum -y install haproxy
配置
配置文件目录 /etc/haproxy/haproxy.cfg
配置文件分成 global/defaults/frontend/backend/4 部分
global 一般不改动,如果需要配置log目录根据默认配置文件里面的说明配置即可
defaults设置各种超时时间,根据自己服务需要进行设置
-
frontend / backend
这部分设置请求转发的后端服务frontend main *:9500 default_backend proxy backend proxy balance roundrobin server proxy1 10.100.0.6:3129 check server proxy2 10.100.0.3:3129 check
我们将http请求转发到拨号vps的代理服务端口上
-
开定对应端口的防火墙
firewall-cmd --zone=public --add-port=9500/tcp --permanent firewall-cmd --reload
启动
systemctl start haproxy
通过haproxy 进行访问代理服务
[root@server ~]# all_proxy=http://127.0.0.1:9500 curl ip.me5.us
121.227.76.155
[root@server ~]# all_proxy=http://127.0.0.1:9500 curl ip.me5.us
180.175.182.237
如果我们在访问过程中进行拨号操作,可以得到如下日志:
[root@server ~]# for i in $(seq 1 20) ; do all_proxy=http://127.0.0.1:9500 curl ip.me5.us; done
121.227.76.205
180.175.182.237
121.227.76.205
180.175.182.237
121.227.76.205
180.175.182.237
180.175.182.237
180.175.182.237
180.175.182.237
180.175.182.237
180.175.182.237
121.227.76.205
180.175.182.237
121.227.76.205
可以看到在拨号期间,haproxy只访问另一台可用机器,当拨号完成后,重新开始均衡访问。
结尾
以上是当前所有工作,提供了通过拨号vps可行的一种实际可行方案。但其实里面用的工具可以分别用不同的工具代替,包括wireguard,squid,haproxy,相同作用的工具有很多。后续还可以考虑将这些服务docker化。
虎虎管家——把淘宝、天猫的商品一键复制到拼多多店铺中。速度快,不限量,支持整店搬家,商品属性智能匹配,自动填写免费,不用下载,登录后直接使用。