Skip to content

Instantly share code, notes, and snippets.

@kangtastic
Last active November 1, 2020 20:28
Show Gist options
  • Save kangtastic/0e657c1318684785ec9d782de557f9d9 to your computer and use it in GitHub Desktop.
Save kangtastic/0e657c1318684785ec9d782de557f9d9 to your computer and use it in GitHub Desktop.
AT&T 6rd script for Linux routers
#!/bin/bash
# Create a 6rd tunnel on a Linux router using AT&T U-Verse Fiber/DSL.
#
# Only creates a tunnel and sets up a default route. IPv6 connectivity for LAN
# clients requires, at minimum, sending Router Advertisements (with radvd/
# dnsmasq) to the LAN interface and enabling IPv6 forwarding in the kernel.
# IPv6 firewalling with ip6tables is also a very good idea.
#
# Hat tip VictorLowther: https://gist.github.com/VictorLowther/2969270
#
# Usage: att6rd.sh IF_LAN IF_TUNNEL [MTU]
# att6rd.sh -h|--help|-?
#
# -h|--help|-? print this help message
# IF_LAN: device name of the LAN-facing interface
# must be a real interface on the system
# IF_TUNNEL: device name of 6in4 tunnel to be created
# [MTU]: MTU of tunnel; default and maximum is 1480 for fiber
# should be 1472 for DSL (PPP), minimum 1280
#
# Run as root once IPv4 connectivity is established.
#
# Example: Script saved as /etc/network/att6rd.sh, am using dhclient as the DHCP
# client on the WAN interface, dhclient-exit-hooks.d/ on system is at
# /etc/dhcp/dhclient-exit-hooks.d/, want 6in4 to be tunnel name, want
# script to run whenever WAN interface gets an IPv4 address.
#
# Save this stub as /etc/dhcp/dhclient-exit-hooks.d/att6rd:
#
# [ "$interface" = "<WAN interface>" ] || return 0
# case "$reason" in
# BOUND|RENEW|REBIND|REBOOT|TIMEOUT)
# /etc/network/att6rd.sh <LAN interface> 6in4
# ;;
# esac
#
# Then, chmod +x both att6rd and att6rd.sh. Done.
# bashisms ho
is_netif() { compgen -G /sys/class/net/$1 >/dev/null; return $?; }
die()
{
echo "$@" >&2
echo "Usage: $0 IF_LAN IF_TUNNEL [MTU]
$0 -h|--help|-?
-h|--help|-?: print this help message
IF_LAN: device name of the LAN-facing interface
must be a real interface on the system
IF_TUNNEL: device name of 6in4 tunnel to be created
[MTU]: MTU of tunnel; defaults to 1480 for fiber
should be 1472 for DSL (PPP), minimum 1280
" >&2
exit 1
}
([ "$1" = "-h" ] || [ "$1" = "--help" ] || [ "$1" = "-?" ]) && die
[ $# -lt 2 ] && die "too few arguments"
[ $# -gt 3 ] && die "too many arguments"
is_netif $1 || die "\"$1\" isn't a network interface"
if [ $# = 3 ]; then
[ $3 -eq $3 ] 2>/dev/null && # integer type check
[ $3 -gt 1279 ] && [ $3 -lt 1481 ] || # mtu range check
die "invalid MTU \"$3\" (IPv6 minimum 1280, Ethernet maximum 1480)"
fi
[ $EUID -ne 0 ] && die "not running as root"
# Device name of LAN-facing interface
# Device name of virtual 6in4 tunnel interface to be created
# Tunnel MTU: Ethernet frame size (1500 bytes) - IPv4 header size (20 bytes)
LAN=$1
TUN=$2
[ $# = 3 ] && MTU=$3 || MTU=1480
# IPv4 local endpoint: our public address on the WAN-facing interface
# IPv4 remote endpoint: anycast address to closest endpoint on AT&T's network
V4L=$(curl -s api.ipify.org)
V4R=12.83.49.81
# 6rd local prefix: a /60 calculated from AT&T's 6rd prefix of 2602:300::/28
# IPv6 local endpoint: will be bound to _LAN-facing interface_, not WAN
# IPv6 remote endpoint: will be bound to tunnel interface
V6PFX=$(echo $V4L | awk -F. '{ t=sprintf("%02x%02x%02x%02x", $1, $2, $3, $4);
print "2602:30"substr(t,1,1)":"substr(t,2,4)":"substr(t,6)"0" }')
V6L=$V6PFX::1/60
V6R=$V6PFX::2/28
# Insert sit module into kernel if it isn't present
grep -q '^sit' /proc/modules || modprobe sit
# Get rid of $LAN's global IPv6 address and the default IPv6 route
ip -6 addr flush dev $LAN scope global
ip -6 route flush ::/0
# Destroy tunnel if it exists already
if is_netif $TUN; then
ip link set $TUN down
ip -6 route flush dev $TUN
ip tunnel del $TUN
fi
# Create tunnel and add back the default IPv6 route
ip tunnel add $TUN mode sit remote $V4R local $V4L ttl 255
ip link set $TUN up
ip link set mtu $MTU dev $TUN
ip addr add $V6L dev $LAN
ip addr add $V6R dev $TUN
ip -6 route add ::/0 dev $TUN
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment