Patchwork [OpenWrt-Devel,PATCHv2,packages] tinc: Add uci config and init files

login
register
Submitter ""@arrakis.dune.hu
Date 2011-11-07 18:45:06
Message ID <0LyUy6-1QuWNR3Uu6-015uMO@smtp.web.de>
Download mbox | patch
Permalink /patch/1576/
State Accepted
Headers show

Comments

""@arrakis.dune.hu - 2011-11-07 18:45:06
From: Linus Lüssing <linus.luessing@web.de>

With this commit configuration via uci, similiar to the one used for
OpenVPN, will be added to tinc.

Most of the parameters are working just as described in the official
manpages of tincd and tinc.conf as provided by its developer.

The only exceptions are 'disabled' which if set to 1 will make the
init script completely ignore this tinc network and/or tinc host
and 'generate_keys' which if set to 1 will check whether
a key pair is already present for the given tinc network and if not will
generate them with the key size of "key_size" (default if not present:
2048) - this reduces the "effort" of setting up a tinc VPN on a router
to just providing the right uci config file with no need of creating
custom initialization scripts for for instance the key generation.

Furthermore, similiar to the OpenVPN configuration, also tinc configs
of its native format can be used. They just need to be placed in
/etc/tinc/NETNAME. The init scripts will always copy the content of
/etc/tinc/ to /tmp first and will append any parameters provided in
/etc/config/tinc afterwards (the user needs to take care to not specify
non-list parameters in both uci and native config).

Signed-off-by: Linus Lüssing <linus.luessing@web.de>
---
Changelog v2:
* Changed option "enable" to "disabled"
* Switched "disabled" default logic (enabled, if "disabled" is not present,
  similar to config/wireless)
* Adding "disabled" option for tinc-host sections as well
* Adding OpenWRT interface name look up support
* Added boolean tinc-host parameters to tinc-net options as well
  (all tinc host parameters may be added to tinc.conf as well)

 net/tinc/Makefile           |    7 ++
 net/tinc/files/tinc.config  |   58 ++++++++++
 net/tinc/files/tinc.init    |  241 +++++++++++++++++++++++++++++++++++++++++++
 net/tinc/files/tinc.upgrade |    1 +
 4 files changed, 307 insertions(+), 0 deletions(-)
 create mode 100644 net/tinc/files/tinc.config
 create mode 100755 net/tinc/files/tinc.init
 create mode 100644 net/tinc/files/tinc.upgrade
Manuel Munz - 2011-11-11 07:35:43
> From: Linus Lüssing <linus.luessing@web.de>
> 
> With this commit configuration via uci, similiar to the one used for
> OpenVPN, will be added to tinc.
> 
> Most of the parameters are working just as described in the official
> manpages of tincd and tinc.conf as provided by its developer.
> 
> The only exceptions are 'disabled' which if set to 1 will make the
> init script completely ignore this tinc network and/or tinc host
> and 'generate_keys' which if set to 1 will check whether
> a key pair is already present for the given tinc network and if not will
> generate them with the key size of "key_size" (default if not present:
> 2048) - this reduces the "effort" of setting up a tinc VPN on a router
> to just providing the right uci config file with no need of creating
> custom initialization scripts for for instance the key generation.
> 
> Furthermore, similiar to the OpenVPN configuration, also tinc configs
> of its native format can be used. They just need to be placed in
> /etc/tinc/NETNAME. The init scripts will always copy the content of
> /etc/tinc/ to /tmp first and will append any parameters provided in
> /etc/config/tinc afterwards (the user needs to take care to not specify
> non-list parameters in both uci and native config).
> 
> Signed-off-by: Linus Lüssing <linus.luessing@web.de>
Reviewed by: Manuel Munz <freifunk at somakoma dot de>

Patch looks good and works, i'd like to see this getting submitted.

Regards, Manuel
Nicolas Thill - 2011-11-16 09:54:20
> Patch looks good and works, i'd like to see this getting submitted.

