#!/sbin/runscript # 2010-08-11 # # exchange default route to route through a tunneled gateway. # preferably used in combination with an existing OpenVPN tunnel. # this may be used as an init script. # # it modifies your default route to go through $GW_INTERNAL_IP. # beforehand it creates a more preferred host route to $GW_EXTERNAL_IP, # which is your tunnel server (e.g. OpenVPN) to keep routing tunnel packets up. # # keep in mind that your client still uses your DNS settings, # so edit /etc/resolv.conf and use a non link local name server, # if you want DNS traffic to go through your tunnel, too. # # DEPENDS basename ip awk # # TODO: call "ip route" less often -> cache stuff # NOTE: return codes of "ip route" not checked to allow soft failures # NOTE: it's somehow dirty to actually not start any daemon and faking it via mark_service_{started,stopped} # NOTE: will work only with exactly one default route given SELF=`basename $1` [ -f "/etc/conf.d/${SELF}" ] && . "/etc/conf.d/${SELF}" depend() { use net after bootmisc } start() { ebegin "Starting ${SELF}" # get original default gateway. # this fails, if more that one exists. (yes, there are reasons for multiple default gateways!) DEFAULT_GW=`ip route |awk '$1~/default/ && $2~/via/ {print $3}'` DEFAULT_GW_METRIC=`ip route |awk '$1~/default/ && $2~/via/ && $6~/metric/ {print $7}'` [ "${DEFAULT_GW}" == "" ] && eend 1 "ERROR: could not get original default gateway!" einfo "adding host route to tunnel gateway [${GW_EXTERNAL_IP}] via original default gateway [${DEFAULT_GW}]..." ip route add "${GW_EXTERNAL_IP}" via "${DEFAULT_GW}" # original default gateway has standard or no metric? remove and save to restore later. if [ "${DEFAULT_GW_METRIC}" == "" -o "X${DEFAULT_GW_METRIC}" == "X0" ]; then RESTORE_DEFAULT_GW=`ip route |awk '$1~/default/ && $2~/via/ {print $0}'` einfo "removing original default gateway [${DEFAULT_GW}]..." ip route del default via "${DEFAULT_GW}" else einfo "not touching original default gateway, which has low priority metric!" fi einfo "adding new default route via tunnel [${GW_INTERNAL_IP}]..." ip route add default via ${GW_INTERNAL_IP} eend $? mark_service_started "${SELF}" } stop() { ebegin "Stopping ${SELF}" einfo "getting original default gateway from direct host route" DEFAULT_GW=`ip route |awk "\\$1~/${GW_EXTERNAL_IP}/ && \\$2~/via/ {print \\$3}"` [ "${DEFAULT_GW}" == "" ] && ewarn "WARNING: could not get original default gateway!" einfo "removing default gateway [${GW_INTERNAL_IP}]..." ip route del default via ${GW_INTERNAL_IP} ip route |grep "^default via " >/dev/null # restore original default gw, if nessessary if [ $? != 0 ]; then einfo "restoring original default gateway [${DEFAULT_GW}]..." ip route add default via ${DEFAULT_GW} fi einfo "removing route to tunnel gateway [${GW_EXTERNAL_IP}] via original default gateway [${DEFAULT_GW}]..." ip route del "${GW_EXTERNAL_IP}" via "${DEFAULT_GW}" eend $? mark_service_stopped "${SELF}" }