Ephemeral IPv6 server addresses

stupid internet tricks

The frippery.org website is hosted by Mythic Beasts. As well as their hosting service I also have one of their IPv6-only VPS Lite virtual private servers. I got it because it seemed like a fun idea to play with a server that knew nothing about the boring old IPv4 internet. And it was cheap.

The VPS comes with a piffling little /96 range of addresses: a mere 4 billion for a single server. So I gave the machine one static address at the bottom of the range and then, just to show that I could, gave it another one. Ho hum. What to do with the other 4 billion?

That's when I had a flash of inspiration: give the server a temporary IPv6 address that changes every hour. This could be used to hide an SSH server from password guessing bots or a web server from nosy people and search engines.

RFC 4941 defines a way to generate IPv6 addresses that change from time to time, but they're intended as a privacy measure on client machines. These addresses are random and only the client knows what they are. They're also tied in to stateless address autoconfiguration, which my VPS doesn't use.

Obviously a server is only useful if clients can connect to it and to do that they need to know its IP address. So either the server needs to advertise its address or there needs to be a way to work it out.

Enter RFC 6238: TOTP: time-based one-time password algorithm. This defines a way to generate single-use passwords by combining a shared secret with the current time and running a cryptographic hash algorithm on the result. Exactly the same technique can be used to generate IP addresses. Something like this:

   #!/bin/sh

   # display the current time-based IPv6 address

   now=`date +%s`
   approx_now=`expr $now - $now % 3600`

   secret="Slartibartfast"
   prefix="2001:db8:1:2:3:4"

   suffix1="dead"
   suffix2="beef"
   for salt in "Arthur" "Trillian" "Zaphod"
   do
      message="${secret}${approx_now}${salt}"
      sum=`echo "$message" | md5sum`
   
      # reserve a /124 for static addresses
      somesum=`echo "$sum" | cut -c1-7`
      if [ "$somesum" != "0000000" ]
      then
         suffix1=`echo "$sum" | cut -c1-4`
         suffix2=`echo "$sum" | cut -c5-8`
         break
      fi
   done
   echo "${prefix}:${suffix1}:${suffix2}"

The above script (also available here: ephemeral.client) can be used on a client machine to work out the current IP address of the server. The address changes every hour. A similar script on the server (ephemeral.server) calculates the same address and adds it to a network interface with a lifetime of two hours. If the server script is run as a cron job just before the hour the new address will be configured before any clients try to use it. It doesn't do any harm to run the script at other times too: putting a call in /etc/rc.d/rc.local might be a good idea. Old addresses expire automatically at the end of their lifetime.

You can also use a CGI script to issue a redirect request to the itinerant server. frippery.org uses this to implement a mirror that's only available via an ephemeral IPv6 address.

A couple of things about the redirection:

Of course, if you know about one-time passwords the idea of using a similar approach to generate IP addresses is fairly obvious. The earliest reference I could find was in a paper by Prof. Renzo Davoli at FOSDEM 2012 (at 13:28 in the linked video). A more formal paper was presented at ICSNC 2013 (pdf).

For more ideas see Part 2.


Ron Yorston
28th July 2015 (updated 8th September 2015)