【教程】指定分配网段内任意 IPv6 作为出口 IP

背景

最近爬虫时想要用自建 ip 池,然后研究了下怎么充分利用 ipv6。
因为一般家用的都会分配一整个段,比如说 /64,那么出口 IP 就有 2^{64} 个。类似地,如果分配的是 /96,那么出口 IP 就有 2^{32} 个。
如果爬虫的目标站点风控策略比较松,比如说,不封禁整个 /64 段,而是只封单个 IP,那么理论上这个方式可以实现爬虫 IP 自由。

搜了些教程,感觉有点乱,所以这里简单整理了自己折腾的过程。既是备忘,也希望能帮到有类似需求的伙伴。
顺带写了个简单的 Python requests 用例供参考。
目前这里只包含了最简单的实现无限ipv6的过程,后面用 nginx 或 openresty 之类实现高可用的部分,可以等楼主进一步研究折腾完再继续更新。

原文章地址在这:https://hansimov.github.io/blog/notes/ipv6-interface.html
非引流(都是个人向的笔记),主要是更新会比较及时(修正笔误、添加说明等),格式也美观些。当然站里的这个贴子我也会定期同步。

下面是正文:


指定任意 IPv6 作为出口 IP

参考资料

查看 ipv6 地址

ip -6 addr show scope global

输出形如:

2: eno1: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 240?:????:????:????:abcd:1234:5678:90ab/64 scope global temporary dynamic
       valid_lft 258952sec preferred_lft 85972sec
    inet6 240?:????:????:????:1234:5678:abcd:1124/64 scope global temporary deprecated dynamic
       valid_lft 258952sec preferred_lft 0sec
    inet6 240?:????:????:????:7890:3456:abcd:0101/64 scope global dynamic mngtmpaddr noprefixroute
       valid_lft 258952sec preferred_lft 172552sec

可以看到,240?:????:????:????::/64 是分配到的 ipv6 网段。

三大运营商的 ipv6 地址开头:

  • 中国联通:2408
  • 中国移动:2409
  • 中国电信:240e

添加路由

将上面的获得的 ipv6 网段添加到路由表中:

ip route add local 240?:????:????:????::/64 dev eno1
  • 将 240?:????:????:????::/64 替换为实际的 ipv6 网段
  • 将 eno1 替换为实际的网卡名称
  • 这里的 dev 是 device 的缩写,表示指定网络接口设备

查看路由

ip -6 route show

形如:

::1 dev lo proto kernel metric 256 pref medium
240?:????:????:???::/64 dev eno1 proto ra metric 100 pref medium
240?:????:????:???::/60 via fe80::1 dev eno1 proto ra metric 100 pref high
fe80::/64 dev ????? proto kernel metric 256 pref medium
fe80::/64 dev eno1 proto kernel metric 1024 pref medium
default via fe80::1 dev eno1 proto ra metric 100 pref medium

如果只想显示公网地址,可以过滤掉包含 fe80:: 和 lo 的地址:

ip -6 route show | grep -v 'fe80::' | grep -v 'lo'

输出形如:

240?:????:????:???::/64 dev eno1 proto ra metric 100 pref medium

启用 ip_nonlocal_bind

sudo nano /etc/sysctl.conf

在文件末尾添加内容并保存:

net.ipv6.ip_nonlocal_bind = 1

使配置生效:

sudo sysctl -p

安装 ndppd

sudo apt install ndppd

配置 ndppd

sudo nano /etc/ndppd.conf

添加内容:

route-ttl 30000
proxy eno1 {
    router no
    timeout 500
    ttl 30000
    rule 240?:????:????:???::/64 {
        static
    }
}
  • 将 eno1 替换为实际的网卡名称
  • 将 240?:????:????:????::/64 替换为实际的 ipv6 网段

启动 ndppd

sudo systemctl start ndppd

设置开机自启:

sudo systemctl enable ndppd

测试出口地址

随机选择一个同网段下的 ipv6 地址,测试出口 IP:

curl --int 240?:????:????:????:abcd:9876:5678:0123 http://ifconfig.me/ip
  • --int 是 --interface 的缩写,用于指定出口 IP

如果之前的步骤都正确,输出的 ipv6 地址应该和 --int 指定的相同,形如:

240?:????:????:????:abcd:9876:5678:0123

Python 示例

运行:

python ip_tester.py

输出形如:

> IPv6 prefix: [240?:????:????:????] (/64)
  > Set: [ipv4]
  * Get: [???.???.???.???]
  > Set: [240?:????:????:????:f618:ad3a:fd1a:f0d0]
  * Get: [240?:????:????:????:f618:ad3a:fd1a:f0d0]
  > Set: [240?:????:????:????:410b:9770:6504:de53]
  * Get: [240?:????:????:????:410b:9770:6504:de53]
  > Set: [240?:????:????:????:b05b:87b2:26b4:15f3]
  * Get: [240?:????:????:????:b05b:87b2:26b4:15f3]
  > Set: [240?:????:????:????:d5bc:58c9:dd74:b45]
  * Get: [240?:????:????:????:d5bc:58c9:dd74:b45]
60 个赞

可以更进一步,在每个v6出口后再套一个warp

5 个赞

感谢分享大佬厉害啊

4 个赞

因为现在限制已经加到/48段了

2 个赞

谢谢回复!想问下套了 WARP 对连接速度影响大不?

看实现了,主要目的是拿ipv6再拿一个ipv4

2 个赞

实用。还是第一次看见这样子的内容

2 个赞

感谢分享,原来还能自己换ip

感谢分享 :melting_face:

感谢分享这个好的教程

看不懂,点赞先

马住,感谢大佬分享

感谢分享,收藏了,回头研究一下

感谢分享大佬厉害啊

当然是封 ipv6 段了啊。

2 个赞

感谢佬友分享

1 个赞

这个思路确实不错,国内大部分网站应该不会封ipv6

2 个赞

同一个地方的warp出来ipv4是不是一样

1 个赞

感谢大佬教程

感谢分享,有需要学习了