Jan 092014
 

I don’t yet have IPv6 native at home. Perhaps Verizon FiOS will provide it soon. In the meantime, I make use of Hurricane Electric, which seems to be everyone’s go-to ISP for tunnels.

This post isn’t about creating an IPv6 tunnel. It’s about making sure that tunnel is rebuilt after you have an IP address change. At home, my Verizon FiOS connection has a dynamic IP address. It changes from time to time, and without warning. This happened a few days ago, overnight.

HE support

The HE FAQ show what to do if your IPv4 endpoint address is dynamic. When I wrote this, the FAQ pointed you at this HE Forum post.

DHCP hooks

It was this post on FreeBSD Forums which pointed me towards using /etc/dhclient-exit-hooks, which contains this:

$ cat  /etc/dhclient-exit-hooks
#!/bin/sh

logger -t dyndns /etc/dhclient-exit-hooks has been invoked

logger -t dyndns "'$reason' '$interface' '$medium' '$new_ip_address' '$old_ip_address'"

if [ "${old_ip_address}" = "" ]
then
    if [ -e /var/tmp/currentIP ]
    then
        old_ip_address=`/bin/cat /var/tmp/currentIP`
    fi
fi

if [ "$new_ip_address" = "" ] ; then
    new_ip_address=`/sbin/ifconfig fxp0 | /usr/bin/sed -n '/.inet /{s///;s/ .*//;p;}'`
    logger -t dyndns "new IP from ifconfig is ${new_ip_address}"
else
    logger -t dyndns "new IP from dhclient is ${new_ip_address}"
fi

if [ "${new_ip_address}" = "" -o "${new_ip_address}" = "${old_ip_address}" ] ; then
    echo "nochg ${old_ip_address}"
    logger -t dyndns "Ooops, IP has not actually changed from ${old_ip_address}"
else
    /usr/local/bin/curl -v --netrc "https://ipv4.tunnelbroker.net/nic/update?hostname=XXXXX"
    ifconfig gif0 down
    ifconfig gif0 delete
    route delete -inet6 default -interface gif0
    
    ifconfig gif0 tunnel ${new_ip_address} 209.51.161.14
    ifconfig gif0 inet6 2001:470:1f06:9ea::2 2001:470:1f06:9ea::1 prefixlen 128
    route -n add -inet6 default 2001:470:1f06:9ea::1
    ifconfig gif0 up

    echo "${new_ip_address}" > /var/tmp/currentIP
    logger -t dyndns "updated from ${old_ip_address} to ${new_ip_address}"
    
fi

logger -t dyndns "all done here"

You will see a curl above. That call will use the contents of /root/.netrc, which contains:

machine ipv4.tunnelbroker.net login MYLOGIN       password MYPASSWORD

That curl request contains a hostname paramter. This is your tunnel id, which you can get from https://www.tunnelbroker.net/. Login, and click on the tunnel in question. Under Tunnel Details, you will see Tunnel ID:. That is the value you want.

So what happens here?

This is what happens when you manually invoke that curl command. I did this back in October, when I started writing this post.

# /usr/local/bin/curl -v --netrc "https://ipv4.tunnelbroker.net/nic/update?hostname=MYTUNNELID"
* Adding handle: conn: 0x801c62600
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x801c62600) send_pipe: 1, recv_pipe: 0
* About to connect() to ipv4.tunnelbroker.net port 443 (#0)
*   Trying 64.62.200.2...
* Connected to ipv4.tunnelbroker.net (64.62.200.2) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: /usr/local/share/certs/ca-root-nss.crt
  CApath: none
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using DHE-RSA-AES256-SHA
* Server certificate:
*        subject: O=tunnelbroker.net; OU=Domain Control Validated; CN=tunnelbroker.net
*        start date: 2011-11-05 00:44:14 GMT
*        expire date: 2016-11-04 21:10:42 GMT
*        subjectAltName: ipv4.tunnelbroker.net matched
*        issuer: C=US; ST=Arizona; L=Scottsdale; O=Starfield Technologies, Inc.; OU=http://certificates.starfieldtech.com/repository; CN=Starfield Secure Certification Authority; serialNumber=10688435
*        SSL certificate verify ok.
* Server auth using Basic with user 'xxxxxxx'
> GET /nic/update?hostname=xxxxxx HTTP/1.1
> Authorization: Basic ZHZsOnByb2ZsZXg=
> User-Agent: curl/7.31.0
> Host: ipv4.tunnelbroker.net
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 ok
< Date: Wed, 02 Oct 2013 11:48:03 GMT
< Server: Apache/2.2.8 (Ubuntu) DAV/2 SVN/1.4.6 PHP/5.2.4-2ubuntu5.17 with Suhosin-Patch mod_ssl/2.2.8 OpenSSL/0.9.8g
< X-Powered-By: PHP/5.2.4-2ubuntu5.17
< Set-Cookie: referer=Direct+Access
< Content-Length: 20
< Connection: close
< Content-Type: text/html; charset=utf-8
<
good 98.111.147.220
* Closing connection 0
* SSLv3, TLS alert, Client hello (1):
#

After that, to recontruct the tunnel, you need this:

ifconfig gif0 down
ifconfig gif0 delete
route delete -inet6 default -interface gif0

ifconfig gif0 tunnel 98.111.147.220 209.51.161.14
ifconfig gif0 inet6 2001:470:1f06:9ea::2 2001:470:1f06:9ea::1 prefixlen 128
route -n add -inet6 default 2001:470:1f06:9ea::1
ifconfig gif0 up

… where 98.111.147.220 was my new IP address.

All that should happen within the dhclient-exit-hooks script. Or so I thought…

What happened next?

After setting this up, I waited for an IP address change. It took a few months, but it happened a few days ago. Here is what I found in /var/log/messages:

Jan  8 05:14:39 bast ntpd[1808]: sendto(204.2.134.163) (fd=26): No route to host
Jan  8 05:14:40 bast ntpd[1808]: sendto(2001:470:8:104::2) (fd=30): No route to host
Jan  8 05:14:43 bast dyndns: /etc/dhclient-exit-hooks has been invoked
Jan  8 05:14:43 bast dyndns: 'ARPSEND' 'fxp0' '' '' ''
Jan  8 05:14:43 bast dyndns: new IP from ifconfig is 71.185.48.53
Jan  8 05:14:43 bast dyndns: Ooops, IP has not actually changed from 71.185.48.53
Jan  8 05:14:43 bast dyndns: all done here
Jan  8 05:14:45 bast dyndns: /etc/dhclient-exit-hooks has been invoked
Jan  8 05:14:45 bast dyndns: 'ARPCHECK' 'fxp0' '' '' ''
Jan  8 05:14:45 bast dyndns: new IP from ifconfig is 71.185.48.53
Jan  8 05:14:45 bast dyndns: Ooops, IP has not actually changed from 71.185.48.53
Jan  8 05:14:45 bast dyndns: all done here
Jan  8 05:14:46 bast dhclient: New IP Address (fxp0): 108.36.196.71
Jan  8 05:14:46 bast dhclient: New Subnet Mask (fxp0): 255.255.255.0
Jan  8 05:14:46 bast dhclient: New Broadcast Address (fxp0): 108.36.196.255
Jan  8 05:14:46 bast dhclient: New Routers (fxp0): 108.36.196.1
Jan  8 05:14:46 bast dyndns: /etc/dhclient-exit-hooks has been invoked
Jan  8 05:14:46 bast dyndns: 'BOUND' 'fxp0' '' '108.36.196.71' ''
Jan  8 05:14:46 bast dyndns: new IP from dhclient is 108.36.196.71
Jan  8 05:14:46 bast dyndns: updated from 71.185.48.53 to 108.36.196.71
Jan  8 05:14:46 bast dyndns: all done here

You can see that at 05:14:46, the IP address was finally BOUND, and that’s when the BIG part of the script is invoked.

But wait, there’s more

Sadly, I had removed curl from my system a few days before this occurred. I have reinstalled it, and now I’m waiting for the next IP address change.

Website Pin Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google StumbleUpon Premium Responsive

  One Response to “Updating your IPv6 tunnel after an IP address change”

  1. Oh, wait, this won’t work for booting. When you boot, your IP address changes. So this entry in /etc/rc.conf will not work. It needs to be scripted…

    gifconfig_gif0="173.49.195.214 209.51.161.14"
    

    That’s because /etc/rc.conf won’t know what address to use….