IPv6

From BitFolk
Jump to navigation Jump to search

Some notes about configuring IPv6 at BitFolk.

Things changed in October 2024

Warning Warning: Starting in October 2024 BitFolk began assigning customers IPv6 netblocks from a different range, and all existing customer VMs were also assigned blocks from that new range. This article will only discuss the current, up-to-date configuration.

Your IPv6 assignment

By default customers are assigned a /48 of IPv6 space that starts with 2a0a:1100:1. The next three hexadecimal digits will identify your /48. For example:

$ ip -6 address show dev enX0
2: enX0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000
    inet6 2a0a:1100:1018::/128 scope global 
       valid_lft forever preferred_lft forever

This would indicate that 2a0a:1100:1018::/48 is this customer's assignment - the /128 is a single IP address from that assignment.

In this case the very first (all zeroes) address 2a0a:1100:1018:: has been configured, but all addresses between 2a0a:1100:1018:0000:0000:0000:0000:0000 and 2a0a:1100:1018:ffff:ffff:ffff:ffff:ffff are available to the customer for assignment (280-1 addresses).

As with IPv4, your IPv6 assignment is listed in the Panel.

Static IPv6 configuration

Dynamic IPv6 address allocation is not used at BitFolk.

Configuring additional IPv6 addresses

ifupdown (Debian)

ifupdown is currently the default network configuration framework on Debian. Other popular options are netplan or systemd-networkd directly. It is also possible to use NetworkManager, though that is usually only used on Debian desktop systems.

ifupdown is configured with the /etc/network/interfaces file (or in files included from that file). Your starting configuration will look something like this, covering both IPv4 and IPv6:

auto enX0
iface enX0 inet static
    address 85.119.82.121/21
    gateway 85.119.80.1

iface enX0 inet6 static
    address 2a0a:1100:1018::/128
    gateway fe80::1
    # This blackhole route is REQUIRED by BitFolk policy in order to prevent
    # traffic for unused addresses looping back out. It will not affect any
    # directly added IP address or route you have. Please do not remove it!
    #
    # If you do not like traffic to unknown adresses being silently dropped you
    # can change "blackhole" to "prohibit" which will result in your host
    # kernel sending back an ICMP Communication with Destination
    # Administratively Prohibited (type 1, code 1) message.
    #
    # Using firewall rules for the same purpose would also be acceptable.
    # ⬇️⬇️⬇️ Please do not remove
    post-up ip route add blackhole 2a0a:1100:1000::/48
    # ⬆️⬆️⬆️ Please do not remove

To add another IPv6 address simply add another iface block lower down:

iface enX0 inet6 static
    address 2a0a:1100:1018::1/128

It will not require a gateway directive.

netplan (Ubuntu 18.04 onwards)

Just add more IPv6 addresses to the addresses: list in the config file (e.g. /etc/netplan/01-netcfg.yaml):

network:
  version: 2
  ethernets:
    enX0:
      addresses:
        - "85.119.82.121/21"
        - "2a0a:1100:1018::/128"
        - "2a0a:1100:1018::1/128"
      routes:
        - to: default
          via: "85.119.80.1"
        - to: default
          via: "fe80::1"
        - to: "2a0a:1100:1018::/48"
          via: "::"
          type: blackhole
      nameservers:
        addresses:
          - "85.119.80.232"
          - "85.119.80.233"
          - "2001:ba8:1f1:f205::53"
          - "2001:ba8:1f1:f206::53"

To update the config and then make it live:

$ sudo netplan try

This will ask you for confirmation that everything is still working. If you don't provide it within a few seconds it will revert the change.

NetworkManager (CentOS and other Red Hat-like systems)

CentOS and other Red Hat-like systems use NetworkManager by default. This can be reconfigured live on the command line using nmcli.

To add an extra IPv6 address:

# nmcli connection modify enX0 +ipv6.addresses 2a0a:1100:1018::1/128


systemd-networkd

Help?

The default IPv6 source address

The source address chosen for IPv6 packets is typically the last one added to the system. This may be undesirable if you are adding addresses that you wish to dedicate to certain services. You can force a particular IPv6 address to be used as source by marking all the other addresses as deprecated. Deprecated addresses will still receive traffic and can still source traffic if they are specifically requested, but by default will not be used as a source address. You mark an IPv6 address as deprecated by setting its preferred_lft to 0.

Deprecating existing addresses

Given the following IPv6 setup:

$ ip -6 addr show dev enX0
2: enX0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000
    inet6 2a0a:1100:1018::/128 scope global 
       valid_lft forever preferred_lft forever
    inet6 2a0a:1100:1018::1/128 scope global 
       valid_lft forever preferred_lft forever

Here 2a0a:1100:1018::1 will most likely be used as a source address because it was added last. In order to force 2a0a:1100:1018:: to be used, you can use ip address change to deprecate the other one:

# ip address change 2a0a:1100:1018::1 dev enX0 preferred_lft 0
# ip address show dev enX0
2: enX0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000
    inet6 2a0a:1100:1018::1/128 scope global deprecated 
       valid_lft forever preferred_lft 0sec
    inet6 2a0a:1100:1018::/128 scope global 
       valid_lft forever preferred_lft forever

To make the change permanent you'll need to set it in your network configuration.

Debian

# This one is to be the one that is used for outbound traffic by default
iface enX0 inet6 static
    address 2a0a:1100:1018::/128
    gateway fe80::1
    # skipped all the stuff about blackhole route in this example

# Perhaps you will only use this one for web serving
iface enX0 inet6 static
    address 2a0a:1100:1018::80/128
    preferred-lifetime 0

# Add another IPv6 address. If it wasn't for the use of
# preferred-lifetime 0 this one would probably be the default source
# address as it was added last
iface enX0 inet6 static
    address 2a0a:1100:1018::bfbf/128
    preferred-lifetime 0

netplan (Ubuntu 18.04 onwards)

In netplan configuration you can set the preferred_lft on any address in the addresses: list:

      addresses:
        - "85.119.82.121/21"
        - "2a0a:1100:1018::/128"
        - "2a0a:1100:1018::1/128":
            lifetime: 0

NetworkManager (CentOS and other Red Hat-like systems)

We haven't been able to work out if NetworkManager can set the preferred_lft of individual addresses apart from autogenerated addresses. Please update if you know how.

It may be possible to use a hook script to run the equivalent ip address change … preferred_lft 0 command.

In general, addresses defined with nmcli connection modify enX0 ipv6.addresses … are in decreasing order of priority, so the first one is the preferred source address.

Firewalling

Don't forget that you'll need to firewall your IPv6 just like you firewall your IPv4. The tool to do so is either nft (current) or ip6tables (deprecated).

Neighbor Discovery

IPv6 uses neighbor discovery to map IPv6 addresses to Ethernet (MAC) addresses. This replaces the functionality of ARP in IPv4, and as a result means you do need to allow some types of ICMPv6 traffic through if you want anything at all to work:

nft

Help?

ip6tables

--append INPUT -p ipv6-icmp --icmpv6-type neighbor-advertisement -j ACCEPT
--append INPUT -p ipv6-icmp --icmpv6-type neighbor-solicitation  -j ACCEPT

Alternatively you may just want to allow everything on link-local addresses:

--append INPUT -s fe80::/10 -j ACCEPT

Preferring IPv4 over IPv6

Sometimes a remote host will have both IPv4 and IPv6 addresses. By default, Linux tends to prefer IPv6. If for some reason you wish to prefer IPv4 addresses then you can do so by adding:

precedence ::ffff:0:0/96 100

at the end of /etc/gai.conf .

Disabling IPv6

If you don't use IPv6 yet then it might be best to explicitly disable it.

Kernel level

Arranging for ipv6.disable=1 to be added to the kernel's command line should work on any Linux distribution from its next boot.

Debian/Ubuntu

IPv6 can be disabled with a sysctl, for example:

# echo 'net.ipv6.conf.all.disable_ipv6=1' > /etc/sysctl.d/disableipv6.conf

As IPv6 support is built into the kernel this will disable IPv6 from the next reboot.

CentOS and other Red Hat-like systems

Unknown if NetworkManager will obey the above sysctl. Let us know?

Reverse DNS

Automated IPv6 reverse DNS (default)

By default you have generic automatic reverse DNS for IPv6 that looks a bit like this:

$ dig +noall +answer -x 2a0a:1100:1018::
0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.1.0.1.0.0.1.1.a.0.a.2.ip6.arpa. 3600 IN PTR 2a0a-1100-1018-0-0-0-0-0.autov6rev.bitfolk.space.
 dig +noall +answer -t aaaa 2a0a-1100-1018-0-0-0-0-0.autov6rev.bitfolk.space.
2a0a-1100-1018-0-0-0-0-0.autov6rev.bitfolk.space. 3600 IN AAAA 2a0a:1100:1018::

As you can see, it resolves correctly both ways.

Controlling your own IPv6 reverse DNS

If instead you would like to take control of your IPv6 reverse DNS then BitFolk can delegate the reverse DNS for your zone to nameservers you specify. These can all be nameservers you control, or BitFolk can provide up to three of them (you just provide the primary: see the page on secondary DNS for more information.)

The reverse zone for 2a0a:1100:1018::/48 would be called 8.1.0.1.0.0.1.1.a.0.a.2.ip6.arpa. You can work this out using dig. For example:

$ dig +noall +question -x 2a0a:1100:1018::
;0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.1.0.1.0.0.1.1.a.0.a.2.ip6.arpa. IN PTR

or sipcalc:

$ sipcalc -ar 2a0a:1100:1018::
-[ipv6 : 2a0a:1100:1018::] - 0

[IPV6 INFO]
Expanded Address        - 2a0a:1100:1018:0000:0000:0000:0000:0000
Compressed address      - 2a0a:1100:1018::
Subnet prefix (masked)  - 2a0a:1100:1018:0:0:0:0:0/128
Address ID (masked)     - 0:0:0:0:0:0:0:0/128
Prefix address          - ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
Prefix length           - 128
Address type            - Aggregatable Global Unicast Addresses
Network range           - 2a0a:1100:1018:0000:0000:0000:0000:0000 -
                          2a0a:1100:1018:0000:0000:0000:0000:0000

[V4INV6]
Expanded v4inv6 address - 2a0a:1100:1018:0000:0000:0000:0.0.0.0
Compr. v4inv6 address   - 2a0a:1100:1018::0.0.0.0

[IPV6 DNS]
Reverse DNS (ip6.arpa)  -
0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.1.0.1.0.0.1.1.a.0.a.2.ip6.arpa.

-


The 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 part is the record you put in your zone and the 8.1.0.1.0.0.1.1.a.0.a.2.ip6.arpa is the name of the zone itself. Here is what a typical BIND-format zone file might look like:

$ORIGIN 8.1.0.1.0.0.1.1.a.0.a.2.ip6.arpa.
$TTL 10800      ; 3 hours
@                       IN SOA a.ns.example.com. hostmaster@example.com. (
                             2024103101   ; serial
                                   1800   ; refresh (30 mins)
                                    900   ; retry (15 mins)
                                1209600   ; expire (2 weeks)
                                   3600 ) ; minimum (20 mins)

                                NS a.ns.example.com.
                                NS b.ns.example.com.
                                NS c.ns.example.com.

; Example reverse DNS for 2a0a:1100:1018::
0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 PTR ruminant.example.com.
; Example reverse DNS for 2a0a:1100:1018::1
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 PTR another.example.com.
; Example reverse DNS for 2a0a:1100:1018::bfbf
f.b.f.b.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 PTR bfbf.example.com.

put this is in a file called for example /etc/bind/8.1.0.1.0.0.1.1.a.0.a.2.ip6.arpa, and then reference this file from your named.conf:

zone "8.1.0.1.0.0.1.1.a.0.a.2.ip6.arpa" {
	type master;
	file "/etc/bind/8.1.0.1.0.0.1.1.a.0.a.2.ip6.arpa";
};

You would then need to delegate reverse DNS for this domain to your nameservers. This can be configured from the IPv6 section of the Panel.

You would be advised to use at least two different nameservers in a reverse DNS delegation. If you don't have enough then BitFolk can provide up to three of them, just ask. BitFolk can also provide the only three visible nameservers while taking the zone from your hidden primary if you wish. In that case you would list the three BitFolk servers in the panel, and if you wish you can firewall your primary server off to BitFolk's internal network only, so that the internet at large can't query it (allow 85.119.80.222, 85.119.80.238, 85.119.80.244, 2001:ba8:1f1:f040::/64 and 2001:ba8:1f1:f25d::/64 on both UDP and TCP).

Routing IPv6

Your /48 assignment can be further subdivided into smaller netblocks. For example, those using their VPS as a VPN server may wish to route an IPv6 network to each of their clients.

It is recommended to use at least a /64 for each IPv6 network—autoconfiguration won't work if you don't. Your /48 can be subdivided into up to 65.535 /64 networks, or 255 /56 networks.

Frequently Asked Questions

I configured an IPv6 address that's all f's and now I can't reach some sites

If you configure an address between ...:ffff:ffff:ffff:ff80 and ...:ffff:ffff:ffff:ffff then you might experience strange routing problems for packets sourced from those addresses.

As per RFC 2526, the last 128 addresses in each subnet are reserved for anycast use. While they might be usable as normal unicast IPv6 addresses, some sites may filter them or they might be used locally.