Linux 系统 IPV4/IPV6 优先级配置 (gai.conf)
本文最后更新于 2024年12月11日 晚上
事情起因
Mac 上一直用的一台 G 口 Oracle 作为出口的代理来上网, 结果发现每次用 Oracle 的出口进行 pip
安装包时都特别慢, 速度大概 100KBps 不到, 换其他的出口就一点问题都没有, 之前尝试过换 DNS 也没啥用.
也测试过到 pypi.org
这个源的 ICMP, 也没发现什么问题.
结果今天仔细研究了一下, 发现 pip
的安装逻辑大概是这样的:
- pip 首先访问
pypi.org
获取包的元数据 - 然后会被重定向到
files.pythonhosted.org
这个 CDN 服务器下载实际的包文件 files.pythonhosted.org
是 PyPI 的文件托管服务,用于存储和分发包文件
然后我尝试在 oracle 机器上 ping 一下 pythonhosted.org
, 结果发现 ipv6 居然没有 CDN, 延迟高达 160MS:
而众所周知一个双栈机器 (同时启用 IPv4 协议栈和 IPv6 协议栈的机器) 默认是 ipv6 优先的, 可能是为了推广 IPV6 之类的考虑吧…
当然这种优先级是可以通过修改配置文件改变的, 本文就讲讲今天研究的两种常见方式
如何手动配置 IPV4 / IPV6 优先
1 - gai.conf
基本上所有 Linux 发行版都使用 /etc/gai.conf
来管理 getaddrinfo
的行为, 而所有需要域名解析的地方都需要用到 getaddrinfo
, 因此修改这个配置文件就可以从根本上解决系统的 ipv4 / ipv6 优先级问题.
简而言之, 直接编辑 /etc/gai.conf
, 取消注释或者添加这一行:
1 |
|
即可设置成 ipv4 优先.
或者直接一行命令 sed 修改:
1 |
|
1.1 - 这行配置做了什么
precedence
: 表示是在配置优先级100
: 数字越大, 优先级越高::ffff:0:0/96
: 这是一个特殊的 IPv6 地址前缀, 用于表示 IPv4-mapped IPv6 地址空间, 简而言之, 就是告诉系统, 当遇到同时支持 IPv4 和 IPv6 的地址时, IPV4 地址的优先级
例子:
1 |
|
在这个配置中:
- 当一个域名同时有 IPv4 和 IPv6 记录时
- IPv4 地址会被映射成 IPv4-mapped IPv6 address(即
::ffff:0:0/96
格式) - 由于其优先级 100 大于纯 IPv6 地址的优先级 10
- 系统会优先使用 IPv4 地址进行连接
2 - 禁用 ipv6
出于某些原因我们可能完全不想要 ipv6, 这时可以直接彻底禁用网卡的 ipv6, 方式:
1 |
|
来修改 /etc/sysctl.conf
然后通过 sysctl -p
来重新加载配置文件, 这时 ipv6 就已经被彻底禁用. (还原的话直接删除这几行或者把0, 1反过来就ok)