IPv6 (简体中文)
在Arch Linux中,IPv6是默认开启的。如果你需要找IPv6隧道的资料,请看IPv6 tunnel broker setup。
邻居发现
向多播地址ff02::1
发送PING可以获得局域网内所有主机的回应。使用时需要注明网卡:
$ ping ff02::1%eth0
向多播地址ff02::2
发送PING,只有路由器会回应。
在PING时加入选项-I 你的ipv6公网地址
,局域网内的主机会以各自的公网地址回应。这时不必注明网卡:
$ ping -I 2001:4f8:fff6::21 ff02::1
无状态地址自动配置 (SLAAC)
在网络准备好的情况下,获取IPv6地址最简单的方法是通过“无状态地址自动配置”(SLAAC)。地址会自动由路由器给出的前缀推算出,不需要其他配置,也不需要DHCP客户端。
客户端
如果你使用netctl管理网络,那么只需要在网络配置中加入下面这一行:
IP6=stateless
如果使用NetworkManager,它会自动检测网络情况并配置好IPv6.
请注意:只有IPv6 icmp数据包可以经过网络传输时,SLAAC才可以正常工作。所以在要配置IPv6的计算机上,必须修改防火墙,允许ipv6-icmp
数据包进入。如果你使用Simple stateful firewall或iptables,你只需要加入:
-A INPUT -p ipv6-icmp -j ACCEPT
如果你使用了其他防火墙(ufw,shorewall等等),请查阅其文档,允许ipv6-icmp
数据包。
网关
网关需要运行一个守护进程,以确保能够将IPv6地址分发给客户端。一般使用radvd(official repositories)。配置radvd很简单。修改/etc/radvd.conf
,加入如下配置:
# replace LAN with your LAN facing interface interface LAN { AdvSendAdvert on; MinRtrAdvInterval 3; MaxRtrAdvInterval 10; prefix ::/64 { AdvOnLink on; AdvAutonomous on; AdvRouterAddr on; }; };
这些配置可以要求客户端由64位的网络前缀自动推算并配置地址。请注意这些配置允许使用分配到局域网的所有可用的前缀。如果你不打算使用::/64
,需要限制允许使用的前缀,可以注明前缀,例如2001:DB8::/64
。prefix
选项可以重复使用多次,分别记录不同的前缀。
网关必须在所有的方向上允许ipv6-icmp
数据包。如果你使用Simple stateful firewall或iptables,需要加入如下规则:
-A INPUT -p ipv6-icmp -j ACCEPT -A OUTPUT -p ipv6-icmp -j ACCEPT -A FORWARD -p ipv6-icmp -j ACCEPT
使用其他防火墙也需要类似的规则。配置完成后可以开启radvd.service
。
IPv6隐私扩展
当一个客户端使用SLAAC配置其IPv6时,它会使用网络前缀和网卡的MAC地址构造地址。这会引起安全问题:计算机的MAC地址可以轻松通过其IPv6地址推算出。为了解决这个问题,提出了“IPv6隐私扩展”标准(RFC 4941)。使用这个隐私扩展,内核会从原本的IPv6地址计算生成一个“临时地址”。在连接远程服务器时,系统会优先选择这个地址以隐藏原来的地址。要启用隐私拓展,可以按照如下步骤:
向/etc/sysctl.d/40-ipv6.conf
加入如下内容:
# Enable IPv6 Privacy Extensions net.ipv6.conf.all.use_tempaddr = 2 net.ipv6.conf.default.use_tempaddr = 2 net.ipv6.conf.nic0.use_tempaddr = 2 ... net.ipv6.conf.nicN.use_tempaddr = 2
其中,nic0
到nicN
是你的网卡。all.use_tempaddr
或default.use_tempaddr
参数不会对已经配置好的网卡起作用。
重启之后,隐私扩展将会启用。
dhcpcd
dhcpcd从6.4.0版本起就在其默认配置文件中添加了选项slaac private
,实现对隐私扩展的支持,可以实现"Stable Private IPv6 Addresses instead of hardware based ones",符合RFC 7217 。(commit)。因此,没有必要修改任何配置,除非你想经常更换地址,而不是在每次连接上新网络时。
NetworkManager
NetworkManager不遵守/etc/sysctl.d/40-ipv6.conf
中的配置。可以在重启后运行$ ip -6 addr show interface
验证:正常的地址之外,没有状态为scope global temporary
的地址。
请查阅NetworkManager#Enable IPv6 Privacy Extensions。
scope global temporary
的IPv6地址从不更新(它在过期后不进入deprecated
状态),但已有验证在长时间之后它会改变。systemd-networkd
Systemd-networkd也不遵守/etc/sysctl.d/40-ipv6.conf
的配置,需要在配置中设置IPv6PrivacyExtensions
选项。
请查阅systemd-networkd和systemd.network(5) man page。
静态地址
有些情况下使用静态地址可以增强安全性。使用SLAAC分配动态地址时,你的计算机的地址会由其网卡MAC推算出,这不利于安全,因为即使地址的网络号改变,你的电脑依然可以被追踪到。
要想用netctl分配一个静态地址,可以参照/etc/netctl/examples/ethernet-static
。如下的部分尤其重要:
... # For IPv6 static address configuration IP6=static Address6=('1234:5678:9abc:def::1/64' '1234:3456::123/96') Routes6=('abcd::1234') Gateway6='1234:0:123::abcd'
DNS=('6666:6666::1' '6666:6666::2')如果你的ISP没有告诉你IPv6的DNS服务器地址,并且你也没有自己的服务器,你可以从resolv.conf这篇文章中选一个。
IPv6与PPPoE
PPPoE的软件包pppd
提供了对PPPoE之上的IPv6的支持(前提是你的ISP和调制解调器支持)。只需要将如下内容加入/etc/ppp/pppoe.conf
:
+ipv6
如果你使用netctl,那么就向你的netctl配置文件加入如下内容:
PPPoEIP6=yes
地址委派 (DHCPv6-PD)
地址委派是一种常见的IPv6部署方式,被许多ISP所采用。具体的做法是将一个地址前缀分配给用户(局域网),即路由器配置为将不同的前缀分配给不同的子网;ISP通过DHCPv6将地址前缀(通常是/56
或/64
)分发出去,DHCP客户端再将前缀分配给局域网。对于一个拥有两个网卡的简单网关来说,它的工作就是将从WAN口(或虚拟接口,比如ppp)获取的前缀分配给局域网。
使用dibbler
Dibbler是一个支持地址委派的DHCPv6客户端及服务器。它在AUR中:dibblerAUR。
如果你使用dibbler
,修改/etc/dibbler/client.conf
:
log-mode short log-level 7 # use the interface connected to your WAN iface "WAN" { ia pd }
dibbler-client(8)
以获取更多的信息。使用dhcpcd
Dhcpcd在IPv4之外也提供了一个完整的支持DHCPv6-PD的客户端。如果你使用dhcpcd
,需要修改/etc/dhcpcd.conf
。你可能已经在用dhcpcd来配置IPv4,所以只需要对现有的配置进行小幅修改:
duid noipv6rs waitip 6 # Uncomment this line if you are running dhcpcd for IPv6 only. #ipv6only # use the interface connected to WAN interface WAN ipv6rs iaid 1 # use the interface connected to your LAN ia_pd 1 LAN #ia_pd 1/::/64 LAN/0/64
这种配置下,客户端会从WAN
接口获取一个前缀,分配给LAN
接口。
如果ISP分配的是/64
的地址,你需要用第二个ia_pd
选项。
这也会禁用除WAN
接口之外的所有路由器请求。
dhcpcd(8)
与dhcpcd.conf(5)
获得更多信息。使用WIDE-DHCPv6
WIDE-DHCPv6是原本由KAME计划开发的DHCPv6开源实现。它在AUR中:wide-dhcpv6AUR。
如果你使用wide-dhcpv6
,修改/etc/wide-dhcpv6/dhcp6c.conf
:
# use the interface connected to your WAN interface WAN { send ia-pd 0; }; id-assoc pd 0 { # use the interface connected to your LAN prefix-interface LAN { sla-id 1; sla-len 8; }; };
sla-len
应设置为满足(WAN-prefix) + (sla-len) = 64
的值。这里示范的情况是针对一个长度/56
的前缀,56+8=64。对于前缀长度/64
的网络,sla-len
应为0
。要启用或运行wide-dhcpv6,使用如下命令。把WAN
改为连接到ISP的网卡:
# systemctl enable/start dhcp6c@WAN.service
dhcp6c(8)
与dhcp6c.conf(5)
获取更多信息。IPv6 on Comcast
dhcpcd -4
or dhcpcd -6
worked using a Motorola SURFBoard 6141 and a Realtek RTL8168d/8111d. Either would work, but would not run dual stack: both protocols and addresses on one interface. (The -6
command would not work if -4
ran first, even after resetting the interface. And when it did, it gave the NIC a /128 address.) Try these commands:
# dhclient -4 enp3s0 # dhclient -P -v enp3s0
The -P
argument grabs a lease of the IPv6 prefix only. -v
writes to stdout
what is also written to /var/lib/dhclient/dhclient6.leases
:
Bound to *:546 Listening on Socket/enp3s0 Sending on Socket/enp3s0 PRC: Confirming active lease (INIT-REBOOT). XMT: Forming Rebind, 0 ms elapsed. XMT: X-- IA_PD a1:b2:cd:e2 XMT: | X-- Requested renew +3600 XMT: | X-- Requested rebind +5400 XMT: | | X-- IAPREFIX 1234:5:6700:890::/64
IAPREFIX
is the necessary value. Substitute ::1
before the CIDR slash to make the prefix a real address:
# ip -6 addr add 1234:5:6700:890::1/64 dev enp3s0
禁用IPv6
关闭IPv6支持
向内核参数加入ipv6.disable=1
可以完全关闭IPv6功能,这应该就是你遇到问题时要做的事。查阅Kernel parameters以获取更多信息。
此外,只加入ipv6.disable_ipv6=1
内核参数可以保留IPv6功能,但不会向网卡分配IPv6地址。
也可以通过向/etc/sysctl.d/40-ipv6.conf
加入如下配置来避免系统给网卡分配IPv6地址:
# Disable IPv6 net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.nic0.disable_ipv6 = 1 ... net.ipv6.conf.nicN.disable_ipv6 = 1
注意你必须在这里清楚地列出所有不需要分配IPv6地址的网卡,仅仅设置all.disable_ipv6
并不会立刻对已经连接的网卡起作用。
另外,如果使用sysctl关闭IPv6,你应该在/etc/hosts
中删除所有的IPv6主机:
#<ip-address> <hostname.domain.org> <hostname> 127.0.0.1 localhost.localdomain localhost #::1 localhost.localdomain localhost
如果忽略这一步,可能会出现连接错误,因为这些主机会解析到IPv6地址,无法连接。
应用程序
在内核中关闭IPv6功能不会阻止应用程序尝试使用IPv6。多数情况下,这样不会有问题,但如果你发现程序无法正常运行,你应该查阅该应用程序的手册页,以找到关闭IPv6的合适方法。
dhcpcd
dhcpcd会尝试发送IPv6路由器请求。要禁用这种行为,可以依照其手册页dhcpcd.conf (5)
,向/etc/dhcpcd.conf
加入如下内容:
noipv6rs noipv6
NetworkManager
在图形界面下,关闭NetworkManager的IPv6支持可以以右键单击网络状态图表,依次选择Edit Connections > Wired > Network name > Edit > IPv6 Settings > Method > Ignore/Disabled,然后点击 "Save"。
在命令行终端下,关闭IPv6支持可以使用nmcli
:
# nmcli connection edit connection0
其中,connection0
是要修改的网络名称。nmcli
运行后进入其命令行,输入如下命令:
nmcli> set ipv6.method ignore
连接到该网络时,NetworkManager不会再配置该网络的IPv6地址。
ntpd
依照Systemd#Drop-in files,修改ntpd.service
的启动方式:
# systemctl edit ntpd.service
这样会产生一个drop-in snippet,替代原有的ntpd.service
来加载ntpd。参数-4
关闭了ntpd的IPv6支持。向drop-in snippet中加入如下内容:
[Service] ExecStart= ExecStart=/usr/bin/ntpd -4 -g -u ntp:ntp
第一行清除了之前的ExecStart
配置,接下来的一行将该配置设置为带有-4
参数的ntpd。
参见
- IPv6 - kernel.org documentation
- IPv6 temporary addresses - a summary about temporary addresses and privacy extensions
- IPv6 prefixes - a summary of prefix types
- net.ipv6 options - documentation of kernel parameters