1#!/bin/sh
2### BEGIN INIT INFO
3# Provides:                     openvpn
4# Required-Start:               $network
5# Required-Stop:                $network
6# Default-Start:                3 5
7# Default-Stop:                 0 1 2 6
8# Short-Description:            This shell script takes care of starting and stopping OpenVPN.
9# Description:                  OpenVPN is a robust and highly flexible tunneling application that uses all of the encryption, authentication, and certification features of the OpenSSL library to securely tunnel IP networks over a single UDP port. 
10### END INIT INFO
11
12# Contributed to the OpenVPN project by
13# Douglas Keller <doug@voidstar.dyndns.org>
14# 2002.05.15
15
16# Modified for SuSE by
17# Frank Plohmann <openvpn@franks-planet.de>
18# 2003.08.24
19# Please feel free to contact me if you have problems or suggestions
20# using this script.
21
22# To install:
23#   copy this file to /etc/rc.d/init.d/openvpn
24#   use the runlevel editor in Yast to add it to runlevel 3 and/or 5
25#   shell> mkdir /etc/openvpn
26#   make .conf or .sh files in /etc/openvpn (see below)
27
28# To uninstall:
29#   use also Yast and the runlevel editor to uninstall
30
31# Author's Notes:
32#
33# I have created an /etc/init.d init script and enhanced openvpn.spec to
34# automatically register the init script.  Once the RPM is installed you
35# can start and stop OpenVPN with "service openvpn start" and "service
36# openvpn stop".
37#
38# The init script does the following:
39#
40# - Starts an openvpn process for each .conf file it finds in
41#   /etc/openvpn.
42#
43# - If /etc/openvpn/xxx.sh exists for a xxx.conf file then it executes
44#   it before starting openvpn (useful for doing openvpn --mktun...).
45#
46# - In addition to start/stop you can do:
47#
48#   /etc/init.d/openvpn reload - SIGHUP
49#   /etc/init.d/openvpn reopen - SIGUSR1
50#   /etc/init.d/openvpn status - SIGUSR2
51
52# Modifications 2003.05.02
53#   * Changed == to = for sh compliance (Bishop Clark).
54#   * If condrestart|reload|reopen|status, check that we were
55#     actually started (James Yonan).
56#   * Added lock, piddir, and work variables (James Yonan).
57#   * If start is attempted twice, without an intervening stop, or
58#     if start is attempted when previous start was not properly
59#     shut down, then kill any previously started processes, before
60#     commencing new start operation (James Yonan).
61#   * Do a better job of flagging errors on start, and properly
62#     returning success or failure status to caller (James Yonan).
63#
64# Modifications 2003.08.24
65#   * Converted the script for SuSE Linux distribution. 
66#	  Tested with version 8.2 (Frank Plohmann).
67#		- removed "chkconfig" header
68#		- added Yast header
69#		- changed installation notes
70#		- corrected path to openvpn binary
71#		- removes sourcing "functions"
72#		- removed sourcing "network"
73#		- removed network checking. it seemed not to work with SuSE.
74#		- added sourcing "rc.status", comments and "rc_reset" command
75#		- removed "succes; echo" and "failure; echo" lines
76#		- added "rc_status" lines at the end of each section
77#		- changed "service" to "/etc/init.d/" in "In addition to start/stop"
78#		  section above.
79#
80# Modifications 2005.04.04
81#   * Added openvpn-startup and openvpn-shutdown script calls (James Yonan).
82#
83
84# Location of openvpn binary
85openvpn="/usr/sbin/openvpn"
86
87# Lockfile
88lock="/var/lock/subsys/openvpn"
89
90# PID directory
91piddir="/var/run/openvpn"
92
93# Our working directory
94work=/etc/openvpn
95
96# Source rc functions
97. /etc/rc.status
98
99# Shell functions sourced from /etc/rc.status:
100#      rc_check         check and set local and overall rc status
101#      rc_status        check and set local and overall rc status
102#      rc_status -v     ditto but be verbose in local rc status
103#      rc_status -v -r  ditto and clear the local rc status
104#      rc_failed        set local and overall rc status to failed
105#      rc_reset         clear local rc status (overall remains)
106#      rc_exit          exit appropriate to overall rc status
107
108#      rc_status        check and set local and overall rc status
109#      rc_status -v     ditto but be verbose in local rc status
110#      rc_status -v -r  ditto and clear the local rc status
111#      rc_failed        set local and overall rc status to failed
112#      rc_reset         clear local rc status (overall remains)
113#      rc_exit          exit appropriate to overall rc status
114
115# First reset status of this service
116rc_reset
117
118[ -f  $openvpn ] || exit 0
119
120# See how we were called.
121case "$1" in
122  start)
123	echo -n $"Starting openvpn: "
124
125	/sbin/modprobe tun >/dev/null 2>&1
126
127	# From a security perspective, I think it makes
128	# sense to remove this, and have users who need
129	# it explictly enable in their --up scripts or
130	# firewall setups.
131
132	#echo 1 > /proc/sys/net/ipv4/ip_forward
133
134	# Run startup script, if defined
135	if [ -f $work/openvpn-startup ]; then
136	    $work/openvpn-startup
137	fi
138
139	if [ ! -d  $piddir ]; then
140	    mkdir $piddir
141	fi
142
143	if [ -f $lock ]; then
144	    # we were not shut down correctly
145	    for pidf in `/bin/ls $piddir/*.pid 2>/dev/null`; do
146	      if [ -s $pidf ]; then
147		kill `cat $pidf` >/dev/null 2>&1
148	      fi
149	      rm -f $pidf
150	    done
151	    rm -f $lock
152	    sleep 2
153	fi
154
155	rm -f $piddir/*.pid
156	cd $work
157
158	# Start every .conf in $work and run .sh if exists
159	errors=0
160	successes=0
161	for c in `/bin/ls *.conf 2>/dev/null`; do
162	    bn=${c%%.conf}
163	    if [ -f "$bn.sh" ]; then
164		. $bn.sh
165	    fi
166	    rm -f $piddir/$bn.pid
167	    $openvpn --daemon --writepid $piddir/$bn.pid --config $c --cd $work
168	    if [ $? = 0 ]; then
169		successes=1
170	    else
171		errors=1
172	    fi
173	done
174
175	if [ $successes = 1 ]; then
176	    touch $lock
177	fi
178
179	rc_status -v
180	;;
181  stop)
182	echo -n $"Shutting down openvpn: "
183	for pidf in `/bin/ls $piddir/*.pid 2>/dev/null`; do
184	  if [ -s $pidf ]; then
185	    kill `cat $pidf` >/dev/null 2>&1
186	  fi
187	  rm -f $pidf
188	done
189
190	# Run shutdown script, if defined
191	if [ -f $work/openvpn-shutdown ]; then
192	    $work/openvpn-shutdown
193	fi
194
195	rm -f $lock
196
197	rc_status -v
198	;;
199  restart)
200	$0 stop
201	sleep 2
202	$0 start
203
204	rc_status
205	;;
206  reload)
207	if [ -f $lock ]; then
208	    for pidf in `/bin/ls $piddir/*.pid 2>/dev/null`; do
209		if [ -s $pidf ]; then
210		    kill -HUP `cat $pidf` >/dev/null 2>&1
211		fi
212	    done
213	else
214	    echo "openvpn: service not started"
215	    exit 1
216	fi
217
218	rc_status -v
219	;;
220  reopen)
221	if [ -f $lock ]; then
222	    for pidf in `/bin/ls $piddir/*.pid 2>/dev/null`; do
223		if [ -s $pidf ]; then
224		    kill -USR1 `cat $pidf` >/dev/null 2>&1
225		fi
226	    done
227	else
228	    echo "openvpn: service not started"
229	    exit 1
230	fi
231
232	rc_status -v
233	;;
234  condrestart)
235	if [ -f $lock ]; then
236	    $0 stop
237	    # avoid race
238	    sleep 2
239	    $0 start
240	fi
241
242	rc_status
243	;;
244  status)
245	if [ -f $lock ]; then
246	    for pidf in `/bin/ls $piddir/*.pid 2>/dev/null`; do
247		if [ -s $pidf ]; then
248		    kill -USR2 `cat $pidf` >/dev/null 2>&1
249		fi
250	    done
251	    echo "Status written to /var/log/messages"
252	else
253	    echo "openvpn: service not started"
254	    exit 1
255	fi
256
257	rc_status -v
258        ;;
259  *)
260	echo "Usage: openvpn {start|stop|restart|condrestart|reload|reopen|status}"
261	exit 1
262esac
263
264exit 0
265