Skip to content

Instantly share code, notes, and snippets.

@smoser
Last active March 17, 2016 00:03
Show Gist options
  • Save smoser/8447726 to your computer and use it in GitHub Desktop.
Save smoser/8447726 to your computer and use it in GitHub Desktop.
script for dd-wrt to set up ipv6 using tunnelbroker.net. Originally found at http://www.dd-wrt.com/wiki/index.php/IPv6_setup_Hurricane_Electric_Tunnel_Broker
## basic connection settings
# to get these values, visit https://ipv4.tunnelbroker.net/
# from the 'Tunnel Details' page
SERVER_IPV4_ADDR="enter ip here"
CLIENT_IPV6_ADDR="enter ip here"
ROUTED_64_ADDR="enter ip here"
## http://ipv4.tunnelbroker.net account settings
## These are only necessary to auto-update the the ipv4 address.
## If you have a static-ish address, you do not need to set them.
# USERID: This is a long random string (~25 chars seen as 'User ID' on main page)
# PASSWD: plain text password you would use to log in.
# TUNNELID: numeric tunnel id 'Tunnel ID: XXXXXXX' on 'Tunnel Details' page.
USERID=""
PASSWD="your plain text password"
TUNNELID="your numeric tunnel id"
# vi: syntax=sh ts=4 noexpandtab
#!/bin/sh
Usage() {
cat <<EOF
${0##*/} mode [options] [arguments]
mode is one of:
update
wanup
setup
EOF
#####Optional/Advanced Settings######
#IPv6 OpenDNS IPv6 Resolver
ENABLE_OPENDNS_IPV6_DNS=1
#HE's endpoint verificiation server ip to add to whitelist
HE_VERIFY_SERVER_IP="66.220.2.74"
#WAN IP Source settings
#Set below to 1 to use internal NVRAM wan address instead of fetching it from a site
USE_NVRAM_WAN_ADDR=1
# This should return your source IP addr when 'curl'd
# other example: http://myip.dnsomatic.com/
WAN_IP_SOURCE_URL="http://ifconfig.me/ip"
#logging settings (set to /dev/null for no logging)
LOG="/tmp/tunnelbroker-ipv6.log"
#Enable this to generate a .wanup script to automatically update local tunnel
#This will not do anything if USERID/PASSWORD are not provided.
ENABLE_WANUP_SCRIPT=1
WANUP_SCRIPT_FILE_PATH="/tmp/etc/config/tunnelUpdate.wanup"
#Generated files paths
CRON_JOB_FILE="/tmp/report.sh"
RADVD_CONFIG="/tmp/radvd.conf"
# increase verbosity (or add '-v' in invocation)
VERBOSITY=1
# stores state in this file.
STATE_D="/tmp/tbstate"
#***************************
#Settings end here
#***************************
log() {
local lvl="$1"
[ "${VERBOSITY:-0}" -gt "$lvl" ] && error "$@"
[ "${VERBOSITY:-0}" -ge "$lvl" ] && echo "$@" >> "$LOG"
}
hashstr() {
#get md5 hash of a string
local tmp=""
tmp=$(echo -n "$1" | md5sum) && [ -n "$tmp" ] &&
[ "${tmp% -}" != "$tmp" ] && _RET="${tmp% -}"
}
assertipv6() {
local psni6="/proc/sys/net/ipv6"
[ -d $psni6 ] && return 0
insmod ipv6 || { error "loading ipv6 failed"; return 1; }
count=0
while sleep .2 && [ ! -d $psni6 ] && count=$(($count+1)); do
[ $count -gt 50 ] && { warn "no $psni6"; break; return 1; }
done
return 0
}
wan_ipv4() {
#get wan ip for our own use
[ -n "$WANIP" ] && { _RET="$WANIP"; return 0; }
local t
if [ "$WAN_IP_MODE" = "nvram" ]; then
log 2 "getting wan ip from nvram"
t=$(nvram get wan_ipaddr) && [ -n "$t" ] && _RET="$t" && return 0
error "failed to get ip from nvram with: nvram get wan_ipaddr"
return 1
else
log 2 "getting wan ip from: $WAN_IP_SOURCE_URL"
t=$(wget $WAN_IP_SOURCE_URL -O - 2>/dev/null) &&
[ -n "$t" ] && _RET="$t" && return 0
error "failed to get wan ip from $WAN_IP_SOURCE_URL"
return 1
fi
}
error() { log 0 "$@"; }
warn() { log 0 "WARN" "$@"; }
fail() { error "$@"; exit 1; }
update() {
local t="" wanip="" md5pwd="" url="" opts=""
[ -n "$PASSWORD" ] || t="$t,PASSWORD"
[ -n "$TUNNELID" ] || t="$t,TUNNELID"
[ -n "$USERID" ] || t="$t,USERID"
[ -n "$HE_VERIFY_SERVER_IP" ] || t="$t,HE_VERIFY_SERVER_IP"
[ -z "${t#,}" ] ||
{ error "update specified, missing required config ($t)"; return 1; }
local pw="$PASSWORD" tid="$TUNNELID" uid="$USERID" verip="$HE_VERIFY_SERVER_IP"
wan_ipv4 || return 1
wanip="$_RET"
hashstr "$pw" && md5pwd="$_RET" ||
{ error "failed to get md5sum of password"; return 1; }
opts="ip=$wanip&pass=$md5pwd&apikey=$uid&tid=$ttid"
url="http://ipv4.tunnelbroker.net/ipv4_end.php"
#update HE endpoint
#need to alllow wan ping or HE will not validate new endpoint
iptables -I INPUT 2 -s "$verip" -p icmp -j ACCEPT
wget -O - "$url?$opts" >"$STATE_D/update.out" 2>&1 || {
error "failed get of $url to update";
cat "${STATE_D}/update.out" 1>&2;
return 1;
}
return 0
}
start() {
local t="" ripv4="" cipv6="" r64addr=""
[ -n "SERVER_IPV4_ADDR" ] || t="$t,SERVER_IPV4_ADDR"
[ -n "CLIENT_IPV6_ADDR" ] || t="$t,CLIENT_IPV6_ADDR"
[ -n "ROUTED_64_ADDR" ] || t="$t,ROUTED_64_ADDR"
[ -z "${t#,}" ] ||
{ error "update specified, missing required config ($t)"; return 1; }
#cut out the "/64" if user typed it in
r64addr=${ROUTED_64_ADDR%/*}
ripv4addr=${SERVER_IPV4_ADDR%/*}
cipv6addr=${CLIENT_IPV6_ADDR%/*}
wan_ipv4 || return 1
wanip="$_RET"
# The following commands are straight from HE's website
ip tunnel add he-ipv6 mode sit remote "$ripv6addr" local "$wanip" ttl 255
ip link set he-ipv6 up
ip addr add "$cipv6addr/64" dev he-ipv6
ip route add ::/0 dev he-ipv6
ip -f inet6 addr
# These commands aren't on HE's website, but they're necessary for the tunnel to work
ip -6 addr add "$ripv6addr/64" dev br0
ip route add 2000::/3 dev he-ipv6
#Enable IPv6 forwarding
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
# make sure to accept proto-41
iptables -I INPUT 2 -p ipv6 -i vlan1 -j ACCEPT
#make sure to not NAT proto-41
iptables -t nat -A POSTROUTING --proto ! 41 -o eth0 -j MASQUERADE
echo "creating radvd conf" >> $STARTUP_SCRIPT_LOG_FILE
if [ "$ENABLE_OPENDNS_IPV6_DNS" -eq 1 ]; then
log 1 "enabled opendns ipv6 per ENABLE_OPENDNS_IPV6_DNS=$ENABLE_OPENDNS_IPV6_DNS"
echo "nameserver 2620:0:ccc::2" >> /tmp/resolv.dnsmasq
echo "nameserver 2620:0:ccd::2" >> /tmp/resolv.dnsmasq
fi
}
main() {
local out="" short="hc:v" long="help,config:,verbose"
out=$(getopt --name "${0##*/}" \
--options "${short_opts}" --long "${long_opts}" -- "$@") &&
eval set -- "${getopt_out}" ||
{ bad_Usage; return; }
local config="${0%/*}/config"
while [ $# -ne 0 ]; do
cur="$1"; next="$2";
case "$cur" in
-h|--help) Usage ; exit 0;;
-c|--config) output=$next; shift;;
-v|--verbose) VERBOSITY=$((${VERBOSITY}+1));;
--) shift; break;;
esac
shift;
done
[ $# -eq 0 ] && { error "expected 'mode' argument"; return 1; }
mode="$1"
shift;
[ -f "$config" ] ||
{ error "$config: not a file. specify --config"; return 1; }
case "$mode" in
update) update "$@";;
start) start "$@";;
*) return 1;;
esac
log 1 "$(date -R):" "starting" "$@"
assertipv6
if [ "$mode"
if [ -n "$PASSWD" ]; then
hashstr "$PASSWD" && MD5PASSWD="$_RET" ||
fail "failed to has password"
fi
}
mode="$1"
if [ "$mode" = "update" ]; then
:
else
:
fi
assertipv6 || fail "failed to load ipv6"
if [ -n "$PASSWD" ]; then
hashstr "$PASSWD" && MD5PASSWD="$_RET" ||
fail "failed to has password"
fi
#cut out the "/64" if user typed it in
ROUTED_64_ADDR=${ROUTED_64_ADDR%/*}
SERVER_IPV4_ADDR=${SERVER_IPV4_ADDR%/*}
CLIENT_IPV6_ADDR=${CLIENT_IPV6_ADDR%/*}
log 1 "wan_ip: $WANIP"
[ -n "$WANIP" ] || fail "WANIP '$WANIP' invalid"
# The following commands are straight from HE's website
ip tunnel add he-ipv6 mode sit remote $SERVER_IPV4_ADDR local $WANIP ttl 255
ip link set he-ipv6 up
ip addr add $CLIENT_IPV6_ADDR/64 dev he-ipv6
ip route add ::/0 dev he-ipv6
ip -f inet6 addr
TEMP_ADDR=`echo $ROUTED_64_ADDR'1'`
# These commands aren't on HE's website, but they're necessary for the tunnel to work
ip -6 addr add $TEMP_ADDR/64 dev br0
ip route add 2000::/3 dev he-ipv6
#Enable IPv6 forwarding
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
# make sure to accept proto-41
iptables -I INPUT 2 -p ipv6 -i vlan1 -j ACCEPT
#make sure to not NAT proto-41
iptables -t nat -A POSTROUTING --proto ! 41 -o eth0 -j MASQUERADE
echo "creating radvd conf" >> $STARTUP_SCRIPT_LOG_FILE
if [ $ENABLE_OPENDNS_IPV6_DNS -eq 1 ]
then
echo "Open DNS ipv6 enabled" >> $STARTUP_SCRIPT_LOG_FILE
echo "nameserver 2620:0:ccc::2" >> /tmp/resolv.dnsmasq
echo "nameserver 2620:0:ccd::2" >> /tmp/resolv.dnsmasq
fi
#generate wanup script
if [ $ENABLE_WANUP_SCRIPT -eq 1 ]; then
log 2 "WANUP script being generated"
sdir="${WANUP_SCRIPT_FILE_PATH%/*}"
[ -d "$sdir" || mkdir -p "$sdir" ||
fail "failed to make dir for wanup script"
cat > "$STARTUP_SCRIPT_LOG_FILE" <<EOF
echo "WANUP script triggered on \$(date)"
if [ $USE_NVRAM_WAN_ADDR_INSTEAD -eq 1 ]; then
EOF
echo 'echo "WANUP script triggered on `date`" >>' $STARTUP_SCRIPT_LOG_FILE > $WANUP_SCRIPT_FILE_PATH
if [ $USE_NVRAM_WAN_ADDR_INSTEAD -eq 1 ]
then
echo -e 'WANIP=$(nvram get wan_ipaddr);' >> $WANUP_SCRIPT_FILE_PATH
else
echo -e 'WANIP=`wget $WAN_IP_SOURCE_ADDR -O - 2>/dev/null`' >> $WANUP_SCRIPT_FILE_PATH
fi
echo -e wget -q 'http://ipv4.tunnelbroker.net/ipv4_end.php?ip=$WANIP'"&pass=$MD5PASSWD&apikey=$USERID&tid=$TUNNELID" >> $WANUP_SCRIPT_FILE_PATH
echo 'ip tunnel change he-ipv6 local $WANIP'>> $WANUP_SCRIPT_FILE_PATH
chmod +x $WANUP_SCRIPT_FILE_PATH
fi
#creating radvd.conf
cat > "$RADVD_CONFIG" <<EOF
#generated by startup script
interface br0 {
AdvSendAdvert on;
prefix $ROUTED_64_ADDR/64 {
AdvOnLink on;
AdvAutonomous on;
AdvRouterAddr on;
r };
};
EOF
echo "starting radvd" >> $STARTUP_SCRIPT_LOG_FILE
radvd -C $RADVD_CONFIG &
# vi: syntax=sh ts=4 noexpandtab
@phipac
Copy link

phipac commented Apr 2, 2015

Hmmm... In what directory would you save config.sh so the script knows where to look? I can't seem to find the reference in the main script. Thanks for your help!

@UrbanPotato
Copy link

can't seem to make this work running the script throws "line 206: syntax error: unexpected "}" (expecting "then")" I tried sed'ing it but I can't seem to make it work what I am I missing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment