Use /etc/tinc/example as a base directory for an example. /etc/tinc/example/README...
[tinc] / redhat / tinc
1 #!/bin/sh
2 #
3 # tinc          tincd VPN setup script
4 #
5 # chkconfig:    2345 46 54
6 #
7 # version:      1.0.4
8 # author:       Lubomir Bulej <pallas@kadan.cz>
9 #               Modified for RPM by Mads Kiilerich <mads@kiilerich.com>
10 #
11 # description:  this script takes care of starting and setting up of VPNs \
12 #               provided by tincd daemon. It parses the configuration files \
13 #               in all VPN directories and sets up the interfaces and routing
14 #
15 # processname:  tincd
16
17 # Source function library.
18 . /etc/rc.d/init.d/functions
19
20 # Source networking configuration.
21 . /etc/sysconfig/network
22
23 # Check that networking is up.
24 [ ${NETWORKING} = "no" ] && exit 0
25
26 #############################################################################
27 # configuration & sanity checks
28
29 TINCD=/usr/sbin/tincd
30 TCONF=/etc/tinc
31 TPIDS=/var/run
32 #DEBUG=-dddd
33
34 # Check the daemon
35 if [ ! -x $TINCD ]; then
36     echo "**tinc: daemon $TINCD does not exist or is not executable!"
37     exit
38 fi
39
40 # Check if ip-route is installed
41 if [ ! -f /sbin/ip ]; then
42     echo "**tinc: ip-route utilities not installed!"
43     exit
44 fi
45
46 # Check the configuration directory
47 if [ ! -d $TCONF ]; then
48     echo "**tinc: configuration directory ($TCONF) not found!"
49     exit
50 fi
51                  
52
53 ##############################################################################
54 # vpn_load ()           Loads VPN configuration
55
56 # $1 ... VPN to load
57
58 vpn_load () {
59     CFG="$TCONF/$1/tinc.conf"
60     [ -f $CFG ] || { echo "**tinc: $CFG does not exist!" >&2; return 1; }
61     
62     # load TINCD config
63     DEV=`grep -i -e '^[[:space:]]*TapDevice' $CFG | sed 's/[[:space:]]//g; s/^.*=//g'`
64     VPN=`grep -i -e '^[[:space:]]*(MyOwnVPNIP|MyVirtualIP)' -E $CFG | head -1 | sed 's/[[:space:]]//g; s/^.*=//g'`
65     
66     # discourage empty and multiple entries
67     [ -z "$DEV" ] && \
68         { echo "**tinc: TapDevice required!" >&2; return 2; }
69     echo $DEV | grep -q '^/dev/tap' ||
70         { echo "**tinc: TapDevice should be in form /dev/tapX" >&2; return 2; }
71     [ `echo $DEV | wc -l` -gt 1 ] && \
72         { echo "**tinc: multiple TapDevice entries not allowed!" >&2; return 3; }
73     [ -z "$VPN" ] && \
74         { echo "**tinc: MyOwnVPNIP/MyVirtualIP required!" >&2; return 2; }
75     [ `echo $VPN | wc -l` -gt 1 ] && \
76         { echo "**tinc: multiple MyOwnVPNIP/MyVirtualIP entries not allowed!" >&2; return 3; }
77     echo $VPN | grep -q -x  \
78         '\([[:digit:]]\{1,3\}\.\)\{3\}[[:digit:]]\{1,3\}/[[:digit:]]\{1,2\}' || \
79         { echo "**tinc: badly formed MyOwnVPNIP/MyVirtualIP address $VPN!"; return 3; }
80     
81     # network device
82     TAP=`echo $DEV | cut -d"/" -f3`
83     NUM=`echo $TAP | sed 's/tap//'`
84
85     # IP address, netmask length
86     ADR=`echo $VPN | cut -d"/" -f1`
87     LEN=`echo $VPN | cut -d"/" -f2`
88
89     # Expand bitlength to netmask    
90     MSK=""; len=$LEN
91     for cnt in 1 1 1 0; do
92         if [ $len -ge 8 ]; then
93             msk=8
94         else
95             msk=$len
96         fi
97             
98         MSK="$MSK$((255 & (255 << (8 - msk))))"
99         [ $cnt -ne 0 ] && MSK="$MSK."
100         len=$((len-msk))
101     done
102
103     # Network & broadcast addresses
104     BRD=`ipcalc --broadcast $ADR $MSK | cut -d"=" -f2`
105     NET=`ipcalc --network $ADR $MSK | cut -d"=" -f2`
106         
107     # MAC address
108     MAC=`printf "fe:fd:%0.2x:%0.2x:%0.2x:%0.2x" $(echo $ADR | sed 's/\./ /g')`
109     # echo "TAP $TAP NUM $NUM ADR $ADR LEN $LEN MSK $MSK BRD $BRD NET $NET MAC $MAC" >&2
110     return 0
111 }
112
113
114 ##############################################################################
115 # vpn_start ()          starts specified VPN
116
117 # $1 ... VPN to start
118
119 vpn_start () {    
120
121     vpn_load $1 || { echo "**tinc: could not vpn_load $1" >&2; return 1; }
122             
123     # create device file
124     if [ ! -c $DEV ]; then
125         [ -e $DEV ] && rm -f $DEV
126         mknod --mode=0600 $DEV c 36 $((16 + NUM))
127     fi
128     
129     # load device module
130     { insmod ethertap --name="ethertap$NUM" unit="$NUM" 2>&1 || \
131         { echo "**tinc: cannot insmod ethertap$NUM" >&2; return 2; }
132     } | grep -v '^Us'
133     
134     # configure the interface
135     ip link set $TAP address $MAC
136     ip link set $TAP up
137     ip addr flush dev $TAP 2>&1 | grep -v -x '^Nothing to flush.'
138     ip addr add $VPN brd $BRD dev $TAP
139     
140     # start tincd
141     $TINCD --net="$1" $DEBUG || \
142         { echo "**tinc: could not start $TINCD" >&2; return 3; }
143
144     # default interface route
145     # ip route add $NET/$LEN dev $TAP
146
147     # setup routes
148     /etc/sysconfig/network-scripts/ifup-routes $TAP
149
150     return 0
151 } # vpn_start
152
153
154 ##############################################################################
155 # vpn_stop ()           Stops specified VPN
156 #
157 # $1 ... VPN to stop
158
159 vpn_stop () {
160
161     vpn_load $1 || return 1
162     
163     # flush the routing table
164     # ip route flush dev $TAP &> /dev/null
165     
166     # kill the tincd daemon
167     PID="$TPIDS/tinc.$1.pid"
168     if [ -f $PID ]; then
169         $TINCD --net="$1" --kill &> /dev/null
170         RET=$?
171     
172         if [ $RET -eq 0 ]; then
173             dly=0
174             while [ $dly -le 5 ]; do
175                 [ -f $PID ] || break
176                 sleep 1; dly=$((dly+1))
177             done
178         fi
179         
180         [ -f $PID ] && rm -f $PID
181     fi
182     
183     # bring the interface down
184     ip link set $TAP down &> /dev/null
185     
186     # remove ethertap module
187     rmmod "ethertap$NUM" &> /dev/null
188     
189     return 0
190 } # vpn_stop
191
192
193 # See how we were called.
194 case "$1" in
195     start)
196         for vpn in `ls -1 $TCONF`; do
197             echo -n "Bringing up VPN $vpn: "
198             vpn_start $vpn && action "" /bin/true
199         done
200         
201         touch /var/lock/subsys/tinc
202         ;;
203         
204     stop)
205         for vpn in `ls -1 $TCONF`; do
206             echo -n "Shutting down VPN $vpn: "
207             vpn_stop $vpn && action "" /bin/true
208         done
209         
210         rm -f /var/lock/subsys/tinc
211         ;;
212         
213     status)
214         echo -n "Configured VPNs: "
215         for vpn in `ls -1 $TCONF`; do
216             PID="$TPIDS/tinc.$vpn.pid"
217             echo -n "$vpn:"
218             if [ -f $PID -a `ps ax | grep "^ *$(cat $PID)" | wc -l` -eq 1 ] 
219             then
220                 echo -n "OK "
221             else
222                 echo -n "DEAD "
223             fi
224         done
225         echo             
226         ;;      
227         
228     restart)
229         $0 stop
230         $0 start
231         ;;
232                 
233     *)
234         echo "Usage: tinc {start|stop|status|restart}"
235         exit 1
236 esac
237
238 exit 0