[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

new script: auto6to4



I've written a short script that, when run on a first-class IPv4 host,
makes it a IPv6 host via a protocol-41 uplink, and also makes an IPv6
cloud around it.  Seems to work okay on the few machines I've tested
it on.  The script goes to some trouble to not do any harm, eg to bail
if the host looks like it is behind a NAT.

The intent is to add bells-and-whistles to this, ultimately making it
into a Debian package that can be "just installed", ie without
configuration, to give reasonable and contagious IPv6 functionality.
It isn't very pretty right now, but I was hoping I could get some
feedback on it anyway.  Mainly I'm hoping people will let me know:

 - if this is a stupid idea, and if so why
 - if they found this useful
 - if making this into a Debian package would be a good idea
 - if they find or fix any bugs, or make any other improvements
 - if they'd like to volunteer to take this over from me (please!)

Thanks,
--
Barak A. Pearlmutter <barak@cs.nuim.ie>
 Hamilton Institute & Dept Comp Sci, NUI Maynooth, Co. Kildare, Ireland
 http://www-bcl.cs.nuim.ie/~barak/

----------------------------------------------------------------
FILE BELOW: auto6to4
----------------------------------------------------------------

#!/bin/bash -f
# CVS version control block - do not edit manually
#  $RCSfile: auto6to4,v $
#  $Revision: 1.10 $
#  $Date: 2005/12/27 00:37:42 $
#  $Source: /home/cvs/meg/system/auto6to4,v $

#  auto6to4 - robustly and automatically enable IPv6 cloud around IPv4 host.
#  Copyright 2005, Barak A. Pearlmutter <barak@cs.nuim.ie>
#   Hamilton Institute, NUI Maynooth, Co. Kildare, Ireland
#   http://www-bcl.cs.nuim.ie/~barak/
#   (Much thanks to David Malone.  David wrote the book on IPv6; buy it!)
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.

DESC=auto6to4

# Debian Dependencies
#  Depends: iproute, ipv6calc
#  Suggests: radvd

## To Do

# - graceful error handling
# - take argument: start, stop, reload
# - figure out how to integrate into /etc/network/if-up.d/ etc
# - configuration option for external IPv4 address for NATed host,
#   so it can run behind NAT
# - copy more schmutz from /etc/init.d/radvd
# - make into nice Debian package
# - use debconf to control radvd and true external IPv4 address


## Get info and decide whether to bring up tunnel.

# Check for IPv6 support in kernel
if [ \! -e /proc/sys/net/ipv6 ]; then
  echo "error: IPv6 support must be enabled in the kernel for ${DESC} to work."
  exit
fi

# Scarf list of local 1st-class IPv4 addresses
ip4addr=`ip -4 addr \
 | egrep inet \
 | egrep -v 'inet 127[.]' \
 | egrep -v 'inet 10[.]' \
 | egrep -v 'inet 172[.]1[6-9][.]' \
 | egrep -v 'inet 172[.]2[0-9][.]' \
 | egrep -v 'inet 172[.]3[0-1][.]' \
 | egrep -v 'inet 192[.]168[.]' \
 | tr / ' ' \
 | awk '{print $2}'`

# Bail if there are none
if [ -z "${ip4addr}" ]; then
    echo "warning: unable to enable 6to4 tunnel,"
    echo "   no suitable IPv4 address configured."
    exit 1
fi

# Bail if there are more than one
if echo "${ip4addr}" | egrep --silent ' '; then
    echo "warning: not attempting to enable 6to4 tunnel,"
    echo "   multiple suitable IPv4 addresses configured."
    echo " Addresses: ${ip4addr}."
    echo " You may wish to reconfigure ${DESC} to choose one."
    exit 1
fi


## Attempt to bring up tunnel

# Convert chosen 1st-class IPv4 address into tunnel endpoint address
ip6net=`ipv6calc --in ipv4 --out ipv6 --action conv6to4 ${ip4addr}`
ip6addr=${ip6net}1

# Name of tunnel interface to configure
tunnel=tun6in4

# Kill tunnel if possibly alive (DISABLED)
if false && ip tunnel | egrep --silent "^${tunnel}:"; then
    ip tunnel del ${tunnel}
fi

# Flush tunnel from routing table if present
if ip -6 route | egrep --silent " dev ${tunnel} " ; then
    ip -6 route flush dev ${tunnel}
    ip -6 addr flush dev ${tunnel}
fi

# configure and start the tunnel
ip tunnel add ${tunnel} mode sit ttl 128 remote any local ${ip4addr}
ip -6 addr add ${ip6addr}/16 dev ${tunnel}
ip -6 route add ::/96 dev ${tunnel}
ip -6 route add 2000::/3 via ::192.88.99.1 dev ${tunnel}
ip link set dev ${tunnel} up


## Route and advertise IPv6 addresses on LAN

radvd=/usr/sbin/radvd

# check if radvd is available
if [ \! -x ${radvd} ]; then
    echo "warning: no radvd executable, not advertising"
    exit
fi

radvddir=/var/run/radvd
radvdcnf=${radvddir}/radvd-auto.conf
PIDFILE=${radvddir}/radvd-auto.pid
radvduid=radvd
OPTIONS="--config ${radvdcnf} -u ${radvduid} -p ${PIDFILE}"

# Build a configuration file for radvd.
# We make one stanza for each suitable interface,
# with a subnet allocated to each.

mkdir --parents ${radvddir}
echo > ${radvdcnf}

interfaces=`ip -4 addr \
		| egrep '^[0-9].*BROADCAST.*MULTICAST' \
		| tr -d : \
		| awk '{print $2}'`
inum=1
for i in ${interfaces}; do
  pref=`echo ${ip6net}${inum} | sed 's/::/:/'`
  cat >> ${radvdcnf} <<EOF
interface ${i}
{
   AdvSendAdvert on;
   IgnoreIfMissing on;
   AdvDefaultLifetime 600;
   AdvDefaultPreference low;
   prefix ${pref}::/64
   {
   };
};
EOF
  # set up to route each subnet
  ip -6 addr add ${pref}::1/64 dev ${i}
  inum=$((inum + 1))
done

# Enable routing
sysctl -q -w net.ipv6.conf.all.accept_ra=0
sysctl -q -w net.ipv6.conf.all.forwarding=1

# shut down any existing ravdvd, using appropriate UID for security
if [ -f ${PIDFILE} ]; then
    su -s /bin/sh -c "kill `cat ${PIDFILE}`" ${radvduid}
fi

# Start advertising
${radvd} ${OPTIONS}



Reply to: