weblog d’un abbe

20080901

Setup IPv6 tunnels from Hurricane Electric

Filed under: Free OS, Fun, Hacking — Tags: , , , — abbe @ 1259

The tunnel setup script:

#!/bin/sh
# Author: Ashish Shukla <gmail.com!wahjava>
# Description: Creates and initializes an IPv6 tunnel from the parameters given in
#              the file name stored in $TUNNEL_CONFIG variable
# License: BSD License
# OS: FreeBSD, GNU/Linux
# Tested on: FreeBSD 7.0-RELEASE-p3
#            Gentoo GNU/Linux 2008.0
# TODO: Port the script to other POSIX compliant OSs
#
# Copyright 2008. Ashish Shukla
#
# CREDITS: Martin J. Levy at HE.net, for the motivation.

OS=$(uname)
WHICH=/usr/bin/which
SCRIPT_NAME=`basename $0`

# The place where tunnel configuration file is stored
TUNNEL_CONFIG=${HOME}/.tunnelconfig

[ -f ${TUNNEL_CONFIG} ] && . ${TUNNEL_CONFIG}

FindLocalEndpoint() {
	if [ ${OS} = Linux ]; then
		if [ ! -z "${IP}" ] ; then
			INET_LOCAL_ENDPOINT=`${IP} addr show |awk "/^[[:space:]]*inet .*global ${IFACE}\$/ { print \\$2 }" |sed -e 's|/[[:digit:]]*||g'`
		elif [ ! -z "${IFCONFIG}" ]; then
			INET_LOCAL_ENDPOINT=`${IFCONFIG} ${IFACE} |awk "/^[[:space:]]*inet / { print \\$2 }" |sed -e 's|addr:||g'`
		fi
	elif [ ${OS} = FreeBSD ]; then
		INET_LOCAL_ENDPOINT=`${IFCONFIG} ${IFACE} |awk '/^[[:space:]]*inet / { print $2 }'`
	fi
}

IsValidExecutable() {
	if [ -z "$1" ] || [ ! -f "$1" ] || [ ! -x "$1" ] ; then
		echo "Error: $2 is not installed or is not executable."
		exit 1
	fi
}

IsValidExecutable "${WHICH}" "which"

if [ ! -z "${PREFER_SUDO}" ]; then
	[ -z "${SUDO}" ] && SUDO=$(${WHICH} sudo 2>/dev/null)
	IsValidExecutable "${SUDO}" "sudo"

	if ! ${SUDO} echo sudo verified ; then
		echo Error: Unable to verify sudo
		exit 1
	fi
	WHICH="${SUDO} ${WHICH}"
fi

[ -z "${WGET}" ] && WGET=$(${WHICH} wget 2>/dev/null)
[ -z "${AWK}" ] && AWK=$(${WHICH} awk 2>/dev/null)
[ -z "${SED}" ] && SED=$(${WHICH} sed 2>/dev/null)
[ -z "${RM}" ] && RM=$(${WHICH} rm 2>/dev/null)

# Check for the Required executables
IsValidExecutable "${WGET}" "GNU wget"
IsValidExecutable "${SED}" "sed"
IsValidExecutable "${AWK}" "awk"
IsValidExecutable "${RM}" "rm"

# echo GNU wget is installed at ${WGET}

if [ $OS = Linux ]; then

	[ -z "${IP}" ] && IP="$(${WHICH} ip 2>/dev/null)"
	[ -z "${IFCONFIG}" ] && IFCONFIG="$(${WHICH} ifconfig 2>/dev/null)"
	[ -z "${ROUTE}" ] && ROUTE="$(${WHICH} route 2>/dev/null)"

	if [ ! -z ${IP} ]; then
		IsValidExecutable ${IP} "iproute2"

		[ ! -z "${PREFER_SUDO}" ] && IP="${SUDO} ${IP}"
#		echo iproute2 is available at ${IP}

		[ ! -z "${INET_LOCAL_ENDPOINT} " ] && FindLocalEndpoint

#		echo Local Endpoint is ${INET_LOCAL_ENDPOINT}.
#		echo inet6 remote endpoint is ${INET6_REMOTE_ENDPOINT}
#		echo inet6 local endpoint is ${INET6_LOCAL_ENDPOINT}

#		echo ${IP} tunnel add ${TUNNEL_IFACE} mode sit remote ${INET_REMOTE_ENDPOINT} local ${INET_LOCAL_ENDPOINT} ttl 255
		${IP} tunnel add ${TUNNEL_IFACE} mode sit remote ${INET_REMOTE_ENDPOINT} local ${INET_LOCAL_ENDPOINT} ttl 255
#		echo ${IP} link set ${TUNNEL_IFACE} up
		${IP} link set ${TUNNEL_IFACE} up
#		echo ${IP} addr add ${INET6_LOCAL_ENDPOINT} dev ${TUNNEL_IFACE}
		${IP} addr add ${INET6_LOCAL_ENDPOINT} dev ${TUNNEL_IFACE}
#		echo ${IP} route add ::/0 dev ${TUNNEL_IFACE}
		${IP} route add ::/0 dev ${TUNNEL_IFACE}
#		echo ${IP} route add ${INET_REMOTE_ENDPOINT} dev ${IFACE}		
		${IP} route add ${INET_REMOTE_ENDPOINT} dev ${IFACE}		

	elif ! [ -z "$(${WHICH} ifconfig 2>/dev/null)" ]; then

		IsValidExecutable ${IFCONFIG} "ifconfig"
		IsValidExecutable "${ROUTE}" "route"
	
		[ ! -z "${PREFER_SUDO}" ] && IFCONFIG="${SUDO} ${IFCONFIG}" && ROUTE="${SUDO} ${ROUTE}"
#		echo ifconfig is available at ${IFCONFIG}

		[ ! -z "${INET_LOCAL_ENDPOINT} " ] && FindLocalEndpoint

#		echo ${IFCONFIG} ${TUNNEL_IFACE} up add ${INET6_LOCAL_ENDPOINT}
		${IFCONFIG} ${TUNNEL_IFACE} up add ${INET6_LOCAL_ENDPOINT}
#		echo ${ROUTE} -A inet6 del ${INET6_REMOTE_ENDPOINT/::1/::} dev ${TUNNEL_IFACE}
		${ROUTE} -A inet6 del ${INET6_REMOTE_ENDPOINT/::1/::} dev ${TUNNEL_IFACE}
#		echo ${ROUTE} -A inet6 add ${INET6_REMOTE_ENDPOINT/::1/::} gw ::${INET_REMOTE_ENDPOINT} dev ${TUNNEL_IFACE}
		${ROUTE} -A inet6 add ${INET6_REMOTE_ENDPOINT/::1/::} gw ::${INET_REMOTE_ENDPOINT} dev ${TUNNEL_IFACE}
#		echo ${ROUTE} -A inet6 add default gw ::${INET_REMOTE_ENDPOINT} dev ${TUNNEL_IFACE}
		${ROUTE} -A inet6 add default gw ::${INET_REMOTE_ENDPOINT} dev ${TUNNEL_IFACE}
#		echo ${ROUTE} add ${INET_REMOTE_ENDPOINT} dev ${IFACE}
		${ROUTE} add ${INET_REMOTE_ENDPOINT} dev ${IFACE}
	else
		echo Neither ifconfig nor ip executables are found at PATH
		echo Please make sure, that one of them is installed and present
		echo in PATH somewhere.
		echo PATH: ${PATH}
	fi
elif [ $OS = FreeBSD ]; then
	[ -z "${IFCONFIG}" ] && IFCONFIG="$(${WHICH} ifconfig 2>/dev/null)"
	[ -z "${ROUTE}" ] && ROUTE="$(${WHICH} route 2>/dev/null)"

	[ ! -z "${PREFER_SUDO}" ] && IFCONFIG="${SUDO} ${IFCONFIG}" && ROUTE="${SUDO} ${ROUTE}"
	[ ! -z "${INET_LOCAL_ENDPOINT} " ] && FindLocalEndpoint

	${IFCONFIG} ${TUNNEL_IFACE} create
	${IFCONFIG} ${TUNNEL_IFACE} tunnel ${INET_LOCAL_ENDPOINT} ${INET_REMOTE_ENDPOINT}
	${IFCONFIG} ${TUNNEL_IFACE} inet6 ${INET6_LOCAL_ENDPOINT}
	${ROUTE} -n add -inet6 default ${INET6_REMOTE_ENDPOINT%%/64}
	${IFCONFIG} ${TUNNEL_IFACE} up
else
	echo This script is not yet ported to ${OS}.
	echo You can help to port it to your ${OS}.
fi

TMPFILE=`mktemp -q -t ${SCRIPT_NAME}.XXXXX`

${WGET} -O /dev/null --keep-session-cookies "--post-data=f_user=${USER}&f_pass=${PASSWORD}&clearpass=" --save-cookies=${TMPFILE} http://ipv4.tunnelbroker.net/login.php 2>/dev/null
${WGET} -O /dev/null --load-cookies=${TMPFILE} "--post-data=ipv4b=${INET_LOCAL_ENDPOINT}&tunnel_id=${TUNNEL_ID}&update=Submit" http://ipv4.tunnelbroker.net/ipv4_update.php 2>/dev/null
${RM} -f ${TMPFILE}

exit 0

Following is the tunnel configuration file, which is stored in my home directory at $HOME/.tunnelconfig:

# Interface
IFACE=ng0

# User
USER=xxxxxxxx

# MD5 hash of the password
# GNU/Linux: printf ${password} |md5sum |awk '{ print $1 }'
# FreeBSD: md5 -q -s ${password}
PASSWORD=xxxxxxxxxxxxxxxxxxxx

# Global Tunnel ID as mentioned in the tunnel configuration webpage
TUNNEL_ID=00000

# Define it, if executing priviledged actions via sudo. RECOMMENDED.
PREFER_SUDO=1

# In case of GNU/Linux,
# if using ifconfig: 6in4 tunnel name start with sit, e.g. sit0
# if using iproute2: 6in4 tunnel name can be any 3 or more letters name, not starting with sit, e.g. he-tunnel
# whereas in FreeBSD, the name starts with gif, .e.g. gif0
TUNNEL_IFACE=gif0

# IPv4 Remote endpoint
INET_REMOTE_ENDPOINT=127.0.0.1

# IPv6 Remote endpoint
INET6_REMOTE_ENDPOINT=2001:db8:xxxx::1/64

# IPv6 Local endpoint
INET6_LOCAL_ENDPOINT=2001:db8:xxxx::2/64

# Define it if you don't want local IPv4 local endpoint to be detected at runtime.
# INET_LOCAL_ENDPOINT=

To use this script, download it and save it as setup-he.sh in your home directory, make it executable, create a tunnel configuration file at $HOME/.tunnelconfig similar to the one shown above, and then finally execute the script on terminal. Happy IPv6ing…:)

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: