IPv6 (简体中文) - ArchWiki

Jump to content

Related articles

- IPv6 tunnel broker setup

在 Arch Linux 中，IPv6 是默认开启的。

tldp Linux+IPv6-HOWTO 这篇文章比较旧， 且缺乏维护。不过其涵盖了本文所提及的许多主题，从基础的东西讲起并且循序渐进到高级配置。而且还有很多命令的例子。初学者可以先读一读这篇文章再接着阅读本文。

## 邻居发现（Neighbor discovery，ND）

使用 Ping 命令来 ping `ff02::1` 这个多播地址，会得到本地链路层的所有主机的响应。需要手动指定接口（`%eth0`）

    $ ping ff02::1%eth0

Ping 完之后，您可以用如下命令来获取本地子网中的所有主机。

    $ ip -6 neigh

如果您 Ping 的是 `ff02::2` 这个多播地址，则只有网络中的路由器会响应。

如果您添加一个 `-I your-global-ipv6` 选项，本地链路上的主机会以他们的本地链路地址来响应。这种情况下可以省略接口。

    $ ping -I 2001:4f8:fff6::21 ff02::1

用下面这个脚本可以 Ping 所有接口上的所有其他主机，并且把你的地址告诉所有人。

    #!/usr/bin/bash
    declare -a l_ifs
    readarray l_ifs < <(/sbin/ip -6 -j address | jq -r '.[] | .ifname ')
    for l_if in ${l_ifs[@]} ; do
     echo $l_if
     declare -a l_addrs
     readarray l_addrs < <(/sbin/ip -6 -j address show dev "$l_if" | \
                            jq -r  '.[0].addr_info[].local')
     for l_addr in ${l_addrs[@]} ; do
       echo $l_addr
       ping -c 4 -6 -I "$l_addr" ff02::1%"$l_if"
     done
    done

## 无状态地址自动配置 (SLAAC)

想要获得一个IPv6地址，最简单的办法就是用SLAAC。只要您的网络配置好了「无状态地址自动配置」（Stateless address autoconfiguration，简称SLAAC），您的设备就会自动根据路由器广播（Router Advertisement，RA）的前缀为自己配置一个地址。既不需要进一步配置，也不需要专门的软件（如DHCP客户端）

### 客户端配置

如果您正在使用 netctl，您要做的只是往接口配置文件里加上这么一行：

    IP6=stateless

如果您使用的是 NetworkManager，那么只要网络内有路由器广播，它就会自动配置上 IPv6 地址。

不过需要注意的是，SLAAC只有在网络允许 IPv6 ICMP 包通过的时候才能工作。所以你需要在客户端防火墙上允许 `ipv6-icmp` 类型的数据包传入。如果您用的是 Simple stateful firewall/iptables，加上下面这行就可以了：

    -A INPUT -p ipv6-icmp -j ACCEPT

如果您用的是其他防火墙，请参考对应的文档来放行 `ipv6-icmp` 数据包。

如果你选择的网络管理方案不支持通过SLAAC配置DNS（比如netctl），那么你可以考虑用ndisc6包里的rdnssd(8)命令来配置DNS。

### 路由器（网关）配置

要正确给网络内的客户端分配 IPv6，我们要用到一个广播守护进程，一般是radvd。其配置过程其实相当简单。参考下面的配置来编辑 `/etc/radvd.conf`文件。

    # 把LAN替换为你实际的局域网接口
    interface LAN {
      AdvSendAdvert on;
      MinRtrAdvInterval 3;
      MaxRtrAdvInterval 10;
      prefix ::/64 {
        AdvOnLink on;
        AdvAutonomous on;
        AdvRouterAddr on;
      };
    };

以上配置会让客户端自己从 /64 地址段中选择地址来使用。请注意如果配置了 `prefix ::/64`，RADVD会向局域网广播那个接口上的所有可用的前缀。如果您想要广播指定的前缀，请手动指定，比如 `prefix 2001:DB8::/64`。`prefix` 节可以根据需要多次重复来广播多个不同前缀。

您可以通过 RDNSS 功能向客户端广播 DNS，以 Google DNS 为例，配置如下：

    RDNSS 2001:4860:4860::8888 2001:4860:4860::8844 {
    };

网关必须在所有链上允许 `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` 服务。

## 隐私拓展

当一个客户端通过 SLAAC 获得一个地址时，其 IPv6 地址是经过客户端网络接口广播的前缀和 MAC 地址计算而得出的。这可能会引起隐私问题，因为别人可以轻易通过 IPv6 SLAAC 地址反推客户端 MAC。为了解决这个问题，RFC 4941 中提出了 IPv6 隐私拓展 标准。启用隐私扩展后，内核会生成一个 临时 地址，这个地址是原来的 SLAAC 地址经过二次计算得出的随机地址。当主动连接到远程服务器时，会优先选择使用私有地址，从而帮助隐藏原始的 SLAAC地址。启用隐私扩展的步骤如下:

向 `/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` 是你的网络接口。你可以参考 Network configuration#Listing network interfaces 来列出你的设备上的接口。 `all.use_tempaddr` 或者 `default.use_tempaddr` 参数对于执行 sysctl 设置时已经存在的接口无效，也就是说不会即时生效。

不过当您重启设备之后，隐私拓展应该就会生效了。

### dhcpcd

dhcpcd's default configuration includes the option `slaac private`, which enables "Stable Private IPv6 Addresses instead of hardware based ones", implementing RFC 7217. Therefore, it is not necessary to change anything, except if it is desired to change of IPv6 address more often than each time the system is connected to a new network. Set it to `slaac hwaddr` for a stable address.

### NetworkManager

The use of IPv6 Privacy Extensions in NetworkManager can be controlled with the `ipv6.ip6-privacy` setting in NetworkManager.conf(5) or in the connection's profile. If it is not set globally nor per-connection, NetworkManager will fall back to reading `/proc/sys/net/ipv6/conf/default/use_tempaddr`.

To explicitly enable IPv6 Privacy Extensions by default, add these lines to NetworkManager.conf(5):

    /etc/NetworkManager/conf.d/ip6-privacy.conf

    [connection]
    ipv6.ip6-privacy=2

Apply the configuration and reconnect to all active connections.

To control the use of IPv6 Privacy Extensions for individual NetworkManager-managed connections, edit the desired connection keyfile in `/etc/NetworkManager/system-connections/` and append to its `[ipv6]` section the key-value pair `ip6-privacy=2`:

    /etc/NetworkManager/system-connections/example_connection.nmconnection

    ...
    [ipv6]
    method=auto
    ip6-privacy=2
    ...

Reload the connection and reconnect to it afterwards.

Note: Although it may seem the `scope global temporary` IPv6 address created by enabling Privacy Extensions never gets renewed (it never shifts to `deprecated` status at the term of its `valid_lft` lifetime), it is to be verified over a longer period of time that this address does indeed change.

### systemd-networkd

systemd-networkd also does not honor the settings `net.ipv6.conf.xxx.use_tempaddr` placed in `/etc/sysctl.d/40-ipv6.conf` unless the option `IPv6PrivacyExtensions` is set with the value `kernel` in the .network file(s).

Other options for the IPv6 Privacy Extensions like:

    net.ipv6.conf.xxx.temp_prefered_lft
    net.ipv6.conf.xxx.temp_valid_lft

are honored, however.

Note: `temp_prefered_lft` is the variable name, preferred has to be misspelled.

See systemd-networkd and systemd.network(5) for details.

### ConnMan

Set in a service file, i.e. `/var/lib/connman/service/settings`:

    IPv6.privacy=preferred

See ConnMan for details.

## Stable private addresses

Another option is a stable private IP address (RFC 7217). This allows for IPs that are stable within a network without exposing the MAC address of the interface.

In order to have the kernel generate a key (for `wlan0`, for example) we can set:

    # sysctl net.ipv6.conf.wlan0.addr_gen_mode=3

Bring the interface down and up and you should see `stable-privacy` next to each IPv6 address after running `ip addr show dev wlan0`. The kernel has generated a 128-bit secret for generating ip addresses for this interface, to see it run `sysctl net.ipv6.conf.wlan0.stable_secret`. We are going to persist this value so add the following lines to `/etc/sysctl.d/40-ipv6.conf`:

    # Enable IPv6 stable privacy mode
    net.ipv6.conf.wlan0.stable_secret = output_from_previous_command
    net.ipv6.conf.wlan0.addr_gen_mode = 2

Note: If you are using dhcpcd to get the IPv6 address, the `stable-privacy` flag will not be attributed to this IP address.

### NetworkManager

The above settings are not honored by NetworkManager, but NetworkManager uses stable private addresses by default.[1][2]

## Static address

Sometimes, using a static address can improve security. For example, if your local router uses Neighbor Discovery or radvd (RFC 2461), your interface will automatically be assigned an address based on its MAC address (using IPv6's Stateless Autoconfiguration). This may be less than ideal for security since it allows a system to be tracked even if the network portion of the IP address changes.

To assign a static IP address using netctl, look at the example profile in `/etc/netctl/examples/ethernet-static`. The following lines are important:

    ...
    # 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'

Note: If you are connected IPv6-only, then you need to determine your IPv6 DNS server. For example:

    DNS=('6666:6666::1' '6666:6666::2')

If your provider did not give you IPv6 DNS and you are not running your own, you can choose from the resolv.conf article.

## IPv6 and PPPoE

The standard tool for PPPoE, pppd(8), provides support for IPv6 on PPPoE as long as your ISP and your modem support it. Just add the following to `/etc/ppp/options`

    +ipv6

If you are using netctl for PPPoE then just add the following to your netctl configuration instead:

    PPPoEIP6=yes

## Prefix delegation (DHCPv6-PD)

Note: This section is targeted towards custom gateway configuration, not client machines. For standard market routers please consult the documentation of your router on how to enable prefix delegation.

Prefix delegation is a common IPv6 deployment technique used by many ISPs. It is a method of assigning a network prefix to a user site (i.e. local network). A router can be configured to assign different network prefixes to various subnetworks. The ISP hands out a network prefix using DHCPv6 (usually a `/56` or `/64`) and a dhcp client assigns the prefixes to the local network. For a simple two interface gateway it practically assigns an IPv6 prefix to the interface connected to to the local network from an address acquired through the interface connected to WAN (or a pseudo-interface such as ppp).

DHCPv6 requires the client to receive incoming connections on port 546 UDP. For an nftables-based firewall, that can be configured with one line in the input chain in `/etc/nftables.conf`:

    table inet filter {
      chain input {
        udp dport dhcpv6-client accept
        ...
      }
    ...
    }

### With dhcpcd

dhcpcd apart from IPv4 dhcp support also provides a fairly complete implementation of the DHCPv6 client standard which includes DHCPv6-PD. If you are using `dhcpcd` edit `/etc/dhcpcd.conf`. You might already be using dhcpcd for IPv4 so just update your existing configuration.

    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

This configuration will ask for a prefix from WAN interface (`WAN`) and delegate it to the internal interface (`LAN`). In the event that a `/64` range is issued, you will need to use the 2nd `ia_pd instruction` that is commented out instead. It will also disable router solicitations on all interfaces except for the WAN interface (`WAN`).

Tip: Also read dhcpcd(8) and dhcpcd.conf(5).

### With WIDE-DHCPv6

WIDE-DHCPv6 is an open-source implementation of Dynamic Host Configuration Protocol for IPv6 (DHCPv6) originally developed by the KAME project. It can be installed with wide-dhcpv6AUR.

If you are using wide-dhcpv6, edit `/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;
      };
    };

Note: `sla-len` should be set so that `(WAN-prefix) + (sla-len) = 64`. In this case it is set up for a `/56` prefix 56+8=64. For a `/64` prefix `sla-len` should be `0`.

The wide-dhcpv6 client can be started/enabled using the `dhcp6c@interface.service` systemd unit file, where `interface` is the interface name in the configuration file, e.g. for a interface name "WAN" use `dhcp6c@WAN.service`.

Tip: Read dhcp6c(8) and dhcp6c.conf(5) for more information.

### systemd-networkd

Configure both your upstream (wan) and downstream (lan) interface. This will enable DHCPv6-PD on the interface where the DHCPv6 client is running. The delegated prefixes are distributed by IPv6 Router Advertisement on the downstream network.

    /etc/systemd/network/wan.network

    [Network]
    # Use 'yes' instead of 'ipv6' for both ipv4 and ipv6.
    DHCP=ipv6

    /etc/systemd/network/lan.network

    [Network]
    IPv6SendRA=yes
    DHCPv6PrefixDelegation=yes

### Other clients

dhclient can also request a prefix, but assigning that prefix, or parts of that prefix to interfaces must be done using a dhclient exit script. For example: https://github.com/jaymzh/v6-gw-scripts/blob/master/dhclient-ipv6.

## NAT64

Wikipedia:NAT64 is the IPv6 transition mechanism where IPv6 only hosts are able to communicate with IPv4 hosts using NAT.

Linux kernel does not support NAT64 natively but there are several packages to add support for NAT64.

- Jool — SIIT and NAT64 for Linux

  https://nicmx.github.io/Jool/ || jool-dkmsAUR, jool-toolsAUR

- TAYGA — NAT64 daemon (unmaintained)

  http://www.litech.org/tayga/ || taygaAUR

## Disable IPv4

This article or section needs expansion.

Reason: Add instructions to disable legacy IP, esp. if the network has NAT64 and DNS64 we do not need to maintain dualstack, also the implementation of CGN degraded ipv4 performance and usability (e.g. hosting nextcloud at home is nowadays often only possible using only ipv6 and services like dynv6.com or namecheap dyndns records. This is because no public ipv4 is available, not even to the CPE router) (Discuss in Talk:IPv6 (简体中文))

## Disable IPv6

Note: The Arch kernel has IPv6 support built in directly, therefore a module cannot be blacklisted.

This article or section needs expansion.

Reason: Add reasons why users may want to disable IPv6, such as low-quality DNS servers or firewall rules (Discuss in Talk:IPv6 (简体中文))

This article or section needs expansion.

Reason: Add drawbacks of disabling IPv6, like degraded performance behind CGN, worse performance in p2p/webrtc based applications and games (Discuss in Talk:IPv6 (简体中文))

### Disable functionality

Adding `ipv6.disable=1` to the kernel line disables the whole IPv6 stack, which is likely what you want if you are experiencing issues. See Kernel parameters for more information.

Alternatively, adding `ipv6.disable_ipv6=1` instead will keep the IPv6 stack functional but will not assign IPv6 addresses to any of your network devices.

One can also avoid assigning IPv6 addresses to specific network interfaces by adding the following sysctl configuration to `/etc/sysctl.d/40-ipv6.conf`:

    # Disable IPv6
    net.ipv6.conf.all.disable_ipv6 = 1
    net.ipv6.conf.nic0.disable_ipv6 = 1
    ...
    net.ipv6.conf.nicN.disable_ipv6 = 1

Restart the `systemd-sysctl.service` unit to apply the configuration changes.

Note that you must list all of the targeted interfaces explicitly, as disabling `all.disable_ipv6` does not apply to interfaces that are already "up" when sysctl settings are applied.

Note: If disabling IPv6 via sysctl, you should comment out the IPv6 hosts in your `/etc/hosts`. Otherwise there could be some connection errors because hosts are resolved to their IPv6 address which is not reachable.

### Other programs

Disabling IPv6 functionality in the kernel does not prevent other programs from trying to use IPv6. In most cases, this is completely harmless, but if you find yourself having issues with that program, you should consult the program's manual pages for a way to disable that functionality.

#### dhcpcd

dhcpcd will continue to harmlessly attempt to perform IPv6 router solicitation. To disable this, as stated in the dhcpcd.conf(5) man page, add the following to `/etc/dhcpcd.conf`:

    noipv6rs
    noipv6

#### NetworkManager

To disable IPv6 in NetworkManager, right click the network status icon, and select Edit Connections > Wired > Network name > Edit > IPv6 Settings > Method > Ignore/Disabled. Then click Save.

This can also be done as:

    # nmcli connection modify ConnectionName ipv6.method "disabled"

Followed by a restart of the network connection:

    # nmcli connection up ConnectionName

To confirm the settings have been applied, use `ip address show` and check no inet6 entry is displayed. Alternatively, `/proc/sys/net/ipv6/conf/interface/disable_ipv6` should have the value 1.

#### ntpd

Following advice in systemd#Drop-in files, edit `ntpd.service` to define how systemd starts it.

This will create a drop-in snippet that will be run instead of the default `ntpd.service`. The `-4` flag prevents IPv6 from being used by the ntp daemon. Put the following into the drop-in snippet:

    [Service]
    ExecStart=
    ExecStart=/usr/bin/ntpd -4 -g -u ntp:ntp

which first clears the previous `ExecStart`, and then replaces it with one that includes the `-4` flag.

#### GnuPG

Disable IPv6 in the dirmngr's configuration file:

    ~/.gnupg/dirmngr.conf

    disable-ipv6

Restart the `dirmngr.service` user unit afterwards.

#### sshd

Ensure sshd is using IPv4 by adding the following to `sshd_config`:

    /etc/ssh/sshd_config

    AddressFamily inet

And restart the `sshd.service`.

#### systemd-timesyncd

On occasion systemd-timesyncd will attempt to query an IPv6 timeserver even when IPv6 has been disabled. This can result in the system clock not being updated and the journal showing an error similar to:

    systemd-timesyncd[336]: Failed to set up connection socket: Address family not supported by protocol

The unit status of `systemd-timesyncd` will show an attempt to connect with an IPv6 address in its Status entry, similar to:

    Status: "Connecting to time server [2001:19f0:8001:afd:5400:1ff:fe9d:cba]:123 (2.pool.ntp.org)"

Per FS#59806, only the "2." ntp.org pools serve IPv6. So to prevent this remove `2.arch.pool.ntp.org` and `2.pool.ntp.org` from the NTP and FallbackNTP entries in `/etc/systemd/timesyncd.conf` file.

### systemd-networkd

networkd supports disabling IPv6 on a per-interface basis. When a network unit's `[Network]` section has either `LinkLocalAddressing=ipv4` or `LinkLocalAddressing=no`, networkd will not try to configure IPv6 on the matching interfaces.

Note however that even when using the above option, networkd will still be expecting to receive router advertisements if IPv6 is not disabled globally. If IPv6 traffic is not being received by the interface (e.g. due to sysctl or ip6tables settings), it will remain in the configuring state and potentially cause timeouts for services waiting for the network to be fully configured. To avoid this, the `IPv6AcceptRA=no` option should also be set in the `[Network]` section.

## Prefer IPv4 over IPv6

The factual accuracy of this article or section is disputed.

Reason: This disables the other default rules. [3] (Discuss in Talk:IPv6 (简体中文)#Factual accuracy - Prefer IPv4 over IPv6)

Uncomment the following line in `/etc/gai.conf`:

    #
    #    For sites which prefer IPv4 connections change the last line to
    #
    precedence ::ffff:0:0/96  100

## See also

- 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

Category:

- Networking (简体中文)

Hidden categories:

- Pages or sections flagged with Template:Expansion
- Pages or sections flagged with Template:Accuracy