Mobile wallpaper
1333 字
7 分钟

创建自己的2^64个IP的代理池

2025-07-22
浏览量 加载中...
本文主要内容

/64 IPv6 地址块的服务器上部署 go-proxy-ipv6-pool 随机出口 IP 代理服务。解决运行后却遭遇的 connection timed outcannot assign requested address 错误。这通常不是代理程序本身的问题,而是服务器网络环境没有进行正确配置。

本文将详细记录从零开始部署一个 Go IPv6 代理池,并彻底解决其网络连接问题的全过程。

组件说明#

  • Golang:运行项目。
  • ndppd:类似于 IPv4 中 ARP 协议的作用,IPv6 中需要使用 ND 协议来发现邻居并确定可用路径。

部署流程#

基本步骤#

第一步:基础环境和代理程序准备#

首先,我们需要准备好 Go 环境并下载代理程序项目。

1. 安装 Go 语言环境

Terminal window
# 下载 Go (请到官网 https://go.dev/dl/ 获取最新版链接)
wget https://go.dev/dl/go1.22.3.linux-amd64.tar.gz
# 解压到 /usr/local
sudo tar -C /usr/local -xzf go1.22.3.linux-amd64.tar.gz
# 将 Go 的二进制文件路径添加到环境变量
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.profile
source ~/.profile
# 验证安装
go version

2. 克隆项目并准备运行脚本

Terminal window
# 克隆项目
git clone https://github.com/XiaoMiku01/go-proxy-ipv6-pool.git
cd go-proxy-ipv6-pool
# 创建一个便捷的 run.sh 脚本
cat << 'EOF' > run.sh
#!/bin/bash
# 将 Go 的缓存目录设置在当前项目下,避免污染系统
export GOMODCACHE="$(pwd)/.gomodcache"
export GOCACHE="$(pwd)/.gocache"
mkdir -p $GOMODCACHE
mkdir -p $GOCACHE
echo "--- Using local Go caches ---"
echo "Module Cache: $GOMODCACHE"
echo "Build Cache: $GOCACHE"
echo "-----------------------------"
# 以 root 权限运行 Go 程序,并将所有脚本参数传递给它
# 注意:后面的网络配置需要程序以 root 权限运行来绑定 IP
# 如果不使用自动绑定IP的修改版,可以不用 sudo
sudo go run . "$@"
EOF
# 赋予脚本执行权限
chmod +x run.sh

第二步:核心网络配置#

这是解决所有网络问题的核心。我们需要从内核 Socket 层、路由层到数据链路层进行“三板斧”配置。

1. 内核参数:允许绑定非本地 IP (解决 cannot assign requested address)

  • 问题:默认情况下,Linux 内核不允许程序绑定到一个尚未明确分配给网络接口的 IP 地址。
  • 解决方案:修改 net.ipv6.ip_nonlocal_bind 参数。
Terminal window
# 临时启用(用于测试,重启后失效)
sudo sysctl -w net.ipv6.ip_nonlocal_bind=1
## 同时修改下其他参数
sudo sysctl -w net.ipv6.conf.all.forwarding=1
sudo sysctl -w net.ipv6.conf.default.forwarding=1
# 永久生效
sudo tee -a /etc/sysctl.conf <<EOF
net.ipv6.ip_nonlocal_bind=1
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.default.forwarding=1
EOF \
&& sudo sysctl -p

2. 本地路由:告知内核 /64 网段归本机所有 (解决出站路由)

  • 问题:内核需要知道它可以从 /64 地址池中的任意 IP 发出数据包。
  • 解决方案:添加一条本地路由规则。
Terminal window
# 临时添加(用于测试,重启后失效)
# 将 <your_ipv6_cidr> 替换为你的网段
# 将 <interface> 替换为你的网卡名,例如 eth0
sudo ip route add local <your_ipv6_cidr> dev <interface>
# 永久生效
sudo nano /etc/network/interfaces.d/xx-cloud-init
# 找到 iface eth0 inet6 static 这部分,在它的末尾添加 post-up 命令。post-up 的意思是“当这个接口成功启动后,执行以下命令”。
# ... (前面的配置不变) ...
# control-alias eth0
iface eth0 inet6 static
address xxxxx
gateway xxxxx
# 在这里添加 post-up 命令
post-up ip route add local <your_ipv6_cidr> dev <interface>
# 重启服务
sudo systemctl restart networking.service

3. NDP 代理:响应路由器的邻居请求 (解决入站路由和 connection timed out)

  • 问题:当外部服务器响应你的请求时,你的服务商路由器需要通过邻居发现协议(NDP)找到你那个随机 IP 对应的 MAC 地址。默认情况下,你的服务器不会对未明确绑定的 IP 进行应答。
  • 解决方案:使用 ndppd (NDP Proxy Daemon) 自动应答所有来自你子网的 NDP 请求。
Terminal window
# 安装 ndppd
sudo apt install -y ndppd
# 编辑配置文件
sudo nano /etc/ndppd.conf
# 清空文件内容,然后粘贴以下为你定制的配置
# 同样,替换 <your_ipv6_cidr> 和 <interface>
# --- ndppd.conf start ---
route-ttl 30000
proxy <interface> {
router no
timeout 500
ttl 30000
rule <your_ipv6_cidr> {
static
}
}
# --- ndppd.conf end ---
# 重启并设置开机自启
sudo systemctl restart ndppd
sudo systemctl enable ndppd
# 检查服务状态,确保 active (running)
sudo systemctl status ndppd

第三步:启动代理并进行最终测试#

所有配置完成后,我们可以启动代理并验证它是否按预期工作。

1. 启动代理服务go-proxy-ipv6-pool 目录下执行:

Terminal window
# 假设你的 HTTP 代理端口是 52122,SOCKS5 是 52123
# CIDR 替换成你自己的
./run.sh --port 52122 --cidr <your_ipv6_cidr>

2. 循环测试 打开一个新的终端窗口,运行下面的命令来持续测试代理,并观察出口 IP 是否在变化:

Terminal window
# 将端口号 52122 替换为你自己设置的 HTTP 端口
while true; do
curl -s \
-w "\n--- Timing Info ---\nHttpCode: %{http_code}\nTotal Time: %{time_total}s\n---------------------\n" \
-x http://localhost:52122 \
--connect-timeout 5 \
ipv6.ip.sb
sleep 0.5
done

如果一切正常,你将看到屏幕上不断打印出不同的、来自你 /64 地址池的 IPv6 地址,并且没有任何报错。

结论#

部署一个功能完备的 IPv6 代理池,关键不在于应用本身,而在于对底层网络环境的深刻理解和正确配置。通过 ip_nonlocal_bindlocal routendppd 这“三板斧”,我们成功地解决了从内核到网络的各层障碍,实现了应用的预期功能。希望这篇指南能帮助到遇到同样问题的朋友们。

最后更新于 2025-07-22,距今已过 117 天

部分内容可能已过时

评论区

目录