Stupid ipv6 tricks – get current ipv6 address – linux

December 16th, 2023

how to get current ipv6 address when addresses change
my computer got a new address, the old address has a preferred lifetime of 0:

# ip -6 address show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
inet6 2604:3d09:3580:a:f66d:4ff:fe32:eaf9/64 scope global mngtmpaddr dynamic
valid_lft 600sec preferred_lft 300sec
inet6 2604:3d00:d44a:486:f66d:4ff:fe32:eaf9/64 scope global deprecated mngtmpaddr dynamic
valid_lft 300sec preferred_lft 0sec
inet6 fe80::f66d:4ff:fe32:eaf9/64 scope link
valid_lft forever preferred_lft forever

I only want the valid address for scripts:
# ip -6 address show dev eth0 | grep -v deprecated | grep mngtmpaddr | sed -e’s/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d’



What this does:

  1. ip -6 address show dev eth0
    1. This shows all the ipv6 addresses configured on eth0
  2.  grep mngtmpaddr
    1. This grep displays only addresses that were derived from the MAC address (IE SLAAC addresses)
  3. grep -v deprecated
    1. This grep removes addresses that are deprecated (IE preferred lifetime = 0) and shouldn’t be used.
  4. sed  -e’s/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d’
    1. This regex removes  everything but IPv6 addresses from the line.
      1. found at

need some way to detect when changes happen.

Stupid ipv6 tricks – get current global ipv6 prefix – linux

July 29th, 2023

I need to know what global prefix my server is on in order to be able to add firewall rules allowing access from this prefix for specific ports. I don’t control the gateway, but it only gives me the one prefix I’m currently using in the router advertisement.

I can use “ip -6 route show dev eth0” to get the routes, including the prefix:

$ ip -6 route show dev eth0
2001:db8:778:6600::/64 proto ra metric 1 expires 299sec pref medium
fe80::/64 proto kernel metric 256 pref medium
default via fe80::dead:beff:dead:beef proto ra metric 1 expires 179sec pref medium

Since I’ve gotten it from the router advertisement and it’s not the default route and we want the lowest metric (at least in my case), we can grep for the specific line and get only the prefix itself to be used in bash scripts:

prefix=$(ip -6 route show dev eth0 | grep "proto ra metric 1" | grep -v ^default | awk '{print $1}')

Stupid IPv6 Tricks

June 22nd, 2015

Today, I was given a VM with an IPv6 address, but it had no IPv6 default route:

$ route -A inet6
Kernel IPv6 routing table
Destination Next Hop Flags Metric Ref Use Iface
2001:db8:80:fd::/64 * U 256 1 0 eth1
fe80::/64 * U 256 0 0 eth1
localhost/128 * U 0 48 1 lo
2001:db8:80:fd::67:8/128 * U 0 77 1 lo
fe80::a00:32ff:feb7:73cd/128 * U 0 53 1 lo
ff00::/8 * U 256 0 0 eth1


I was also not given the router I needed to set the default route to. But no fear, we can ping the router multicast address!

$ ping6 ff02::2 -I eth1 -c1
PING ff02::2(ff02::2) from fe80::a00:32ff:feb7:73cd eth1: 56 data bytes
64 bytes from fe80::a00:32ff:fe4f:9ebc: icmp_seq=1 ttl=64 time=0.411 ms
--- ff02::2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.411/0.411/0.411/0.000 ms

And all is solved!

# route -A inet6 add default gw fe80::a00:43ff:fe4f:9ebc dev eth1
$ route -A inet6
Kernel IPv6 routing table
Destination Next Hop Flags Metric Ref Use Iface
2001:db8:80:fd::/64 * U 256 1 0 eth1
fe80::/64 * U 256 0 0 eth1
*/0 fe80::a00:32ff:fe4f:9ebc UG 1 0 0 eth1
localhost/128 * U 0 48 1 lo
2001:db8:80:fd::67:8/128 * U 0 77 1 lo
fe80::a00:32ff:feb7:73cd/128 * U 0 53 1 lo
ff00::/8 * U 256 0 0 eth1
$ ping6 -c1
PING 56 data bytes
64 bytes from icmp_seq=1 ttl=48 time=163 ms
--- ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 163.953/163.953/163.953/0.000 ms

And there was much rejoicing!

Enabling a DHCPv6 client with Prefix Delegation ability on Ubuntu Server

April 11th, 2013

What is Prefix Delegation?
Prefix Delegation (PD) is a mechanism for a DHCPv6 server to let a home networking router ask for an IPv6 prefix (subnet) that the router can then split up and delegate to the clients it serves.

In the (hopefully) not too distant future, ISPs will be offering native IPv6. Since there is no NAT in IPv6, and most people have at least a couple of computers sitting behind a hardware NAT box, they will need to get IPv6 addresses for every device they have. This is done via DHCPv6 and PD. When your ISP is ready (if it isn’t already) you’ll be able to use this to participate in the IPv6 world!

Let’s just dig in then!
Required software:

  • wide-dhcp6c


Why wide-dhcp6c, instead of ISC’s dhclient with IPv6 options?

  1. IPv6 documentation on dhclient is lacking and almost non-existant.
  2. wide-dhcp6c has the ability to assign a block from the received PD block to an interface.
  3. ISC requires you to run a separate instance for v6 anyway.


For this example network:
eth0 = WAN (ISP facing) interface
eth1 = LAN (home network) interface

in /etc/sysctl.conf add/set:

net.ipv6.conf.all.forwarding = 1

This makes the server a router (forwarding = 1) and allows eth0 to continue accepting Router Advertisements to get it’s default route. (by default, it will no longer accept Router Advertisements when forwarding is set.)

in /etc/network/interfaces add/set:

iface eth0 inet6 static

We set it to static because we will not be using the ISC DHCP client to obtain our IPv6 address and prefix, we will be using the wide dhcpv6 client.

To install the wide dhcpv6 client run this on the command line:

sudo apt-get install wide-dhcpv6-client

On install, you will get a prompt like this:
click to embiggen!
Enter the WAN interface (eth0 in our case)

Configure wide dhcp6c

cd /etc/wide-dhcp6c
sudo nano dhcp6c.conf

make it look like:

