解决双栈网络下 HTTP代理和Socket5默认响应IPV6

1. 背景

在我日常维护IPV4代理池的时候,进行增量代理池完毕后,对新的代理IP进行测速验证的时候发现,使用代理返回的数据虽然是我的代理服务器的IP,但却不是IPV4,而是IPV6。

image.png

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)

这条命令我用的是Ipv40.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地址的响应了

最后修改:2023 年 10 月 05 日
如果觉得我的文章对你有用,请随意赞赏