These scripts exist so that I can connect and disconnect from third party networks such as 3's UTMS network without worrying that data intended for their network will disappear up the internet pipe instead when disconnecting the mobile phone. We also avoid the idiosyncrasy of having overlapping routes in the routing tables.. I.e. a default route would overlap with everything, incuding localhost and routes back to the LAN.
The routes are made by inverting an Internet bogons list.
Bogons can be obtained from the simpler bogons reference page or the more thorough but more frequently changing bogon IPs. Go for the aggregated CIDR/bit notation format. Beware that sometimes a broken list is published, such as including overlapping prefixes. Inverse detects this and aborts. Then the old route table would be left in place.
This script combines bogons from the Internet URL with your own bogons to produce a list of valid routes. Usage: getroutes <URL> <own bogons file> <file to write routes to>
It requires a program inverse that can be compiled as gcc -o inverse inverse.c
The file <own bogons file> is like this: (Only include entries that are not in the URL file)
010.000.000.000/08 127.000.000.000/08 172.016.000.000/12 192.168.000.000/16 224.000.000.000/04
It is padded as shown so the sort / comm utilities sort the entries correctly. Others can be added to block off certain IP's /32 or networks.
#!/bin/sh
# Copyright Michael John Wensley http://www.wensley.org.uk/
# this example shows how to use inverse to obtain and format a route list
# first parameter is URL of bogons
# second is padded private bogons to drop in textfile, that arent in the bogons file i.e. 192.000.002.000/24
# third is where to save the result
# pad out addresses for correct sortability
function presort () {
IFS=" "
tr -s "./" " " | while read
do case "$REPLY" in
\#*) ;;
*) printf %03u.%03u.%03u.%03u/%03u\\n $REPLY ;;
esac
done
}
# make list of current routes
wget -O - $1 | presort | sort -g - $2 | /usr/local/sbin/inverse | presort > $3
exit $?
This program applies the difference between two files full of routes to the system routing table. Usage: routes <old routes file> <new routes file> [echo]
#!/bin/sh
# Copyright Michael John Wensley http://www.wensley.org.uk/
# this example shows how to use inverse to apply routes
# compress addresses for route
function pack () {
sed -s 's/^0*\(.*[0-9]\)\.0*\(.*[0-9]\)\.0*\(.*[0-9]\)\.0*\(.*[0-9]\)\/0*\(.*[0-9]\)$/\1.\2.\3.\4\/\5/'
}
# generate commands to add or remove routes to match current
IFS="/"
comm -3 "$2" "$3" | cut -s -f2 | pack | while read IP BITS
do
[ -n "$4" ] && echo "+"$IP/$BITS
case $BITS in
0) route add default dev $1 ;;
32) route add -host $IP dev $1 ;;
*) route add -net $IP/$BITS dev $1 ;;
esac
if [ "$?" != "0" ]
then
exit -1
fi
done
comm -3 "$2" "$3" | cut -f1 | cut -s -d"/" -f1-2 | pack | while read IP BITS
do
[ -n "$4" ] && echo "-"$IP/$BITS
case $BITS in
0) route -v del default dev $1 ;;
32) route -v del -host $IP dev $1 ;;
*) route -v del -net $IP/$BITS dev $1 ;;
esac
if [ "$?" != "0" ]
then
exit -1
fi
done
[ -n "$4" ] && echo All done
logger "Routes All Done"
A script can be made to get new routes and apply them to the system in one go. Just change the URL and create the mine-complete file.
#!/bin/sh N=http://localhost/bogons.txt M=/var/local/routes/mine-complete.txt NE=/var/local/routes/new.txt C=/var/local/routes/current.txt O=/var/local/routes/old.txt /usr/local/sbin/getroutes $N $M $NE cp $C $O mv $NE $C /usr/local/sbin/routes w1ad $O $C echo
The sangoma S518 card I have needs to have the routes loaded after it brings up ppp. After having installed hotplug, do
echo WAN_ACTION=\"addroutes\" >> /etc/wanpipe/wanrouter.rc
ln --symbolic /etc/wanpipe/scripts/addroutes /etc/wanpipe/scripts/wanpipe1-addroutes
ln --symbolic /etc/wanpipe/scripts/addroutes /etc/wanpipe/scripts/wanpipe1-w1ad-addroutes
Now /etc/wanpipe/scripts/addroutes is invoked whenever wanpipe brings up the link. e.g. after the line has been re-connected.
#!/bin/sh logger "ADDROUTES ON: $@" /usr/local/sbin/routes w1ad /var/local/routes/null.txt /var/local/routes/current.txt >/dev/null 2>/dev/null & pid=$! disown $pid #wondershaper w1ad 500 100
This script produces a list of domains with IP addresses from an IPv6 squid access log
if [ ! -f /dev/shm/stage1 ]
then
cat /dev/shm/access.log | cut -c23- | cut -d" " -f1,5,7 | \
sed 's/^\([^ ]*\) \([^ ]*\) \([^ ]*\)$/\1 \3 \2/g' | \
cut -d"/" -f1-4 > /dev/shm/stage1
fi
if [ ! -f /dev/shm/stage2 ]
then
uniq /dev/shm/stage1 > /dev/shm/stage2
fi
if [ ! -f /dev/shm/stage3 ]
then
cat /dev/shm/stage2 | sed '
s/^\([^ ]* DIRECT\/::ffff:\)\([0-9]\{1\}\)\(\.\)/\100\2\3/g
s/^\([^ ]* DIRECT\/::ffff:\)\([0-9]\{2\}\)\(\.\)/\10\2\3/g
s/^\([^ ]* DIRECT\/::ffff:[^.]*\.\)\([0-9]\{1\}\)\(\.\)/\100\2\3/g
s/^\([^ ]* DIRECT\/::ffff:[^.]*\.\)\([0-9]\{2\}\)\(\.\)/\10\2\3/g
s/^\([^ ]* DIRECT\/::ffff:[^.]*\.[^.]*\.\)\([0-9]\{1\}\)\(\.\)/\100\2\3/g
s/^\([^ ]* DIRECT\/::ffff:[^.]*\.[^.]*\.\)\([0-9]\{2\}\)\(\.\)/\10\2\3/g
s/^\([^ ]* DIRECT\/::ffff:[^.]*\.[^.]*\.[^.]*\.\)\([0-9]\{1\}\)\( \)/\100\2\3/g
s/^\([^ ]* DIRECT\/::ffff:[^.]*\.[^.]*\.[^.]*\.\)\([0-9]\{2\}\)\( \)/\10\2\3/g
' > /dev/shm/stage3
fi
if [ ! -f /dev/shm/stage4 ]
then
cat /dev/shm/stage3 | sort | uniq > /dev/shm/stage4
fi
I have not seen a complete IPv6 routes list yet. I use the following to have a complete IPv6 routing table after having dropped the default route that sit0 likes to setup. This allows the site and rfc 4193 local ranges to be unroutable and hence safe to use for local experiments.
If you are not on 6to4 you'll substitute ommission of 2002 for your own netblock.
#!/bin/sh
# wget http://www.iana.org/assignments/ipv6-unicast-address-assignments -O /var/local/routes/ipv6.txt
cat /var/local/routes/ipv6.txt | grep -v ^2002 | grep ^....\: | cut -f1 -d" " | while read
do
route -A inet6 $1 $REPLY gw ::192.88.99.1 dev $2
done
It is possible to provide a set of routes via a DHCP option, which gives the advantage of end-stations knowing immediately that certain private IP addresses are unreachable.
If using an operating system that recognises only a single instance of the route option, you can offer only a few routes (about 40 at most), so I have paired down the null “martian” list to the bare essentials. Of course, it is possible to have a more complete table elsewhere.
0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 240.0.0.0/4
Inverted, it gives this table for dhcpd, replace 192,0,2,1 with the IP address of your router.
option rfc3442-classless-static-routes code 121 = array of unsigned integer 8; option rfc3442-classless-static-routes-microsoft code 249 = array of unsigned integer 8; option rfc3442-classless-static-routes 8,1,192,0,2,1, 7,2,192,0,2,1, 6,4,192,0,2,1, 7,8,192,0,2,1, 8,11,192,0,2,1, 6,12,192,0,2,1, 4,16,192,0,2,1, 3,32,192,0,2,1, 3,64,192,0,2,1, 4,96,192,0,2,1, 5,112,192,0,2,1, 6,120,192,0,2,1, 7,124,192,0,2,1, 8,126,192,0,2,1, 3,128,192,0,2,1, 5,160,192,0,2,1, 6,168,192,0,2,1, 12,172,0,192,0,2,1, 11,172,32,192,0,2,1, 10,172,64,192,0,2,1, 9,172,128,192,0,2,1, 8,173,192,0,2,1, 7,174,192,0,2,1, 4,176,192,0,2,1, 9,192,0,192,0,2,1, 11,192,128,192,0,2,1, 13,192,160,192,0,2,1, 16,192,169,192,0,2,1, 15,192,170,192,0,2,1, 14,192,172,192,0,2,1, 12,192,176,192,0,2,1, 10,192,192,192,0,2,1, 8,193,192,0,2,1, 7,194,192,0,2,1, 6,196,192,0,2,1, 5,200,192,0,2,1, 4,208,192,0,2,1;