Sunday, June 19, 2011

IPv6 6to4 Tunnel using Linux

I have created for my self a script that allow me to create a 6to4 tunnel in one command, I would like to share with you the results:
#!/bin/bash
# 
# Shiran  Guez CCIE 20572
# 
# Create a 6to4 IPv6 tunnel, allow an easy step into the IPv6 world
#  
# should run the script with root or sudo
# curl is needed for External IP address retrive 
# 
# GENERAL Note :
#
# The below is an example of a tcpdump output from the test performed by this script, you can see that first we generate an IPv6 packet that is translated and sent to the anycast and answer is recived back from anycast address.
#12:13:29.215403 IP6 (hlim 64, next-header ICMPv6 (58) payload length: 64) 2002:5744:2e00::1 > 2a00:1450:400c:c01::69: [icmp6 sum ok] ICMP6, echo request, length 64, seq 1
#12:13:29.215417 IP (tos 0x0, ttl 200, id 0, offset 0, flags [DF], proto IPv6 (41), length 124)
#    10.0.0.4 > 192.88.99.1: IP6 (hlim 64, next-header ICMPv6 (58) payload length: 64) 2002:5744:2e00::1 > 2a00:1450:400c:c01::69: [icmp6 sum ok] ICMP6, echo request, length 64, seq 1
#12:13:29.583505 IP (tos 0x80, ttl 245, id 0, offset 0, flags [DF], proto IPv6 (41), length 124)
#    192.88.99.1 > 10.0.0.4: IP6 (class 0x80, hlim 55, next-header ICMPv6 (58) payload length: 64) 2a00:1450:400c:c01::69 > 2002:5744:2e00::1: [icmp6 sum ok] ICMP6, echo reply, length 64, seq 1
#12:13:29.583505 IP6 (class 0x80, hlim 55, next-header ICMPv6 (58) payload length: 64) 2a00:1450:400c:c01::69 > 2002:5744:2e00::1: [icmp6 sum ok] ICMP6, echo reply, length 64, seq 1
#
#
_START_6TO4_ () {
                LOCAL_IP_ADDR=`ifconfig | grep "inet " | grep -v "127.0." | awk -F : '{print $2}' | awk '{print $1}'`
                EXTEN_IP_ADDR=`curl corz.org/ip`
                ARRR_6TO4_IPV6=$(printf "2002:%02x%02x:%02x%02x::1" $(echo $EXTEN_IP_ADDR | tr "." " "))
                NETWORK_PREFIX=$(printf "2002:%02x%02x:%02x%02x:1::/64" $(echo $EXTEN_IP_ADDR | tr "." " "))
                ETH0_IPV6=$(printf "2002:%02x%02x:%02x%02x:1::1/64" $(echo $EXTEN_IP_ADDR | tr "." " "))
                #               
                # Create the tunnel
                ip tunnel add tun6to4 mode sit ttl 200 remote any local $LOCAL_IP_ADDR
                ip link set dev tun6to4 up
                ip -6 addr add $ARRR_6TO4_IPV6/48 dev tun6to4
                ip -6 addr add $ETH0_IPV6 dev eth0
                ip -4 addr add $EXTEN_IP_ADDR dev tun6to4
                #Comment:        RFC 3068 
                #Comment:        http://www.rfc-editor.org/rfc/rfc3068.txt
                #Comment:        This block is used by the multiple, separately operated networks 
                #Comment:        and often originates from many different Autonomous Systems.
                #Comment:        The below add a route redirecting the outgoing traffic to the anycast address.
                ip -6 route add 2000::/3 via ::192.88.99.1 dev tun6to4 metric 1
                ip -6 route add $NETWORK_PREFIX dev eth0 metric 1
                # Display and test results
                _SHOW_
}
_STOP_ALL_ () {
        ip -6 route flush dev tun6to4
        ip -6 route flush scope global
        ip -6 addr flush scope global
        ip link set dev tun6to4 down
        ip tunnel del tun6to4
}
_REFRESH_TUNNEL_ () {
                _STOP_ALL_
                _START_6TO4_
}
_SHOW_ () {
        echo " =============== 6to4 Dynamic Tunnel ===================="
        echo " ETH0 IPV6 ADDR : $(echo "`ip -6 addr | grep -A 2 eth0 | grep inet6 | awk '{print $2}'`")"
        echo " TUNNEL IPV6 ADDR : $(echo "`ip -6 addr | grep -A 2 tun6to4 | grep inet6 | awk '{print $2}'`")"
        echo " Testing Connectivity please wait..."
        # TEST IS PERFORMED TO ONE OF GOOGLE.COM IPV6 ADDR 2a00:1450:400c:c01::69
        echo " TEST RESULT : $(ping6 -c 1 2a00:1450:400c:c01::69 > /dev/null && echo "SUCCESS" || echo "FAILED TO CONNECT" ;)"
}
case "$1" in
  start)
        _START_6TO4_
    ;;
  stop)
        _STOP_ALL_
   ;;
  show)
        _SHOW_
    ;;
  refresh)
        _REFRESH_TUNNEL_
        ;;
  *)
    echo "Usage: tunnel6 {start|stop|refresh|show}"
    exit 1
    ;;
esac
exit 0