Setting up IPv6

In this document, this is example data and this is data to be entered at the keyboard

To use IPv6 on my network, as the ISP may change, I use private addressing as the primary range, with native and/or 6to4 when compatible ISP is connected.

Users could also used configured 6in4 tunnelling but that involves interaction with a provider end. 6to4 is probably the fastest for sites without pure ipv6 access.

Summary of private site ipv6

if an interface on vlan f00d has MAC of AC:DE:48:23:45:67

builtin link address, similar to 169.254.RAN.DOM/16
simple site local lan address, similar to 192.168.VLAN.NODE/24 style addressing, it may be deprecated but still useful until geoip can be a standard.
alternate site local lan address with randomised prefix in place of 00:0000:0000, suggest from a key
Got a site ipv4 address of; systems may have an 6to4 address like this:
and perhaps a teredo address like this:
Got native ipv6 from ISP d0be; might have an address like this:

Site local addresses might now be stored locally in home.arpa. rather than local. as used by multicast dns, and protects site addressing from being misrouted by the drop catch of expiry revokation of ip address space.

Most sites want to use fec0:: addresses and home.arpa for forever internal usage.

forward zone
SOA example.home.arpa.
forward records
example.lan.home.arpa. IN AAAA fec0:0:0:f00d:aede:48ff:fe23:4567
example.lan.home.arpa. IN EUI48 ac-de-48-23-45-67
example.lan.home.arpa. IN EUI64 ac-de-48-ff-fe-23-45-67
example.lab.home.arpa. IN AAAA fec0:0:0:f00d:aede:48ff:fe23:4567
example.lab.home.arpa. IN EUI48 ac-de-48-23-45-67
example.lab.home.arpa. IN EUI64 ac-de-48-ff-fe-23-45-67
forward alias
www.home.arpa. IN AAAA fec0:0:0:f00d:aede:48ff:fe23:4567
reverse IN PTR example.lan.home.arpa.

Template system

There is a choice of systemd's networkd or network-manager (nm) for resilient interface configuration.

This is not an either-or, both can be used together.

This is because networkd has a stateless config, whereas nm would assign and refer to connections by uuid and that would change for repeated container connections.

networkd does not manage interfaces til told to do so whereas nm has to be told to leave interfaces alone, for example when networkd is to manage them differently.

Best flexibility comes from a host bridge, I call that "br", with each VLAN tag for the host presented afterwards, so "br1" for VLAN 1 to "br4094" for VLAN 4094. This is because prior to VLAN aware bridges, a bridge per vlan was needed to which a vlan detagged ethernet interface was attached such as eth.1 to eth.4094 and they could have the same names, wheres br.1 to br.4094 definately implies vlan aware and would have an extra character.


First setup of the bridge, set the host mac address here, usually the system's hardware address, not setting mtu here, enable VLANFiltering and set DefaultPVID=none for security.

  1. # don't set MTUBytes here, defer to [link], so we get mtu_set_by_user=true in kernel
  2. [NetDev]
  3. Name=br
  4. Kind=bridge
  5. MACAddress=AC:DE:48:23:45:67
  6. #MTUBytes=65535
  7. [Bridge]
  8. VLANFiltering=true
  9. #MTUBytes=9216
  10. # after brctl, bridge priority in "ip -c -d link show dev br"
  11. # and port priority in "bridge -d link show dev enp5s0"
  12. Priority=32768
  13. MulticastSnooping=true
  14. DefaultPVID=none


Final setup of the host bridge, we set mtu to 65535, as big as possible, and disable IP addressing on the bridge itself as all networks are presented as tags. In this example VLAN 1 and 4094

  1. [Match]
  2. Name=br
  3. # wait for the mac address to be changed
  4. #MACAddress=AC:DE:48:23:45:67
  5. [Link]
  6. MTUBytes=65535
  7. DHCP=no
  8. LinkLocalAddressing=no
  9. VLAN=br1
  10. VLAN=br4094
  11. [BridgeVLAN]
  12. VLAN=1
  13. [BridgeVLAN]
  14. VLAN=4094