interface eth0 { # external facing interface (WAN)
  send ia-na 1;
  send ia-pd 1;
  request domain-name-servers;
  request domain-name;
  script "/etc/wide-dhcpv6/dhcp6c-script";

id-assoc pd 1 {
  prefix-interface eth1 { #internal facing interface (LAN)
    sla-id 0; # subnet. Combined with ia-pd to configure the subnet for this interface.
    ifid 1; #IP address "postfix". if not set it will use EUI-64 address of the interface. Combined with SLA-ID'd prefix to create full IP address of interface.
    sla-len 8; # prefix bits assigned. Take the prefix size you're assigned (something like /48 or /56) and subtract it from 64. In my case I was being assigned a /56, so 64-56=8

  id-assoc na 1 {
  # id-assoc for eth1

Install RADVD

sudo apt-get install radvd

Then change the default start from S20 to S98 and add a 10 second delay (to run *after* wide-DHCPv6 is done, otherwise it can’t pick up the IPv6 prefix that has been assigned)
– get normal runlevel:

N 2

Go to the runlevel directory:

cd /etc/rc2.d

(replace the 2 with the number from previous command)

mv S20radvd S98radvd

Edit S98radvd and add

sleep 10

after the first set of comments.
We move it to S98 so pretty much everything else is done starting and we’re not delaying anything important by that 10 seconds.

Configure the following in /etc/radvd.conf
interface eth1 # LAN interface
AdvManagedFlag off; # no DHCPv6 server here.
AdvOtherConfigFlag off; # not even for options.
AdvSendAdvert on;
AdvDefaultPreference high;
AdvLinkMTU 1280;
prefix ::/64 #pick one non-link-local prefix assigned to the interface and start advertising it
AdvOnLink on;
AdvAutonomous on;

Restart radvd
sudo /etc/init.d/radvd restart

And if your ISP has a DHCPv6 server running, you should have a happy IPv6 address everywhere.
To check if things are working:
ifconfig eth0
ifconfig eth1
(to see if IPv6 addresses are assigned.)
If you don’t have an IPv6 address on these interfaces that doesn’t start with fe80::, then it’s likely (at this point) that your ISP doesn’t have IPv6 enabled.

Writing an IPv6 Address – The 6 Commandments of RFC5952

February 13th, 2012

When we write down IPv4 addresses, no one really has to go over just how you write them. Most people get it after only a little while of seeing it done. 4 sets of numbers, from 0 to 255, each separated by a “.”.
When IPv6 started to be developed, it quickly became apparent that there needed to be an easier way to write it out than (for example)
Even if you quickly realize that you could drop the leading zeros (as we naturally do in “dotted decimal”), it’s still fairly unwieldy:
even if it is much better.
So the idea of the double colon was introduced to combine sets of zero’s together. The first RFC’s said that 1 or more groups of 16 bits of zeros could be combined to “::”
That’s almost usable! Of course it won’t always go that easily, especially if you start using SLAAC to configure your network:
Darn. But still better than nothing.
Unfortunately, even with these rules, there wasn’t enough of them for the machines who are the ultimate users of these. By the rules that are defined in earlier RFC’s, all of these are valid:
and case wasn’t ever discussed either:
is perfectly legit.
This makes it harder to write code for things that need to decode these addresses. And RFC 5952 was written to try and address these shortcomings.

Here are the 6 commandments of RFC 5952:
1) Thou shalt not SHOUT your IPv6 address.

    IPv6 must be written in lowercase. 2001:db8::1 not 2001:DB8::1

2) Thou shall destroy leading zeros.

    Always truncate leading zeros. 2001:0db8::1 is not acceptable, you must use 2001:db8::1

3) Thou shalt not use the double colon where there is only one 16 bit set of zeros.

    If you only have one set of 4 zeros, you can no longer use the double colon, instead it just gets shortened to one zero. An address such as 2001:db8:0000:4:5:6:7:8 can’t use the double colon and only gets shortened to 2001:db8:0:4:5:6:7:8

4) Thou shall use the double colon to it’s greatest potential.

    If you have multiple sets of more than 8 zeros, you have to use the set with the most zeros. So if you have 2001:db8:0000:0000:1:0000:0000:0000 you have to use the double colon on the right set of 0’s – 2001:db8:0:0:1::

5) Wheresoever thou has two places to use the double colon, thou shall use the leftmost.

    If there are 2 equal sets of zeros, use the double colon on the one on the left, and single zeros on the right. 2001:db8:0000:0000:1:0000:0000:1 would become 2001:db8::1:0:0:1

6) Thou shall use the square brackets to separate IPv6 address from thy port number.

    When writing an IPv6 address with a port number, use square brackets around the IPv6 address to keep confusion at bay, since ports are appended with a : (the same separator as IPv6 sections): [2001:db8::1]:80 With the square brackets, we know it’s IPv6 address 2001:db8::1 on port 80, not IPv6 address 2001:db8::1:80

IPv6 Friday

February 13th, 2012

This site looks to be quite the resource. I think it’s my favorite new IPv6 website/blog. Every Friday, IPv6 Friday encourages you to spend 30 minutes learning/testing something new about IPv6. Take some time out of your Friday and get on the bandwagon!

World IPv6 Launch

February 12th, 2012

Just under one year after World IPv6 Day comes World IPv6 Launch. Organizations are coming together to *permanantly* enable IPv6 for their sites/customers. This is the event most of us have been waiting for. Once IPv6 is running on major sites full time, we’ll really get to test out infrastructure and troubleshooting on it. However, it will also mean that anyone that is looking to enable IPv6 on their network from that point onward will have to be very careful about how they do it. Much more will be at stake, as there will be major sites that will prefer IPv6, so any issues will be quickly noticed! Of course that also means that the days of multi-day IPv6 outages should be over! 🙂

Simple Approach to Prefix Distribution in Basic Home Networks

January 31st, 2012

Here’s a draft (on it’s way to becoming an RFC) up at the IETF that describes how home networks could distribute IPv6 addresses obtained from an ISP.

It’s nice to see some of this work finally being done! Also, while they say “Basic Home Networks”, by today’s standards, some of the examples are quite advanced (however that’s not saying it will always remain that way!)

As is often the case, this draft expired. However, it’s not forgotten as it’s been resurrected here

World IPv6 Day is here!

June 7th, 2011

World IPv6 day appears to be off and running to a pretty awesome start, if Hurricane Electric’s stats are anything to go by. They posted an image of their traffic about 1 hour after the start of IPv6 and, well, take a look: traffic

Akaimai also has a nice graph of their traffic at

IPv6 Firewalling with ip6tables

March 30th, 2011

Now that you’ve gotten IPv6 configured on your home network, forget about relying on NAT to be your “firewall”. All your devices now have a globally routed IP (v6) address, so it’s time to get familiar with a setting up a “real” firewall.

Since my IPv6 router is a linux box that is also other things (server, wireless access point, etc) I can’t set up a nice dedicated firewall like pfsense (currently IPv6 is enabled on the beta versions) without spending more money and quite a bit more work. So I’ll work with what I have – ip6tables

Here’s a simple set of ip6tables rules I’ve come up with. You’ll want to tweak these for your specific site. Mine are called from /etc/rc.local

# IPv6 firewall (ipv6tables)
#flush tables
ip6tables -F

#Define Policy
ip6tables -P INPUT DROP
ip6tables -P FORWARD DROP
ip6tables -P OUTPUT ACCEPT

# Input to the router
# Allow all loopback traffic
ip6tables -A INPUT -i lo -s 0/0 -d 0/0 -j ACCEPT

#Allow unrestricted access on internal network
ip6tables -A INPUT -i $LAN_IF -j ACCEPT
ip6tables -A INPUT -i $WLAN_IF -j ACCEPT

#Allow unrestricted outgoing connections
ip6tables -A INPUT -i $WAN_IF -m state --state RELATED,ESTABLISHED -j ACCEPT

# Forwarding through from the internal network
# For now allow unrestricted access out from the internal network
ip6tables -A FORWARD -i $LAN_IF -j ACCEPT
ip6tables -A FORWARD -i $WLAN_IF -j ACCEPT

#Allow unrestricted outgoing connections
ip6tables -A FORWARD -i $WAN_IF -m state --state RELATED,ESTABLISHED -j ACCEPT

# allow SSH in
ip6tables -A FORWARD -s 2000::/3 -i $WAN_IF -p tcp -m tcp --dport 22 -j ACCEPT

# allow remote desktop in
ip6tables -A FORWARD -s 2000::/3 -i $WAN_IF -p tcp -m tcp --dport 3389 -j ACCEPT

# Drop everything else
ip6tables -A FORWARD -i $WAN_IF -j DROP

#allow everything to our router/server.
ip6tables -A INPUT -s 0/0 -d 2001:470:81e5::1/128 -j ACCEPT

# Drop everything else
ip6tables -A INPUT -i $WAN_IF -j DROP

In a few places, I only allow packets from 2000::/3. Currently this encompasses all of the global IPv6 addresses, so I could have easily used 0/0 (equivalent to ::/0 or “anywhere”) but I’m okay with being a little more specific here. In fact, for some of them (like ssh and remote desktop) I should be even more specific, but this is a start.

Ensure you can test your rules before leaving them on. I had some rules ordered incorrectly (I tried adding some rules after the “Drop everything else” rule for the chain) and broke www to for a while. (oops!). To verify www, dns and smtp on my server, I used to test these rules.