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:

ping pythonhosted.org

而众所周知一个双栈机器 (同时启用 IPv4 协议栈和 IPv6 协议栈的机器) 默认是 ipv6 优先的, 可能是为了推广 IPV6 之类的考虑吧…

当然这种优先级是可以通过修改配置文件改变的, 本文就讲讲今天研究的两种常见方式

如何手动配置 IPV4 / IPV6 优先

1 - gai.conf

基本上所有 Linux 发行版都使用 /etc/gai.conf 来管理 getaddrinfo 的行为, 而所有需要域名解析的地方都需要用到 getaddrinfo , 因此修改这个配置文件就可以从根本上解决系统的 ipv4 / ipv6 优先级问题.

简而言之, 直接编辑 /etc/gai.conf, 取消注释或者添加这一行:

1
precedence ::ffff:0:0/96  100

即可设置成 ipv4 优先.

或者直接一行命令 sed 修改:

1
sed -i 's/#precedence ::ffff:0:0\/96  100/precedence ::ffff:0:0\/96  100/' /etc/gai.conf

1.1 - 这行配置做了什么

  • precedence: 表示是在配置优先级
  • 100: 数字越大, 优先级越高
  • ::ffff:0:0/96: 这是一个特殊的 IPv6 地址前缀, 用于表示 IPv4-mapped IPv6 地址空间, 简而言之, 就是告诉系统, 当遇到同时支持 IPv4 和 IPv6 的地址时, IPV4 地址的优先级

例子:

1
2
precedence ::ffff:0:0/96  100    # IPv4-mapped IPv6 addresses
precedence ::/0 10 # 所有 IPv6 addresses

在这个配置中:

  1. 当一个域名同时有 IPv4 和 IPv6 记录时
  2. IPv4 地址会被映射成 IPv4-mapped IPv6 address(即 ::ffff:0:0/96 格式)
  3. 由于其优先级 100 大于纯 IPv6 地址的优先级 10
  4. 系统会优先使用 IPv4 地址进行连接

2 - 禁用 ipv6

出于某些原因我们可能完全不想要 ipv6, 这时可以直接彻底禁用网卡的 ipv6, 方式:

1
2
3
4
5
6
7
8
9
10
cat >> /etc/sysctl.conf << EOF
net.ipv6.conf.all.autoconf = 0
net.ipv6.conf.default.autoconf = 0
net.ipv6.conf.all.accept_ra = 0
net.ipv6.conf.default.accept_ra = 0
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
net.ipv6.conf.eth0.disable_ipv6 = 1
EOF

来修改 /etc/sysctl.conf

然后通过 sysctl -p 来重新加载配置文件, 这时 ipv6 就已经被彻底禁用. (还原的话直接删除这几行或者把0, 1反过来就ok)


Linux 系统 IPV4/IPV6 优先级配置 (gai.conf)
https://moreality.net/posts/12422/
作者
Moreality
发布于
2024年12月11日
许可协议