SixXS with Heartbeat Script for Dynamic IPv4 Connections



  • This may be of use for some of you who are running pfSense and tunneling IPv6 over IPv4 using SixXS who are unlucky enough not to have a static IPv4 available to them (like me).

    My address is assigned dynamically via PPPoE, with no ability to obtain a static, so I've been looking for a way to have AICCU or HeartBeat setup for some time now, but with no success.

    I recently came across a script for the EdgeRouter, written in Python, that talks to the SixXS Heartbeat service, so I've given it a go on my pfSense 2.2.1 installation, and can report back that this works great for me!

    The original script was found here:
    http://community.ubnt.com/t5/EdgeMAX/SIXXS-connectivity-without-AICCU-with-minimum-system/td-p/550538

    This led me to also find another script, that uses netcat and md5sum to perform the same thing, from the author the above script was based on.  I also got this to work as well, natively in pfSense, without having to install Python.

    The original shell script can be found here:
    https://www.sixxs.net/archive/sixxs/heartbeat/heartbeat.sh

    So, below is how I got both to work - you can choose whichever method you want, I'm running the Python version since that is what I got to work first, and it seemed (on my machine) to execute a lot quicker.

    First up, the shell version, modified slightly to remove the loop and convert BSD commands:

    #! /bin/sh
    # written by Oliver Walter <owb@gmx.de>
    localv6=""
    password=""
    remotev4=""
    remotev6=""
    
    hb="HEARTBEAT TUNNEL `echo -n $localv6|cut -d '/' -f 1` sender `date +%s`"
    echo -n "$hb `echo -n $hb $password|md5|cut -d ' ' -f 1`"|nc -w 1 -u $remotev4 3740
    ping6 -s 8 -c 1 -q $remotev6 >/dev/null 2>&1 &</owb@gmx.de>
    

    And secondly the Python version, just removed the loop around this one:

    #!/usr/local/bin/python
    #
    
    import time,hashlib,subprocess,socket,os
    
    localv6=""
    password=""
    remotev4=""
    remotev6=""
    
    hbBase="HEARTBEAT TUNNEL " + localv6 + " sender " + str(int(time.time()))
    hbToSend=hbBase + " " + hashlib.md5(hbBase + " " + password).hexdigest()
    sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    sock.sendto(hbToSend, (remotev4, 3740))
    sock.close()
    with open(os.devnull, "w") as fnull:
            subprocess.call(["/sbin/ping6", "-s", "8", "-c", "1", "-q", remotev6], stdout=fnull, stderr=fnull)
    

    Only requirement you need, if you intend to use the Python version, is obviously Python, so login via an SSH shell and install that:

    pkg install python python2
    

    Down to the main parts now - firstly go to the SixXS webpage, login and goto "User Home".  Go into the details of your Tunnel, and set the Tunnel Type/Endpoint to "6in4-heartbeat".  Click "Change Tunnel Type" and then when the page reloads, go into your "Live Tunnel Status on the POP" page - this is where we will get the details to enter into the script.

    Back in your SSH shell to the scripts, open for editing, and then enter the details as follows:

    
    script     Live Status Page
    localv6  = Inner Them
    remotev4 = Outer Us
    remotev4 = Inner Us
    password = Heartbeat password
    

    IMPORTANT - the Heartbeat Information section on this page may take a few minutes to show up.  In my case, there was about a 5 minute delay between when I first went to the Live Status page, and it appearing.  It was completely missing when I first visited, so it may take a few refreshes to show up.

    Make sure you have set the script file to be executable (chmod +x) and then run the script.

    If you refresh the status page and it's all working, you should see the "Last Heartbeat" time update and show that its worked.

    Now you have it working, note that the tunnel will drop from the SixXS end if a heartbeat hasn't been received for 5 mins.

    So to fix that, we now need to put an entry into crontab, so still on the SSH shell:

    crontab -e
    

    Fill out your crontab like this (copy and paste the below if you haven't got one setup already):

    SHELL=/bin/sh
    PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin
    # Order of crontab fields
    # minute        hour    mday    month   wday    command
    *               *       *       *       *       /usr/local/bin/python /path/to/script/heartbeat.py
    *               *       *       *       *       /path/to/script/heartbeat.sh
    

    Only enter the line above for the script you are actually using.  Save this out, and then use date to work out when the next minute has ticked over.  Once it has ticked over, go back to the Live Status page and refresh and you should see the timer update.

    The above crontab will run the script every minute, so it has 5 goes before you get disconnected for inactivity.

    I've tested this through reboots and it seems to work pretty well for me, it automatically updates every time I reboot the machine (which forces my PPPoE IPv4 to be dynamically reassigned), and the tunnel is up as soon as I login to the pfSense web interface, so it should work pretty well for others too.


  • Banned

    So, well… here's a couple of suggestions:

    1/ Install the Filer package and use that to upload whatever custom scripts you have (Diagnostics - Filer)
    2/ Install the Cron package and use that to maintain your custom cronjobs (Services = Cron).

    This way, the mods will actually survive upgrades.


Log in to reply