解决双栈网络下 HTTP代理和Socket5默认响应IPV6
1. 背景
在我日常维护IPV4代理池的时候,进行增量代理池完毕后,对新的代理IP进行测速验证的时候发现,使用代理返回的数据虽然是我的代理服务器的IP,但却不是IPV4,而是IPV6。
2.分析
因为我使用的代理工具是gost
github
: GO Simple Tunnel)
我首先在issues里面进行反馈了一波,然后我又换了 squid 进行搭建同样也是这个问题
所以这大几率不是gost
的问题
我尝试了gost的几种不同的参数
./gost -L=user:[email protected]:3727 &
root@dev:~# lsof -i:3727
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
lost 24419 root 6u IPv6 9046580 0t0 TCP *:3727 (LISTEN)
这条命令我用的是Ipv4
的0.0.0.0
指的自己外网服务IP,所以这里Type返回的是IPV6我很不理解
于是我尝试换一种方式
./gost -L=user:[email protected]:3727
这次返回的结果和上次不大一样
root@dev:~# lsof -i:3727
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
gost 30534 root 6u IPv4 9078916 0t0 TCP dev.lan:3727 (LISTEN)
这次返回的Type是Ipv4,于是我打开IDEA 写了个方法去调用 这个代理
@Test
public void testProxy(){
final int proxyPort = 8080;
final String proxyHost = "1.1.1.1";
final String username = "user";
final String password = "password";
Authenticator proxyAuthenticator = new Authenticator() {
@Override
public Request authenticate(Route route, Response response) throws IOException {
String credential = Credentials.basic(username, password);
return response.request().newBuilder()
.header("Proxy-Authorization", credential)
.build();
}
};
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)))
.proxyAuthenticator(proxyAuthenticator)
.build();
OkHttpUtils.setOkhttpClient(client);
JSONObject json = OkHttpUtils.getJson("https://ip.gs/json");
log.info("json{}", json);
}
这里打印返回的json还是IPV6
{
"country":"China",
"country_eu":false,
"city":"****",
"ip":"******", // IPV6
"latitude":**.1987,
"time_zone":"Asia/Shanghai",
"ip_decimal":993200**,
"asn_org":"Chinanet",
"region_name":"***an",
"asn":"AS4*3*",
"country_iso":"CN",
"user_agent":{
"product":"Mozilla",
"raw_value":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36",
"comment":"(Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36",
"version":"5.0"
},
"region_code":"H*",
"longitude":****
}
在这个时候我突然想到 我这个服务器是双栈网络,即 IPv4 协议栈和 IPv6 协议栈,而IPV6的优先级是要比IPV4要高的。PS(所有现代化的操作系统和浏览器均会以 IPv6 优先)
我马上使用curl
去进行测试
root@dev:~# curl ip.sb
240e:381:****:****:***:****:****:***/64
果然默认是使用的ipv6进行互联的
3.修改配置
IPV4优先
在 Debian 等 Linux 系统下,有一个 /etc/gai.conf
文件,用于系统的 getaddrinfo
调用,默认情况下,它会使用 IPv6 优先 ,如果你不想使用 IPv6 优先,可以在这个文件中找到:
#precedence ::ffff:0:0/96 100
取消注释,修改为:
precedence ::ffff:0:0/96 100
Sed 修改
sed -i 's/#precedence ::ffff:0:0\/96 100/precedence ::ffff:0:0\/96 100/' /etc/gai.conf
reboot
重启以后开机 再进行测试
root@debian ~ # curl ip.sb
**.***.**.** // ipv4
IPV6优先
有时候又需要IPv6 优先(IPV6大型代理池)因为宽带一般分配一条/64的IPV6 容量大可以尽情的换!我们就可以这样做,加入这两行提高IPV6的优先级
label 2002::/16 1
label 2001:0::/32 1
再次测试 代理池已经成功是返回的IPV4
地址的响应了
此处评论已关闭