Config of a network device, realtek 8169. I like predictable naming, although for resilience match directly on the PCI slot of a device. If the other end supports LACP then an interstitial bonding device between the bridge and the links may be used, this can even be useful without actual multilink aggregation.

  1. [Match]
  2. Driver=r8169
  3. Path=pci-0000:01:00.0
  4. [Link]
  5. #MTUBytes=9216
  6. NamePolicy=kernel database onboard slot path
  7. MACAddressPolicy=persistent


Complete the interface config, here the vlans to present are set, and a detagged vlan when that is used, usually with management controller sharing like AMT. The MTU also set to the maximum the card works with, use an ifconfig binary search to find it.

  1. [Match]
  2. Driver=r8169
  3. Path=pci-0000:01:00.0
  4. [Link]
  5. RequiredForOnline=no
  6. MTUBytes=6122
  7. # LinkLocalAddressing=no for no "degraded"
  8. # https://github.com/systemd/systemd/issues/575
  9. [Network]
  10. Bridge=br
  11. DHCP=no
  12. LinkLocalAddressing=no
  13. LLDP=true
  14. # lldpd more complete info, both could be enabled though would interleave each other
  15. # then cause syslog events as changes detected
  16. #EmitLLDP=customer-bridge
  17. EmitLLDP=false
  18. [BridgeVLAN]
  19. VLAN=1
  20. [BridgeVLAN]
  21. VLAN=4094
  22. EgressUntagged=4094
  23. PVID=4094


Setup a VLAN 4094, duplicate this for other vlan substituting the number. Host vlan I like to use the host MAC, so repeat it here.

  1. [Match]
  2. [NetDev]
  3. Name=br20
  4. Kind=vlan
  5. MACAddress=AC:DE:48:23:45:67
  6. #MTUBytes=65535
  7. [VLAN]
  8. Id=4094


Complete the setup of a VLAN, using static everything, typical on a server.

If the "global" addresses are not actually static then a helper program may write them to /run/systemd/network/25-br4094.network and such addresses left out of /etc

In the tradition of liberal acceptance, conservative sending, again maximise the link MTU so everything is received, and use routing MTU to limit what is sent, in many cases to 1500, this allows jumbo frames to be taken advantage of even on a mixed MTU vlan.

For virtual guests connected to the bridge with macvtap and containers in linux namespaces attached via veth, there may well be no MTU limits enabling the exploitation of huge frames, like 65535 sized.

alternate routing tables, such as for 6to4, could be set /etc/iproute2/rt_tables.d/example.conf

I use resolved, /etc/resolv.conf linked to /run/systemd/resolve/resolv.conf, which sets "nameserver ::1", and then run a local unbound to handle resolution, whereas I do use ptpd and ntpd rather than timesyncd, although the latter is configured as a fallback sometimes.

  1. [Match]
  2. Name=br4094
  3. [Link]
  4. MTUBytes=65535
  5. [Network]
  6. DHCP=no
  7. IPv6AcceptRA=false
  8. ConfigureWithoutCarrier=yes
  9. Address=
  10. Address=fec0:0:0:0ffe:aede:48ff:fe23:4567/64
  11. Address=2001:db8:d0be:0ffe:aede:48ff:fe23:4567/64
  12. Address=2002:c000:0201:0ffe:aede:48ff:fe23:4567/64
  13. #DNS=2001:db8:d0be:0ffe:aede:48ff:fe23:4567
  14. #DNS=
  15. [IPv6AcceptRA]
  16. UseDNS=false
  17. UseDomains=false
  18. [DHCP]
  19. UseDomains=false
  20. UseDNS=false
  21. UseNTP=false
  22. [Route]
  23. Destination=2002:c000:0201:0ffe::/64
  24. Table=4
  25. [Route]
  26. Destination=
  27. MTUBytes=6122

Why bother to configure ipv6 transition addresses on a native site?

Because the unreliable part is crossing the address families, if destination sites only offer native and ipv4 then the transition tech may not get exercised, and exercising them is a good thing to convince operators of interest in native, and ipv4 only systems may see data on ipv4 payload protocol 41 or udp 3544.

The unreliablity comes from source tracing issues, therefore this part of transition tends to get deprecated and used only as a last resort, such as use of in 6to4, and now used only to try to reach an ipv6 only site as a last resort.

