summaryrefslogtreecommitdiff
blob: d65e6f8bd7c43827f1f6d8bff3001d38c7df275e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/sbin/runscript
# Copyright 1999-2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

VPNDIR=${VPNDIR:-/etc/openvpn}
VPN=${SVCNAME#*.}
if [ -n "${VPN}" ] && [ ${SVCNAME} != "openvpn" ]; then
	VPNPID="/var/run/openvpn.${VPN}.pid"
else
	VPNPID="/var/run/openvpn.pid"
fi
VPNCONF="${VPNDIR}/${VPN}.conf"

depend() {
	need localmount net
	use dns
	after bootmisc
}

checkconfig() {
	# Linux has good dynamic tun/tap creation
	if [ $(uname -s) = "Linux" ] ; then
		if [ ! -e /dev/net/tun ]; then
			if ! modprobe tun ; then
				eerror "TUN/TAP support is not available" \
					"in this kernel"
				return 1
			fi
		fi
		if [ -h /dev/net/tun ] && [ -c /dev/misc/net/tun ]; then
			ebegin "Detected broken /dev/net/tun symlink, fixing..."
			rm -f /dev/net/tun
			ln -s /dev/misc/net/tun /dev/net/tun
			eend $?
		fi
		return 0
	fi

	# Other OS's don't, so we rely on a pre-configured interface
	# per vpn instance
	local ifname=$(sed -n -e 's/[[:space:]]*dev[[:space:]][[:space:]]*\([^[:space:]]*\).*/\1/p' "${VPNCONF}")
	if [ -z ${ifname} ] ; then
		eerror "You need to specify the interface that this openvpn" \
			"instance should use" \
			"by using the dev option in ${VPNCONF}"
		return 1
	fi

	if ! ifconfig "${ifname}" >/dev/null 2>/dev/null ; then
		# Try and create it
		echo > /dev/"${ifname}" >/dev/null
	fi
	if ! ifconfig "${ifname}" >/dev/null 2>/dev/null ; then
		eerror "${VPNCONF} requires interface ${ifname}" \
			"but that does not exist"
		return 1
	fi
}

start() {
	# If we are re-called by the openvpn gentoo-up.sh script
	# then we don't actually want to start openvpn
	[ "${IN_BACKGROUND}" = "true" ] && return 0
	
	ebegin "Starting ${SVCNAME}"

	checkconfig || return 1

	local args="" reenter=${RE_ENTER:-no}
	# If the config file does not specify the cd option, we do
	# But if we specify it, we override the config option which we do not want
	if ! grep -q "^[ 	]*cd[ 	].*" "${VPNCONF}" ; then
		args="${args} --cd ${VPNDIR}"
	fi
	
	# We mark the service as inactive and then start it.
	# When we get an authenticated packet from the peer then we run our script
	# which configures our DNS if any and marks us as up.
	if [ "${DETECT_CLIENT:-yes}" = "yes" ] && \
	grep -q "^[ 	]*remote[ 	].*" "${VPNCONF}" ; then
		reenter="yes"
		args="${args} --up-delay --up-restart"
		args="${args} --script-security 2"
		args="${args} --up /etc/openvpn/up.sh"
		args="${args} --down-pre --down /etc/openvpn/down.sh"

		# Warn about setting scripts as we override them
		if grep -Eq "^[ 	]*(up|down)[ 	].*" "${VPNCONF}" ; then
			ewarn "WARNING: You have defined your own up/down scripts"
			ewarn "As you're running as a client, we now force Gentoo specific"
			ewarn "scripts to be run for up and down events."
			ewarn "These scripts will call /etc/openvpn/${SVCNAME}-{up,down}.sh"
			ewarn "where you can put your own code."
		fi

		# Warn about the inability to change ip/route/dns information when
		# dropping privs
		if grep -q "^[ 	]*user[ 	].*" "${VPNCONF}" ; then
			ewarn "WARNING: You are dropping root privileges!"
			ewarn "As such openvpn may not be able to change ip, routing"
			ewarn "or DNS configuration."
		fi
	else
		# So we're a server. Run as openvpn unless otherwise specified
		grep -q "^[ 	]*user[ 	].*" "${VPNCONF}" || args="${args} --user openvpn"
		grep -q "^[ 	]*group[ 	].*" "${VPNCONF}" || args="${args} --group openvpn"
	fi

	# Ensure that our scripts get the PEER_DNS variable
	[ -n "${PEER_DNS}" ] && args="${args} --setenv PEER_DNS ${PEER_DNS}"

	[ "${reenter}" = "yes" ] && mark_service_inactive "${SVCNAME}"
	start-stop-daemon --start --exec /usr/sbin/openvpn --pidfile "${VPNPID}" \
		-- --config "${VPNCONF}" --writepid "${VPNPID}" --daemon \
		--setenv SVCNAME "${SVCNAME}" ${args}
	eend $? "Check your logs to see why startup failed"
}

stop() {
	# If we are re-called by the openvpn gentoo-down.sh script
	# then we don't actually want to stop openvpn
	if [ "${IN_BACKGROUND}" = "true" ] ; then
		mark_service_inactive "${SVCNAME}"
		return 0
	fi

	ebegin "Stopping ${SVCNAME}"
	start-stop-daemon --stop --quiet \
		--exec /usr/sbin/openvpn --pidfile "${VPNPID}"
	eend $?
}

# vim: set ts=4 :