Skip to content

Instantly share code, notes, and snippets.

@KaraRyougi
Last active December 12, 2023 14:57
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save KaraRyougi/5a5158f93b5db5d4c5fe6852bb99ae1d to your computer and use it in GitHub Desktop.
Save KaraRyougi/5a5158f93b5db5d4c5fe6852bb99ae1d to your computer and use it in GitHub Desktop.
IPv6 完全随机化连接

使用整段 IPv6 以避免被墙的设置方案:

服务端

假设我们拥有 2602:feda:db8::/48 这段 IPv6 地址,且该段地址被静态路由至我们的服务器。

首先配置防火墙,详略。

将整段 IPv6 地址配置至服务器:

ip -6 route add local 2602:feda:db8::/48 dev lo

使用 CloudFlare 的 tubular 来监听/转发:

cd go/bin
export ASSUME_NO_MOVING_GC_UNSAFE_RISK_IT_WITH=go1.18
./tubectl bind ss-tcp tcp 2602:feda:db8::/48 0
./tubectl bind ss-udp udp 2602:feda:db8::/48 0
pid=$(pidof ss-server)
./tubectl register-pid $pid ss-tcp tcp ::1 2048
./tubectl register-pid $pid ss-udp udp ::1 2048

这里假设我们已经安装了 tubular,且 shadowsocks 正在侦听本地地址 ::1 的 2048 端口。

以上操作便将 2602:feda:db8::/48 整段地址中的所有端口均转发至本地 ::1 的 2048 端口。此段 /48 IP 中的任意地址、任意端口均可作为服务器连接地址。

客户端

Linux 中指定地址范围的 DNAT 并不随机,而是根据四元组的哈希来得到地址。因此,我们选择定时生成随机 ip6tables 规则。或者可以修改内核以实现真正随机。

生成 ip6tables 规则的 bash 脚本:

ip6tables -t nat -F OUTPUT

for M in {1..100}
do
    net="2602:feda:db8"
    for N in {1..5}
    do
        part=$(($RANDOM+$RANDOM))
        net+=$(printf ":%x" $part)
    done
    ip6tables -t nat -A OUTPUT -d 2001:db8::$M -p tcp -m tcp --dport 1000 -j DNAT --to-destination [$net]:3000-9999 --random
done

以上规则应当定时(如:1 分钟)更新以确保地址分布的随机性。这里我们只使用了 3000 - 9999 的低位端口。

生成 Shadowsocks 规则示意:

for n in range(100):
    print("{\"address\": \"2001:db8::"+f'{n+1:x}'+"\", \"port\": 1000, \"password\": \"LE9TepiTbA0GLARuoNQe\", \"method\": \"chacha20-ietf-poly1305\"},")

以上规则在配置完成后可保持不变,就是你的客户端得支持负载均衡。

附言

AperNet 的随机 IPv6 解锁不是这么做的!不过反正也是个随机化思路了,效果估计没差别。

即便以后一墙一整段也问题不大,毕竟 IPv6 地址实在是太便宜太多了~ 不过本方案主要是给使用 Shadowsocks 的古典派使用的,对于使用 TLS 翻墙的可能没什么帮助。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment