summarylogtreecommitdiffstats
path: root/tun-cfg
diff options
context:
space:
mode:
authorNatrio2015-06-15 14:22:46 +0300
committerNatrio2015-06-15 14:22:46 +0300
commit8ef8f2a02f4bcb9b5a1334c2f7cc24193e0d95f4 (patch)
tree4ce578cd61b7b3ba864e0283e4087a1b06442fb2 /tun-cfg
downloadaur-8ef8f2a02f4bcb9b5a1334c2f7cc24193e0d95f4.tar.gz
Initial import
Diffstat (limited to 'tun-cfg')
-rwxr-xr-xtun-cfg466
1 files changed, 466 insertions, 0 deletions
diff --git a/tun-cfg b/tun-cfg
new file mode 100755
index 000000000000..c6fadf51f63d
--- /dev/null
+++ b/tun-cfg
@@ -0,0 +1,466 @@
+#!/bin/bash
+
+# Tunnel-configurer:
+# Client-server IP tunnel configuration via the same IP tunnel.
+#
+# Copyright (C) 2014 Natrio <natrio@list.ru>
+#
+# 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.
+
+PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
+
+[[ "$1" =~ ^(-tun|-h|-help|--help|)$ ]] || exec ifconfig "$@"
+
+# config defaults
+PORT=68
+MTU=1500
+TIMEOUT=10
+CMD=tun-cat
+
+usage() {
+ [[ -n "$1" ]] && return 0
+ echo "Tunnel-configurer version 1.6.1
+ Client-server IP tunnel configuration via the same IP tunnel.
+
+-- vtund.conf --
+ # ifconfig replacement by wrapper
+options {
+ ...
+ #ifconfig /sbin/ifconfig;
+ ifconfig $HELPSTR;
+ ...
+
+ # Usual ifconfig example ($NAME doesn't break it):
+ # On server
+host0 {
+ passwd K@bI\$D0x;
+ up {
+ ifconfig \"%d 10.10.0.1 pointopoint 10.10.8.8\";
+ };
+}
+
+ # On client
+host0 {
+ passwd K@bI\$D0x;
+ up {
+ ifconfig \"%d 10.10.8.8 pointopoint 10.10.0.1\";
+ ip \"route add 10.10.10.0/24 dev %d\";
+ ip \"route add 10.10.0.0/24 dev %d\";
+ };
+}
+
+ # And same one with parameters transmission:
+ # Server example #1, without ${NAME}.conf and names
+host1 {
+ passwd K@bI\$D0x;
+ up {
+ ifconfig \"-tun %d local 10.10.0.1 send 10.10.10.5 10.10.10.0/24 10.10.0.0/24\";
+ };
+}
+
+ # Server example #2, with ${NAME}.conf and client's domain name
+host1 {
+ passwd K@bI\$D0x;
+ up {
+ ifconfig \"-tun %d send host1.vpn\";
+ };
+}
+
+ # Client example, getting all parameters from server
+host1 {
+ passwd K@bI\$D0x;
+ up {
+ ifconfig \"-tun %d get metric 100\";
+ };
+}
+
+-- Common definion's file /etc/${NAME}.conf (useful for server) --
+ # defaults
+PORT=68
+MTU=1500
+TIMEOUT=10
+ # the address of server for all hosts (example)
+LOCAL=server.vpn
+ # routes for sending to clients (example)
+ROUTES='10.10.10.0/24 10.10.0.0/24'
+
+-- Command-line description --
+ifconfig wrapper:
+ $NAME <'ifconfig' options>
+Server:
+ $NAME -tun <interface> send|-s <client_addr> [OPTIONS] [<client-side routes>]
+Client:
+ $NAME -tun <interface> get|-g|listen [OPTIONS] [<'ip route' options>][-6|v6 <options>]
+
+Addresses of client and server may be specified by IP, by name, or by
+ comma-separated list of IPv4,IPv6,names with v4,v6,no4,no6 modifiers.
+ All names will be resolved on server side, and only first IPv4 and IPv6 will be used:
+
+ 10.1.0.1 -> 10.1.0.1
+ 10.1.0.1,fc00::1001:1 -> 10.1.0.1 fc00::1001:1
+ host.vpn -> 10.1.0.4 fc00::1001:4
+ host.vpn,v4 -> 10.1.0.4
+ host.vpn,v6 -> fc00::1001:4
+
+Routes may be specified by IPv4/mask, IPv6/mask,
+ default (for IPv4), defaultv6 or default6 (for IPv6).
+
+OPTIONS:
+ port|-P <port> : default=68
+ mtu|-m <MTU> : default=1500, 0=no change
+forcemtu|+m <MTU> : Don't get MTU from server (client only)
+ local|-l <addr>|-: Force/skip local address (server only)
+ noaddr|-a : Don't modify any IPv4 addresses on interface
+ no6addr|-A : Don't modify any IPv6 addresses on interface
+ nopeer|-p : Don't set peer address (IPv4)
+ peer|+p : Add a route to peer instead of peer address (IPv4)
+noroutes|-r : server - Don't send any routes from config
+ : client - Don't get IPv4 routes from server
+no6routes|-R : Don't get IPv6 routes from server (client only)
+ timeout|-t <sec> : default=10, 0=endless
+ nofork|-B | nobg | nobackground
+
+NOTE:
+ By default, tun-cfg forks to background to prevent vtund from endless waiting
+ for tun-cfg termination, if the connection fails during configuration progress.
+"
+ exit $URET
+}
+
+log() {
+ echo $LPREF "$@" >&2
+}
+
+sec_up() {
+ local garb
+ IFS='. ' read "$1" garb < /proc/uptime
+}
+
+get46() {
+ if [[ -z "$IPv4" && "$1" =~ ^[0-9.]+$ ]] ; then IPv4="$1"
+ elif [[ -z "$IPv6" && "${1,,*}" =~ ^[0-9a-f.:]+$ ]] ; then IPv6="$1"
+ else return 1
+ fi
+ return 0
+}
+
+get_addr() {
+ local addr garb prev IFS skip i
+ [[ -z "$3" ]] && return 1
+ unset IPv4 IPv6
+ IFS=' ,'
+ for i in $3 ; do
+ case "${i,,*}" in
+ 6|v6|ip6|ipv6|no4|'-4') skip=4 ;;
+ 4|v4|ip4|ipv4|no6|'-6') skip=6 ;;
+ *)
+ get46 "$i" && continue
+ while IFS=' ' read addr garb ; do
+ [[ "$addr" = "$prev" ]] && continue
+ get46 "$addr"
+ [[ -n "$IPv4" && -n "$IPv6" ]] && break
+ prev="$addr"
+ done < <(RESOLV_MULTI=on exec getent ahosts "$i")
+ ;;
+ esac
+ done
+ [[ -n "$skip" ]] && unset IPv"$skip"
+
+ if [[ -z "$IPv4" && -z "$IPv6" ]] ; then
+ log "Can't resolve '$3' to $1 address"
+ exit 7
+ fi
+ export "$1=$IPv4" "$2=$IPv6"
+}
+
+set_addr() {
+ if [[ -z "$NOADDR" && -n "$1" ]] ; then
+ [[ -z "$NOPEER" && -n "$peer" ]] && PEER="peer $peer"
+ log $RPREF "address $1" $PEER
+ ip addr rep "$1" $PEER dev "$ifc" || exit 3
+ fi
+ shift
+ if [[ -n "$PLUS" && -n "$peer" ]] ; then
+ log $RPREF "peer route $peer" "$@"
+ ip route rep "$peer" dev "$ifc" "$@" || exit 5
+ fi
+}
+
+set_addr_v6() {
+ if [[ -z "$NO6ADDR" && -n "$1" ]] ; then
+ dis6="/proc/sys/net/ipv6/conf/$ifc/disable_ipv6"
+ [[ -f "$dis6" ]] && echo 0 > "$dis6"
+ log $RPREF "address $1"
+ ip -6 addr rep "$1" dev "$ifc" || exit 3
+ echo 0 > "$dis6"
+ fi
+ shift
+ if [[ -n "$peer_6" ]] ; then
+ log $RPREF "peer route $peer_6" "$@"
+ ip -6 route rep "$peer_6" dev "$ifc" "$@"
+ fi
+}
+
+addsend() {
+ local D LOG send
+ D="$1"
+ shift
+ case "$D" in
+ A4)
+ LOG="$1"
+ [[ -n "$2" ]] && LOG="$LOG peer $2"
+ send="$1:$2"
+ ;;
+ R4)
+ LOG="route $1"
+ send="$1"
+ ;;
+ MTU) LOG="mtu $1" ;;
+ A6) LOG="address $1" ;;
+ R6) LOG="route $1" ;;
+ esac
+ [[ -z "$send" ]] && send="$D:$1"
+ log "-> $LOG"
+ SEND[$((i++))]="$send"
+}
+
+main() {
+ case "$ROLE" in
+ send)
+ unset SEND; i=0
+ if [[ -n "$peer" ]] ; then
+ set_addr "$LOCAL"
+ addsend A4 "$peer" "$LOCAL"
+ fi
+ if [[ -n "$peer_6" ]] ; then
+ set_addr_v6 "$LOCAL6"
+ addsend A6 "$peer_6"
+ [[ -n "$LOCAL6" ]] && addsend R6 "$LOCAL6"
+ fi
+ read MTU < "/sys/class/net/$ifc/mtu"
+ addsend MTU "$MTU"
+ for R in $ROUTES $* ; do
+ [[ "${R,,*}" =~ ^defaultv?6$ ]] && R="::/0"
+ if [[ "$R" =~ : ]] ; then
+ [[ -n "$peer_6" ]] || continue
+ addsend R6 "$R"
+ else
+ [[ -n "$peer" ]] || continue
+ addsend R4 "$R"
+ fi
+ done
+
+ if [[ -n "$peer" ]] ; then
+ ping=ping; P="$peer"
+ elif [[ -n "$peer_6" ]] ; then
+ ping=ping6; P="$peer_6"
+ fi
+ sec_up START
+ log "sending ->"
+ while :; do
+ "$CMD" send "$ifc" "$PORT" "${SEND[@]}" || exit 4
+ "$ping" -q -c1 -W1 -I "$ifc" "$P" &> /dev/null && break
+ sec_up SEC
+ if ((TIMEOUT!=0)) && ((SEC > START+TIMEOUT)) ; then
+ log "Time is out."
+ exit 6
+ fi
+ done
+ log "Confirmed, $P is UP."
+ ;;
+
+ get)
+ if [[ "$*" =~ ^(.* |)(v6|-6)(| .*)$ ]] ; then
+ ROPTSv4="${BASH_REMATCH[1]}"
+ ROPTSv6="${BASH_REMATCH[3]}"
+ else
+ ROPTSv4="$*"
+ ROPTSv6="$*"
+ fi
+
+ RPREF='<-'
+ log "listening" $RPREF
+ exec < <(exec "$CMD" listen "$ifc" "$PORT" "$TIMEOUT")
+
+ FIRST=1
+ while IFS='=,: ' read A B; do
+ if [[ "$A" = A6 ]] ; then
+ set_addr_v6 "$B"
+
+ elif ((FIRST==1)) ; then
+ peer="$B"
+ set_addr "$A" $ROPTSv4
+
+ elif [[ "$A" = MTU && -n "$B" && -z "$FORCEMTU" ]] ; then
+ log $RPREF "mtu $B"
+ ip link set "$ifc" mtu "$B"
+
+ elif [[ "$A" = R6 && -n "$B" && -z "$NO6ROUTES" ]] ; then
+ log $RPREF "route $B" $ROPTSv6
+ ip -6 route rep "$B" dev "$ifc" $ROPTSv6
+
+ elif [[ -n "$A" && -z "$B" && -z "$NOROUTES" ]] ; then
+ log $RPREF "route $A" $ROPTSv4
+ ip route rep "$A" dev "$ifc" $ROPTSv4 || exit 5
+ fi
+ FIRST=0
+ done
+ log "Completed."
+ ;;
+ esac
+ }
+
+FILE=`readlink -f $0`
+FILENAME="${FILE##*/}"
+DIR="${FILE%/*}"
+
+CONFIG=/etc/${FILENAME}.conf
+[[ -f "$CONFIG" ]] && . "$CONFIG"
+
+[[ "$CMD" =~ ^/ ]] || CMD="$DIR/$CMD"
+
+[[ -z "$HELPSTR" ]] && HELPSTR="$FILE"
+NAME="${HELPSTR##*/}"
+
+URET=0
+[[ "$1" != '-tun' ]] && usage
+URET=1
+usage "$2"
+ifc="$2"
+shift 2
+
+unset ROLE PLUS PEER NO6ADDR NOADDR NOPEER FORCEMTU NOBG NOROUTES NO6ROUTES RPREF
+while (($#>0)) ; do
+ case "$1" in
+ -s|send)
+ usage "$2"
+ get_addr peer peer_6 "$2"
+ ROLE="send"
+ shift 2
+ ;;
+
+ -g|get|listen)
+ ROLE="get"
+ shift
+ ;;
+
+ -m|mtu)
+ usage "$2"
+ MTU="$2"
+ shift 2
+ ;;
+
+ +m|forcemtu)
+ usage "$2"
+ MTU="$2"
+ FORCEMTU=1
+ shift 2
+ ;;
+
+ -P|port)
+ usage "$2"
+ PORT="$2"
+ shift 2
+ ;;
+
+ -t|timeout)
+ usage "$2"
+ TIMEOUT="$2"
+ shift 2
+ ;;
+
+ -B|nobg|nobackground|nofork)
+ NOBG=1
+ shift
+ ;;
+
+ -l|local)
+ usage "$2"
+ LOCAL="$2"
+ [[ "$2" = '-' ]] && LOCAL=
+ shift 2
+ ;;
+
+ -a|noaddr)
+ NOADDR=1
+ shift
+ ;;
+
+ -A|no6addr)
+ NO6ADDR=1
+ shift
+ ;;
+
+ +p|peer)
+ NOPEER=1
+ PLUS=1
+ shift
+ ;;
+
+ -p|nopeer)
+ NOPEER=1
+ shift
+ ;;
+
+ -r|noroutes)
+ ROUTES=
+ NOROUTES=1
+ shift
+ ;;
+
+ -R|no6routes)
+ NO6ROUTES=1
+ shift
+ ;;
+
+ *)
+ break
+ ;;
+ esac
+done
+usage "$ROLE"
+
+[[ -z "$TIMEOUT" ]] && TIMEOUT=0
+LPREF="$FILENAME($ifc):"
+fd2="/proc/$$/fd/2"
+if [[ "$(readlink -e $fd2)" =~ ^(/dev/null)|($FILE)$ ]] ; then
+ exec 2>&-
+ exec 2> >(exec logger -t "${LPREF%:}" -p daemon.info)
+ LPREF=
+fi
+
+[[ "$MTU" =~ ^(0|auto)$ ]] && MTU=
+[[ -n "$MTU" ]] && mtu="mtu $MTU" || mtu=
+log "Setting $ifc UP" $mtu
+ip link set "$ifc" up $mtu || exit 2
+
+if [[ "$ROLE" = send ]] ; then
+ get_addr LOCAL LOCAL6 "$LOCAL"
+ [[ -z "$LOCAL" ]] && NOADDR=1
+ [[ -z "$LOCAL6" ]] && NO6ADDR=1
+fi
+
+if [[ -z "$NOADDR" ]] ; then
+ log "flushing IPv4 address"
+ ip -4 addr flush dev "$ifc" || exit 3
+fi
+
+if [[ -z "$NO6ADDR" ]] ; then
+ log "flushing IPv6 address"
+ ip -6 addr flush dev "$ifc" || exit 3
+ ip -6 route flush dev "$ifc"
+fi
+
+if [[ -n "$NOBG" ]] ; then
+ main "$@"
+else
+ main "$@" &
+fi