Altibox IPv6 using DHCP Client

December 28, 2024 | 8 minutes read

Altibox now supports native IPv6 and IPv4 stacks and gone are the days of dealing with IPv6 rapid deployment otherwise abbreviated as 6rd. Here is my updated config for my Mikrotik router using IPv6 dhcp-client instead of 6rd.

In my previous article Altibox IPv6 with 6to4 we needed to pre-plan IPv6 addresses based on our IPv4 address before connecting. By using native IPv6 DHCP client we can skip all that and just set up a ipv6-client and then do address planning after we get our prefix delegation via the client.

Altibox provides a webpage explaining their support for IPv6 and the main message is that you need to start a dhcp-client on your router to get IPv6 prefix delegations. https://wiki.mikrotik.com/Manual:IPv6/DHCP_Client

Enabling the IPv6 DHCP Client

Let’s start by putting the Altibox central in Bridge Mode. More info from Altibox here.

Note: Using your own router without the Altibox central is out of scope for this article.

Setting up a dhcp-client is pretty straight forward. We start by assigning the first address we get from the prefix delegation on our bridge interface and secondly create a dhcp-client on our ether1 which is my WAN port. We also add-default-route, give the dynamic addres pool a name and hinting that we want a ::/56 block delegation. Lastly we are asking that the dhcp-client should handle address and prefix delgation and that we won’t be using the ISPs DNS’es.

# Add the first address from the prefix that will be delegated to us
/ipv6 address
add address=::1 from-pool=ipv6-pd interface=bridge

# Start the dhcp-client
/ipv6 dhcp-client
add add-default-route=yes comment="Altibox pd" interface=ether1 pool-name=ipv6-pd prefix-hint=::/56 request=address,prefix use-peer-dns=no

Then we activate neighbour discovery and configure the defaults for the prefix.

/ipv6 nd
set [ find default=yes ] mtu=1480

/ipv6 nd prefix default
set autonomous=yes preferred-lifetime=1w valid-lifetime=4w2d

Verifying connectivity

Please note: I have replaced parts of the addresses with cafe,b00b or babe for masking parts of the real addresses. I also like silly stuff and playing with the words that you can create in your ipv6 addressing. IPv6 addresses use hexadecimal notation ranging from 0-9 and a-f.

Let’s investigate our address and prefix delegation from Altibox. We can see that our delegation prefix is 2a01:799:192:cafe::/56 and our router’s address is 2a01:798:100:600:b5b5:70e4:f0f0:b00b

/ipv6/dhcp-client print
Columns: INTERFACE, STATUS, REQUEST, PREFIX, ADDRESS
# INTERFACE  STATUS  REQUEST  PREFIX                            ADDRESS
;;; Altibox pd
0 ether1     bound   address  2a01:799:192:cafe::/56, 6h28m32s  2a01:798:100:600:b5b5:70e4:f0f0:b00b, 6h28m32s
                     prefix

# Print more detail for the same connection. I mangled with the output for better readability
/ipv6/dhcp-client/print detail
Flags: D - dynamic; X - disabled, I - invalid
 0    ;;; Altibox pd
      interface=ether1 status=bound duid="0x000b00b0cafe" dhcp-server-v6=fe80::201:3ff:babe:1
      request=address,prefix add-default-route=yes default-route-distance=1 use-peer-dns=no
      allow-reconfigure=no dhcp-options="" pool-name="ipv6-pd" pool-prefix-length=64
      prefix-hint=::/56 prefix-address-lists="" dhcp-options=""
      prefix=2a01:799:192:cafe::/56, 6h11m20s address=2a01:798:100:600:b5b5:70e4:f0f0:b00b, 6h11m20s

# print out ipv6 addresses
/ipv6/address print
Flags: D - DYNAMIC; G - GLOBAL, L - LINK-LOCAL
Columns: ADDRESS, FROM-POOL
 #    ADDRESS                                  FROM-POOL
 0 D  ::1/128
 1 DG 2a01:798:100:600:b5b5:70e4:f0f0:b00b/128
 2  G 2a01:799:192:cafe::1/64                  ipv6-pd

# print out the ipv6 routes
/ipv6/route/print
Flags: D - DYNAMIC; I - INACTIVE, A - ACTIVE; c - CONNECT, d - DHCP; H - HW-OF>
Columns: DST-ADDRESS, GATEWAY, DISTANCE
     DST-ADDRESS                              GATEWAY                      D
DAd  ::/0                                     fe80::201:3ff:babe:1%ether1  1
DAd  2a01:799:192:cafe::/56                                                1
DAc  2a01:799:192:cafe::/64                   bridge                       0

Pingtest on the router

Perform a ping test directly on the router. Please note the nuance of using the ping [:resolve some.ipv6host.tld] notation when pinging ipv6 addresses.