Then if a dns resource is visited by a client that supports 6to4 or teredo, sites need these addresses as well as the native one to exercise the transition.

There remains use in configuring this on an IPv4 site even together with native ipv6, as sites may not be able to rely on to reach native sites except as a last resort, so in most cases is a recommendation whilst public IPv4 is in use.

  1. iface sit0 inet6 static
  2. address `printf "2002:%02x%02x:%02x%02x::" \`ip route get | sed $'s/.*src//\nq' | tr "." " "\``
  3. netmask 16
  4. gateway ::

Newer systems that are not behind any NAT can also use the following:

The line containing int0 is an example to provide ipv6 to an ethernet interface, which may be a bridge to allow the use of ebtables even with only the one interface.

iface tun6to4 inet manual
        up /sbin/ip tunnel add tun6to4 mode sit ttl 64 remote any local $(ip --family inet route get | sed $'s/.*src//\nq')
        up /sbin/ip link set dev tun6to4 up
        up /sbin/ip -6 addr add $(ipv6calc --in ipv4addr --out ipv6addr --action conv6to4 \
				$(ip --family inet route get | sed $'s/.*src//\nq'))/16 dev tun6to4
	up ifconfig add int0 $(ipv6calc --in prefix+mac --out ipv6addr --action prefixmac2ipv6 \
                                 $(grep ^2002.*tun6to4$ /proc/net/if_inet6 | cut --output-delimiter=":" --characters=1-4,5-8,9-12):1::/64 \
                                 $(cat /sys/class/net/int0/address) \
        up /sbin/ip -6 route add 2000::/3 via :: dev tun6to4 metric 1
	up ip route get | sed $'s/.*src//\nq' > /etc/sv/tinydns4/env/IP
	up ipv6calc --in ifinet6 --out ipv6addr $(grep ^2002.*int0$ /proc/net/if_inet6| cut -f1 -d" ") > /etc/sv/dnscache6/env/IP
	up ipv6calc --in ifinet6 --out ipv6addr --printuncompressed \
                $(grep ^2002.*tun6to4$ /proc/net/if_inet6| cut -f1 -d" ") > /etc/sv/tinydns6/env/IP
        down /sbin/ip -6 route flush dev tun6to4
        down /sbin/ip link set dev tun6to4 down
        down /sbin/ip tunnel del tun6to4

Securing 6to4

Only ip6tables could protect the 6to4 system from being used as an anonymous IP forwarder, even if all the applications running were considered secure. Here I have 2 local interfaces using IPv6 addresses, and block data from tun6to4 from turning round and falling back in, in reality it may be more strict than this.

As ip4tables does not have a routine to match the inner ipv6 address at the ipv4 level, so use bpf make sure it is for us, so we do not particpate in a reflection attack, in particular require the 6to4 source address to contain the actual origin ipv4 before linux tun6in4 interface strips it away. This assumes dsl0 is a ppp interface. Replace the example addresses to use.

  1. iptables -A INPUT -d -i dsl0 -p 41 -m bpf --bytecode \
  2. "`tcpdump -ddd -i dsl0 \
  3. link[0x2c:2] = 0x2002 and \
  4. link[0x2e:4] = link[0x10:4] and \
  5. link[0x1c:2] = 0x2002 and \
  6. link[0x1e:4] = link[0xc:4] \
  7. | tr "\n" ","`" -j ACCEPT
  1. link[0x32:2] = 0 and \
  2. link[0x34:4] = 0 and \
  3. link[0x38:4] = 0 and \

It is still prudent to additionally configure all applications to reject usage from unauthorised sources wherever possible. This provides an additional layer of protection in case system comes up without firewall rules loading 😿

This means ALL: ALL in /etc/hosts.deny, then add permitted applications one by one in /etc/hosts.allow

For samba hosts deny = ::/0 with explicit allows for required hosts is useful.

Unless there are exotic requirements, usually allow system to communicate with itself

Let the system communicate with the outside world where the system initiates communication. Exceptions can be added to permit incoming communications such as to ports providing internet services.

Let an internal interface communicate freely with system, and to the outside world where the internal side initiates the communication.

There may also be an occasion to add some multicast iptables rules

It is good to set the firewall policy to drop so that we fail secure, when the rules are verified.

Run netfilter-persistent save to write out current rules so they start

Then, provided that 6to4 starts after the internet connection, there is IPv6. If the system shares a machine with Windows, substitute 2002:%02x%02x:%02x%02x:: for 2002:%02x%02x:%02x%02x::%02x%02x:%02x%02x and echo $ip for echo $ip.$ip to generate the same address as that OS may give itself. There are also other ways

Using 6to4 and native together.

We can set up multiple routing tables so endstations can reach both 6to4 and native remote nodes, using the 6to4 address to communicate with remote 6to4 nodes and native otherwise. The system will generally not send encapsulated traffic to, as 2002:: addresses usually communicate with other 2002:: addresses, with the local station selecting its site or global address to talk with remote stations in thore addressing classes.

Usually we will use tc, iptables and iproute2 together

echo 6to4 4 > /etc/iproute2/rt_tables.d/example.conf

If the site also has native ipv6 then that will be preferred.

up /sbin/ip -6 rule add from 2002:xxxx:xxxx::/48 lookup 6to4
up /sbin/ip -6 route add 2002::/16 table 6to4 dev tun6to4
up /sbin/ip -6 route add 2000::/3 table 6to4 via :: dev tun6to4

This means if the gateway receives a packet from 2002:xxxx:xxxx::/48 then consider the 6to4 routing table.

Sharing IPv6 on local ethernet

In 2018 I am using link-local (fe80::/64) , site-local(fec0::/64), 6to4 (2002::/16), and global addressing. The link-local and site-local can be redarded as fixed, with 6to4 and native subject to ISP changes, thus all except linklocal are advertised via radvd/slaac

Stations then can select site-local to communicate locally, this would not be affected by use of dynamic IP or provider switching. Multiple providers can be active and then there will be even more prefix advertised.

The ultimate configuration could advertise 6to4 and native only when the ISP is online, giving all stations immediate visibility on whether they can use the "Internet". local communications would use local addresses by default.

For 6to4 space, downstream interfaces have added a 2002 address formed from each serving public ipv4 address. Add these lines under gateway ::, changing d0be for desired network or vlan number.

	up ifconfig $IFACE add `ifconfig sit0 | grep "inet6 addr: 2002" | cut -d : -f 
2-4`:1:`c(){ echo ${5:0:1}$(printf %x $((${5:1:1}^2)))${5:3:2}:${5:6:2}ff:fe${5:9:2}:${5:12:2}${5:15:2};};c $(ifconfig $IFACE)`/64
	down ifconfig $IFACE del `ifconfig sit0 | grep "inet6 addr: 2002" | cut -d : -f 2-4`:d0be:
`c(){ echo ${5:0:1}$(printf %x $((${5:1:1}^2)))${5:3:2}:${5:6:2}ff:fe${5:9:2}:${5:12:2}${5:15:2};};c $(ifconfig $IFACE)`/64

The router machine has to tell the others to use it as gateway. To do this, stateless advertisement "slaac" or dhcpv6 culd be used.

radvd requires a configuration file to say which addresses to give out. You can generate this automatically from your sit0 address, especially reccommended if you don’t have a fixed public IP address. You could generate a config file as follows, assuming your internal interface is int0 and that it’s already configured with it’s own public v6 address as above, then start radvd up with /etc/init.d/radvd start. Multiple ethernet interfaces could also be handled separately by giving each their own interface block in radvd.conf if you prefer that, instead of bridging them together as here.

The MTU of 6to4 routes may need to restrict to 1480 if the corresponding IPv4 tunnel or 6to4 is limited to an MTU of 1500. If using native IPv6, then an AdvLinkMTU of 1500 or more is likely to be possible. If it is not set then TCP or UDP find their too-large packets are thrown away rather than knowing not to send them, and do not work as well as they could.

NET=`ifconfig $IFACE | grep "inet6 addr: 2002" | cut -d : -f 2-5`
echo 'interface '$IFACE'
	AdvLinkMTU 1480;
	AdvSendAdvert on;
	prefix '$NET'::/64
		AdvOnLink on;
		AdvAutonomous on;
};' > /etc/radvd.conf


