Last active
November 1, 2020 20:28
-
-
Save kangtastic/0e657c1318684785ec9d782de557f9d9 to your computer and use it in GitHub Desktop.
AT&T 6rd script for Linux routers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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