/ping [:resolve ipv6.google.com]
  SEQ HOST                                     SIZE TTL TIME       STATUS
    0 2a00:1450:400f:801::200e                   56  61 8ms770us   echo reply
    1 2a00:1450:400f:801::200e                   56  61 8ms838us   echo reply
    2 2a00:1450:400f:801::200e                   56  61 8ms869us   echo reply
    3 2a00:1450:400f:801::200e                   56  61 8ms864us   echo reply
    sent=4 received=4 packet-loss=0% min-rtt=8ms770us avg-rtt=8ms835us max-rtt=8ms869us

Testing on your computer

You can test through your browser and here are some examples:

Example of pinging from a linux or a mac with the ping6 command.

ping6 -c 4 ipv6.google.com
PING ipv6.google.com (2a00:1450:400f:801::200e) 56 data bytes
64 bytes from arn09s22-in-x0e.1e100.net (2a00:1450:400f:801::200e): icmp_seq=1 ttl=60 time=9.46 ms
64 bytes from arn09s22-in-x0e.1e100.net (2a00:1450:400f:801::200e): icmp_seq=2 ttl=60 time=24.1 ms
64 bytes from arn09s22-in-x0e.1e100.net (2a00:1450:400f:801::200e): icmp_seq=3 ttl=60 time=39.4 ms
64 bytes from arn09s22-in-x0e.1e100.net (2a00:1450:400f:801::200e): icmp_seq=4 ttl=60 time=32.5 ms

--- ipv6.google.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 9.459/26.360/39.374/11.159 ms

Testing traceroute with the traceroute6 utility

$ traceroute6 nrk.no
traceroute to nrk.no (2a02:26f0:4300::1724:4cf8), 30 hops max, 80 byte packets
 1  router.samueljon.tech (2a01:799:192:cafe::1)  0.836 ms  1.164 ms  2.244 ms
 2  * * *
 3  g2a02-26f0-4300-0000-0000-0000-1724-4cf8.deploy.static.akamaitechnologies.com (2a02:26f0:4300::1724:4cf8)  5.013 ms  5.138 ms  5.489 ms

Delegating /64 subnets from the /56 delegation

Key Points in IPv6 Addressing

  • An IPv6 address has 128 bits.
  • A /56 prefix means the first 56 bits are fixed, leaving 72 bits available for subnetting and hosts.
  • A /64 subnet is standard for most IPv6 configurations, leaving 64 bits for host addressing.

Subnetting Calculation

  • To go from a /56 to a /64, you are adding 8 bits to define the subnet.
  • With these 8 bits, you can create 2^8 subnets.
  • 2^8=256 subnets.

This means you can create 256 unique /64 subnets from a single /56 prefix. Each /64 subnet can then support 2^64−1 unique host addresses.

We can use the ipv6calc tool to get more insights on the prefix as shown below.

The ipv6calc is an open-source software that you can install on your *nix machine with the corresponding package manager. I did this on a Mac OSX machine and did install it via homebrew brew install ipv6calc

subnetcalc 2a01:799:192:cafe::/56
Address       = 2a01:799:192:cafe::
                   2a01 = 00101010 00000001
                   0799 = 00000111 10011001
                   0192 = 00000001 10010010
                   cafe = 11001010 11111110
                   0000 = 00000000 00000000
                   0000 = 00000000 00000000
                   0000 = 00000000 00000000
                   0000 = 00000000 00000000
Network       = 2a01:799:192:ca00:: / 56
Netmask       = ffff:ffff:ffff:ff00::
Wildcard Mask = ::ff:ffff:ffff:ffff:ffff
Hosts Bits    = 72
Max. Hosts    = 2^72 - 1
Host Range    = { 2a01:799:192:ca00::1 - 2a01:799:192:caff:ffff:ffff:ffff:ffff }
Properties    =
   - 2a01:799:192:cafe:: is a HOST address in 2a01:799:192:ca00::/56
   - Global Unicast Properties:
      + Interface ID = 0000:0000:0000:0000
      + Sol. Node MC = ff02::1:ff00:0000
DNS Hostname  = (Name or service not known)

Here we can see that the allocation consists of the following range:

2a01:799:192:ca00::1 - 2a01:799:192:caff:ffff:ffff:ffff:ffff

Here are some funny /64 prefixes derived from the 2a01:799:192:cafe::/56 prefix delegation.

    2a01:799:192:cafe:babe::/64 # Playful nod to "babe."
    2a01:799:192:cafe:b00b::/64 # A cheeky reference with "b00b."
    2a01:799:192:cafe:f00d::/64 # Perfect for a foodie subnet, referencing "food."
    2a01:799:192:cafe:dead::/64 # For the dark humor crowd: "dead."
    2a01:799:192:cafe:beef::/64 # A fun choice, "beef" for tech-savvy carnivores.
    2a01:799:192:cafe:c0de::/64 # Nerdy and coding-themed: "code."
    2a01:799:192:cafe:baad::/64 # "Bad" in leetspeak for a subnet with a mischievous reputation.
    2a01:799:192:cafe:face::/64 # Playful and memorable with "face."
    2a01:799:192:cafe:feed::/64 # For an infrastructure feeding data or services: "feed."
    2a01:799:192:cafe:cafe::/64 # Classic redundancy and humor: "cafe" in the "cafe" delegation.
    2a01:799:192:cafe:bead::/64 # Perfect for a creative arts subnet.
    2a01:799:192:cafe:b055::/64 # For the boss: "boss."
    2a01:799:192:cafe:b33r::/64 # For the after-hours network: "beer."
    2a01:799:192:cafe:d00d::/64 # Friendly and casual: "dude."

If you want to delegate /64 prefixes to other vlans or interfaces you can see some of my previus post on ipv6. You can use the ipv6 tag in the sidebar on the main page to find relevant articles.

Firewall configuration

It is possible that these rules are already in your router since these are the default ipv6 rules that come as default.

/ipv6 firewall address-list
add address=::/128 comment="defconf: unspecified address" list=bad_ipv6
add address=::1/128 comment="defconf: lo" list=bad_ipv6
add address=fec0::/10 comment="defconf: site-local" list=bad_ipv6
add address=::ffff:0.0.0.0/96 comment="defconf: ipv4-mapped" list=bad_ipv6
add address=::/96 comment="defconf: ipv4 compat" list=bad_ipv6
add address=100::/64 comment="defconf: discard only " list=bad_ipv6
add address=2001:db8::/32 comment="defconf: documentation" list=bad_ipv6
add address=2001:10::/28 comment="defconf: ORCHID" list=bad_ipv6
add address=3ffe::/16 comment="defconf: 6bone" list=bad_ipv6
add address=::224.0.0.0/100 comment="defconf: other" list=bad_ipv6
add address=::127.0.0.0/104 comment="defconf: other" list=bad_ipv6
add address=::/104 comment="defconf: other" list=bad_ipv6
add address=::255.0.0.0/104 comment="defconf: other" list=bad_ipv6
/ipv6 firewall filter
add action=accept chain=input comment="defconf: accept established,related,untracked" connection-state=established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=invalid
add action=drop chain=input dst-port=53 in-interface=!LAN protocol=tcp
add action=drop chain=input dst-port=53 in-interface=!LAN protocol=udp
add action=accept chain=input comment="defconf: accept ICMPv6" protocol=icmpv6
add action=accept chain=input comment="defconf: accept UDP traceroute" port=33434-33534 protocol=udp
add action=accept chain=input comment="defconf: accept DHCPv6-Client prefix delegation." dst-port=546 protocol=udp src-address=fe80::/10
add action=accept chain=input comment="defconf: accept IKE" dst-port=500,4500 protocol=udp
add action=accept chain=input comment="defconf: accept ipsec AH" protocol=ipsec-ah
add action=accept chain=input comment="defconf: accept ipsec ESP" protocol=ipsec-esp
add action=accept chain=input comment="defconf: accept all that matches ipsec policy" ipsec-policy=in,ipsec
add action=drop chain=input comment="defconf: drop everything else not coming from LAN" in-interface-list=!LAN
add action=accept chain=forward comment="defconf: accept established,related,untracked" connection-state=established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" connection-state=invalid
add action=drop chain=forward comment="defconf: drop packets with bad src ipv6" src-address-list=bad_ipv6
add action=drop chain=forward comment="defconf: drop packets with bad dst ipv6" dst-address-list=bad_ipv6
add action=drop chain=forward comment="defconf: rfc4890 drop hop-limit=1" hop-limit=equal:1 protocol=icmpv6
add action=accept chain=forward comment="defconf: accept ICMPv6" protocol=icmpv6
add action=accept chain=forward comment="defconf: accept HIP" protocol=139
add action=accept chain=forward comment="defconf: accept IKE" dst-port=500,4500 protocol=udp
add action=accept chain=forward comment="defconf: accept ipsec AH" protocol=ipsec-ah
add action=accept chain=forward comment="defconf: accept ipsec ESP" protocol=ipsec-esp
add action=accept chain=forward comment="defconf: accept all that matches ipsec policy" ipsec-policy=in,ipsec
add action=drop chain=forward comment="defconf: drop everything else not coming from LAN" in-interface-list=!LAN

Credits

Added 2024.12.01: Post from Nils Norman Haukås on the same topic but using different type of router.

Added 2024.12.28: Github link to trrunde’s routerconfig.

Photo by Christopher Burns on Unsplash

popular post

Altibox IPv6 using DHCP Client

Altibox now supports native IPv6 and IPv4 stacks and gone are the days of …

Read More

7 Types of Rest

Are you getting enough sleep but still feeling tired? Perhaps you are not …

Read More

The life as a ballerina

I love getting inspired, and sometimes that inspiration comes from unexpected …

Read More