radvd gives computers their site and ISP IPv6 addresses, such as a native and a 6to4 address. Also, internet address of nameservers, and a dns search list. isc dhcp has an ipv6 mode used to issue DNS to UEFI IPV6 pxe bios and microsoft windows.

the isc dhcpv6 matches on an item called DUID rather than directly on ethernet mac addresses, a class and subclasses can be defined to match on both.

the 3 definitions are then used to issue to ipv4, DUID-LLT and DUID-LL, so stations get the same addresses that radvd gives, whilst await support for use-eui-64 true;

  1. class "dhcp-fake-stateless" {
  2. match pick-first-value (hardware,concat(substring(option dhcp6.client-id, 0, 4), suffix (option dhcp6.client-id, 6)));
  3. }
  4. subclass "dhcp-fake-stateless" 1:AC:DE:48:23:45:67
  5. subclass "dhcp-fake-stateless" 0:1:0:1:AC:DE:48:23:45:67
  6. subclass "dhcp-fake-stateless" 0:3:0:1:AC:DE:48:23:45:67

In the end I got bored of doing this and a 2022 patch for ISC DHCPv6 enables it to issue predictable addresses directly to clients derived wherever possible from their MAC address, that (not so) coincidently matches the ones generated by "slaac"

Patching DHCPv6 like that enables a vastly simpler config file that basically just specifies prefixes:

  1. authoritative;
  2. use-eui-64 true;
  3. persist-eui-64-leases true;
  4. limit-addrs-per-ia 256;
  5. lease-id-format hex;
  6. allow duplicates;
  7. shared-network vd0be {
  8. subnet6 fec0:0:0:d0be::/64 {
  9. pool6 {
  10. range6 fec0:0:0:d0be:0:0:0:0 fec0:0:0:d0be:ffff:ffff:ffff:ffff;
  11. allow all clients;
  12. option dhcp6.name-servers fec0:0:0:d0be:aede:48ff:fe23:4567;
  13. option dhcp6.sntp-servers fec0:0:0:d0be:aede:48ff:fe23:4567;
  14. option dhcp6.domain-search "example.home.arpa","home.arpa";
  15. }
  16. }
  17. }

Here vlan d0be is served up a nameserver and ntp server, and the server (hopefully) calculates predictable addresses for clients. This is more typical of a stateless internal management network, hence the use of fec0.

Reverse DNS

It’s useful to create a reverse DNS zone on nameservers so that machines can have DNS names, even for 6to4 users. They can set up reverse dns delegation as well.

Annex for users of Sky ADSL

Users of this service have to use the supplied Netgear ADSL router, and it changes IP address periodically. Users may set a DMZ machine in its configuration, and its inbuilt DHCP server can be set to fix the IP allocation for this machine and others by MAC Address. This machine can provide 6to4 service to the other computers.

for the /etc/network/interfaces

iface sit0 inet6 static
        up /usr/local/sbin/6to4guard
        up /sbin/ifconfig int0 add $(/usr/local/sbin/lanip)
        up /etc/init.d/radvd reload
        down /sbin/ifconfig int0 del $(ifconfig int0 | grep "inet6 addr: 2002" | tr -s " " | cut -d" " -f4)
        address `printf "2002:%02x%02x:%02x%02x::" \`routerip | tr "." " "\``
        netmask 16
        gateway ::

source code of routerip

# sky router screenscraper

while test -z "${IP2}"
        IP=$(wget -O - --user=admin --password=sky -q | grep -A 2 "IP Address" | head -2 | tail -1)
        IP2=$(cut -d$'>' -f2 <<<"${IP}" | cut -d$'<' -f1)
        sleep 1
echo $IP2

source of lanip

LAN=$(/sbin/ifconfig sit0 | grep 2002 | tr -s " " | cut -d" " -f4 | cut -d":" -f1-3)
IP=:`c(){ echo ${5:0:1}$(printf %x $((${5:1:1}^2)))${5:3:2}:${5:6:2}ff:fe${5:9:2}:${5:12:2}${5:15:2};};c $(ifconfig int0)`/64
echo ${LAN}$':1'${IP}

echo -ne $'interface int0\n{
AdvSendAdvert on;\n
prefix '${LAN}$':1'${IP}$'\n{AdvOnLink on;\nAdvAutonomous on;\nAdvRouterAddr on;\n};\n};' > /etc/radvd.conf

Users may use the same 6to4guard script as above.

Experiment of MAC OS X 6to4 via a Belkin router

This is partially complete, the Mac OS X would not originate 2002:: packets unless the embedded IPv4 address is configured to an interface, though that will then be inserted into outgoing packets too, which may need to be changed for the router to accept it.

ROUTERIP=$(2>/dev/null curl -q | grep 'var wan_ip' | cut -d\" -f2)
ifconfig stf0 inet6 $(printf "2002:%02x%02x:%02x%02x::" $(<<<"${ROUTERIP}" tr . " ") prefixlen 16 -alias
ifconfig stf0 inet6 $(printf "2002:%02x%02x:%02x%02x::" $(<<<"${ROUTERIP}" tr . " ") prefixlen 16
ifconfig en1 ${ROUTERIP} alias

Altering of Gateway MTU on Mac OS X

To drop MTU use a startup file although it is preferred to use route instead of ifconfig to set MTU, as you might be using standard size frames or even jumbograms on your local network but be restricted to 1500 sized Ethernet or even less to reach the Internet.

This example appleis if your ISP provides an MTU of 1492 (8 less than the ethernet max 1500) and want to use 6to4 tunnelling, which will subtract another 20 giving 1472. Mac OS X seems very picky about ordering of options hence these notes.

route -vn change default -mtu 1492
route -vn change -inet6 default -mtu 1472
netstat -nrl

Network Manager

We can create vlan entries in /etc/NetworkManager/system-connections/ where `uuid` is replaced with a generated UUID.

We suppose for example purposes that the device has a MAC of AC:DE:48:23:45:67

We change autoconnect to true, to bring up when device enp0s0 comes up





If the vlan device is not intended for direct IP usage, then it can be setup without.

>/etc/NetworkManager/system-connections/printer echo "
uuid="`uuidgen -t`"




Once the file is set, use nmcli con up id experiment but notice that nmcli will complain Error: Unknown connection:/ if the file is present and either incorrect or readable to users other than root.

Some distributions of GNOME3 hide applets from the system tray or notification area.

What is with the ipv6 only list element?

Or, are my favourite websites still ipv4 only?

Some info could be seen in F12 developer tools on various browsers, then go over to Network and reload.

  1. IPv6 transition was not the all at once event that some would like, as site operators fear cutting themselves off from customers in case their site is unreachable when dual-stacked
  2. Instead the behaviour seen if a popular site looks like it is still ipv4 only can be seen in F12 developer tools. Users may well find some ipv6 resources, and can imagine the site to be monitoring that closely.
  1. The first thing they can do is make a minor resource like a bullet or pixel dual stacked, so the site as a whole still loads over ipv4.
  2. This item may load oven ipv6, or ipv4, be delayed or not load at all, chosen so that minimal effect on the website appearance if it does not load.
  3. This can be seen in F12 as various resource get loaded over ipv6, the operator monitors that carefully to see if visitors are at least able to load that resource over ipv4, whereas ipv6 is a bonus.
  4. A very few unlucky visitors obsolete resolvers might crash but that then cuts off the internet for them and they have to fix it without knowing the dual stacked resource as the cause, and are therefore unable to blame the site operator, solving that issue.
  5. Time passes and near enough 100% of visitors can load the site and all resources, for the operator to decide to add ipv6 to all domain names.
  6. Some time later, the operator likes to know what happens if visitors get an ipv6 only resource, so put one on an ipv6 only domain, that has minimal layout consequence if it does not load. This reveals a user ipv6 address even if they usually favour ipv4. This server is at this stage.
  7. Finally, everyone of importance can access over ipv6 so lose the ipv4 address off the main domain, not there so far.

The End

Some extra info for trying IPv6 on Windows XP and tg582n