Applied in r29137, initscript was changed in r29166 to use new service
functions.

--
-{Nico}

Patch

diff --git a/net/tinc/Makefile b/net/tinc/Makefile
index 05f9546..b8b09ec 100644
--- a/net/tinc/Makefile
+++ b/net/tinc/Makefile
@@ -45,6 +45,13 @@  CONFIGURE_ARGS += \
 define Package/tinc/install
 	$(INSTALL_DIR) $(1)/usr/sbin
 	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/tincd $(1)/usr/sbin/
+	$(INSTALL_DIR) $(1)/etc/init.d/
+	$(INSTALL_BIN) files/$(PKG_NAME).init $(1)/etc/init.d/$(PKG_NAME)
+	$(INSTALL_DIR) $(1)/etc/config
+	$(INSTALL_CONF) files/$(PKG_NAME).config $(1)/etc/config/$(PKG_NAME)
+	$(INSTALL_DIR) $(1)/etc/openvpn
+	$(INSTALL_DIR) $(1)/lib/upgrade/keep.d
+	$(INSTALL_DATA) files/tinc.upgrade $(1)/lib/upgrade/keep.d/tinc
 endef
 
 $(eval $(call BuildPackage,tinc))
diff --git a/net/tinc/files/tinc.config b/net/tinc/files/tinc.config
new file mode 100644
index 0000000..38737a7
--- /dev/null
+++ b/net/tinc/files/tinc.config
@@ -0,0 +1,58 @@ 
+config tinc-net NETNAME
+	# Remove to enable
+	option disabled 1
+
+	## Daemon Configuration	(cmd arguments)
+	#option generate_keys 0
+	#option key_size 2048
+	#option log /tmp/log/tinc.NETNAME.log
+	#option debug 3
+
+	## Server Configuration (tinc.conf)
+	#option AddressFamily any
+	#option BindToAddress 127.0.0.1
+	#option BindToInterface lo
+
+	#list ConnectTo peer1
+
+	#option DirectOnly 0
+	#option Forwarding internal
+	#option GraphDumpFile /tmp/log/tinc.NETNAME.dot
+	#option Hostnames 0
+	#option IffOneQueue 0
+	#option Interface NETNAME
+	#option KeyExpire 3600
+	#option MACExpire 600
+	#option MaxTimeout 900
+	#option Mode router
+
+	option Name NODENAME
+
+	#option PingInterval 60
+	#option PingTimeout 5
+	#option PriorityInheritance 0
+	#option PrivateKeyFile /etc/tinc/NETNAME/rsa_key.priv
+	#option ProcessPriority normal
+	#option ReplayWindow 16
+	#option StrictSubnets 0
+	#option TunnelServer 0
+	#option UDPRcvBuf x
+	#option UDPSndBuf x
+
+config tinc-host NODENAME
+	# Remove to enable
+	option disabled 1
+
+	option net NETNAME
+
+	#list Address example.com
+	#option Cipher blowfish
+	#option ClampMSS yes
+	#option Compression 0
+	#option Digest sha1
+	#option IndirectData 0
+	#option MACLength 4
+	#option PMTU 1514
+	#option PMTUDiscovery yes
+	#option Port 655
+	#option Subnet 192.168.1.0/24
diff --git a/net/tinc/files/tinc.init b/net/tinc/files/tinc.init
new file mode 100755
index 0000000..9051359
--- /dev/null
+++ b/net/tinc/files/tinc.init
@@ -0,0 +1,241 @@ 
+#!/bin/sh /etc/rc.common
+# Tinc init script
+# Copyright (C) 2011 Linus Lüssing
+#  Based on Jo-Philipp Wich's OpenVPN init script
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+START=42
+BIN=/usr/sbin/tincd
+SSD=start-stop-daemon
+EXTRA_COMMANDS="up down"
+
+LIST_SEP="
+"
+TMP_TINC="/tmp/tinc"
+
+append_param() {
+	local v="$1"
+	case "$v" in
+		*_*_*_*) v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_} ;;
+		*_*_*)   v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_} ;;
+		*_*)     v=${v%%_*}-${v#*_} ;;
+	esac
+	ARGS="$ARGS --$v"
+	return 0
+}
+
+append_conf_bools() {
+	local p; local v; local s="$1"; local f="$2"; shift; shift
+	for p in $*; do
+		config_get_bool v "$s" "$p"
+		[ "$v" == 1 ] && echo "$p = yes" >> "$f"
+		[ "$v" == 0 ] && echo "$p = no" >> "$f"
+	done
+}
+
+append_params() {
+	local p; local v; local s="$1"; shift
+	for p in $*; do
+		config_get v "$s" "$p"
+		IFS="$LIST_SEP"
+		for v in $v; do
+			[ -n "$v" ] && append_param "$p" && ARGS="$ARGS $v"
+		done
+		unset IFS
+	done
+}
+
+append_conf_params() {
+	local p; local v; local s="$1"; local f="$2"; shift; shift
+	for p in $*; do
+		config_get v "$s" "$p"
+		IFS="$LIST_SEP"
+		for v in $v; do
+			# Look up OpenWRT interface names
+			[ "$p" = "BindToInterface" ] && {
+				local ifname=$(uci -P /var/state get network.$v.ifname 2>&-)
+				[ -n "$ifname" ] && v="$ifname"
+			}
+
+			[ -n "$v" ] && echo "$p = $v" >> "$f"
+		done
+		unset IFS
+	done
+}
+
+prepare_host() {
+	local s="$1"; local n
+	local disabled=0
+
+	# net disabled?
+	config_get n "$s" net
+	config_get_bool disabled "$n" disabled 0
+	[ "$disabled" == 1 ] && return 0
+
+	if [ "$#" = "2" ]; then
+		[ "$2" != "$n" ] && return 0
+	fi
+
+	# host disabled?
+	config_get_bool disabled "$s" disabled 0
+	[ "$disabled" == 1 ] && {
+		[ -f "$TMP_TINC/$n/hosts/$s" ] && rm "$TMP_TINC/$n/hosts/$s"
+		return 0
+	}
+
+	[ ! -f "/etc/tinc/$n/hosts/$s" ] && {
+		echo -n "tinc: Warning, public key for $s for network $n "
+		echo -n "missing in /etc/tinc/$n/hosts/$s, "
+		echo "skipping configuration of $s"
+		return 0
+	}
+
+	# append flags
+	append_conf_bools "$s" "$TMP_TINC/$n/hosts/$s" \
+		ClampMSS IndirectData PMTUDiscovery
+
+	# append params
+	append_conf_params "$s" "$TMP_TINC/$n/hosts/$s" \
+		Address Cipher Compression Digest MACLength PMTU Port Subnet
+}
+
+check_gen_own_key() {
+	local s="$1"; local n; local k
+
+	config_get n "$s" Name
+	config_get_bool k "$s" generate_keys 0
+	[ "$k" == 0 ] && return 0
+
+	([ -z "$n" ] || [ -f "$TMP_TINC/$s/hosts/$n" ] || [ -f "$TMP_TINC/$s/rsa_key.priv" ]) && \
+		return 0
+	[ ! -d "$TMP_TINC/$s/hosts" ] && mkdir -p "$TMP_TINC/$s/hosts"
+
+	config_get k "$s" key_size
+	if [ -z "$k" ]; then
+		$BIN -c "$TMP_TINC/$s" --generate-keys </dev/null
+	else
+		$BIN -c "$TMP_TINC/$s" "--generate-keys=$k" </dev/null
+	fi
+
+	[ ! -d "/etc/tinc/$s/hosts" ] && mkdir -p "/etc/tinc/$s/hosts"
+	cp "$TMP_TINC/$s/rsa_key.priv" "/etc/tinc/$s/"
+	[ -n "$n" ] && cp "$TMP_TINC/$s/hosts/$n" "/etc/tinc/$s/hosts/"
+}
+
+prepare_net() {
+	local s="$1"
+	local disabled=0
+	local n
+
+	# disabled?
+	config_get_bool disabled "$s" disabled 0
+	[ "$disabled" == 1 ] && return 0
+
+	[ ! -d "$TMP_TINC/$s" ] && mkdir -p "$TMP_TINC/$s"
+	[ -d "/etc/tinc/$s" ] && cp -r "/etc/tinc/$s" "$TMP_TINC/"
+
+	# append flags
+	append_conf_bools "$s" "$TMP_TINC/$s/tinc.conf" \
+		DirectOnly Hostnames IffOneQueue PriorityInheritance \
+		StrictSubnets TunnelServer \
+		ClampMSS IndirectData PMTUDiscovery
+
+	# append params
+	append_conf_params "$s" "$TMP_TINC/$s/tinc.conf" \
+		AddressFamily BindToAddress ConnectTo BindToInterface \
+		Forwarding GraphDumpFile Interface KeyExpire MACExpire \
+		MaxTimeout Mode Name PingInterval PingTimeout PrivateKeyFile \
+		ProcessPriority ReplayWindow UDPRcvBuf UDPSndBuf \
+		Address Cipher Compression Digest MACLength PMTU Port Subnet
+
+	check_gen_own_key "$s" && return 0
+}
+
+start_net() {
+	local s="$1"
+	local disabled=0
+
+	# disabled?
+	config_get_bool disabled "$s" disabled 0
+	[ "$disabled" == 1 ] && return 0
+
+	PID="/var/run/tinc.$s.pid"
+	ARGS=""
+
+	# append params
+	append_params "$s" \
+		log debug
+
+	$BIN -c "$TMP_TINC/$s" -n $s $ARGS --pidfile="$PID"
+}
+
+kill_net() {
+	local s="$1"
+	local S="${2:-TERM}"
+	local disabled=0
+
+	# disabled?
+	config_get_bool disabled "$s" disabled 0
+	[ "$disabled" == 0 ] || [ "$S" == "TERM" ] || return 0
+
+	PID="/var/run/tinc.$s.pid"
+
+	$SSD -q -p $PID -x $BIN -K -s $S
+	[ "$S" == "TERM" ] && {
+		rm -f "$PID"
+		[ -n "$s" ] && rm -rf "$TMP_TINC/$s"
+	}
+}
+
+hup_net()  { kill_net "$1" HUP;  }
+stop_net() { kill_net "$1" TERM; }
+
+start() {
+	config_load tinc
+
+	config_foreach prepare_net tinc-net
+	config_foreach prepare_host tinc-host
+
+	config_foreach start_net tinc-net
+}
+
+stop() {
+	config_load tinc
+	config_foreach stop_net tinc-net
+}
+
+reload() {
+	config_load tinc
+	config_foreach hup_net tinc-net
+}
+
+restart() {
+	stop; sleep 5; start
+}
+
+up() {
+	local exists
+	local INSTANCE
+	config_load tinc
+	for INSTANCE in "$@"; do
+		config_get exists "$INSTANCE" TYPE
+		if [ "$exists" == "tinc-net" ]; then
+			prepare_net "$INSTANCE"
+			config_foreach prepare_host tinc-host "$INSTANCE"
+			start_net "$INSTANCE"
+		fi
+	done
+}
+
+down() {
+	local exists
+	local INSTANCE
+	config_load tinc
+	for INSTANCE in "$@"; do
+		config_get exists "$INSTANCE" TYPE
+		if [ "$exists" == "tinc-net" ]; then
+			stop_net "$INSTANCE"
+		fi
+	done
+}
diff --git a/net/tinc/files/tinc.upgrade b/net/tinc/files/tinc.upgrade
new file mode 100644
index 0000000..13f5d80
--- /dev/null
+++ b/net/tinc/files/tinc.upgrade
@@ -0,0 +1 @@ 
+/etc/tinc/