[PATCH] vpn-select/configurehood: Reorganize code to start and stop VPN
Adrian Schmutzler
freifunk at adrianschmutzler.de
Mo Feb 12 14:03:45 CET 2018
This patch is meant to tidy up the code in vpn-select and to repair
some inconveniences left over from the transfer to KeyXchangeV2.
1. VPN configuration and start/stop are separated now. This is
resonable since the configuration is now done by the hood file,
which is checked for changes elsewhere, so we call vpn-configure
only if changes are found. The start/stop however is affected by
more transient conditions like internet availability etc.
2. The code to set up general config and individual fastd/L2TP peers
has been moved to a library.
3. This patch deactivates VPN for 5 minutes if no internet is
present during the configurehood call. To disable this, just
remove the topmost /usr/sbin/vpn-stop. Regarding issue #72, both
should work, since we do not create a config if VPN is missing.
4. Tunneldigger is not started without peers like before
Behavior changes:
- This patch will destroy the previous VPN configuration if none
is given in the current hood file.
- Since vpn-configure includes the setup of L2TP peers, gateway
L2TP files are only queried during hood file-based configuration,
not every 5 minutes as before.
- VPN is disabled during the phase were a changed (!) hood file is
evaluated and config is reset.
- With the current state (no changes as suggested in 3.), no VPN
processes are running if WAN is disconnected. Config will be
present if the chosen hood supports it.
Signed-off-by: Adrian Schmutzler <freifunk at adrianschmutzler.de>
---
Dieser Patch soll nicht als Konkurrenz zu Christians Patch diskutiert
werden, sondern als Vorschlag für eine langfristigere Lösung.
In den Details gibt es sicher noch Optimierungspotential.
---
.../fff/fff-hoods/files/usr/sbin/configurehood | 12 +--
src/packages/fff/fff-vpn-select/Makefile | 2 +-
.../files/lib/functions/fff/vpn-select | 100 +++++++++++++++++++++
.../fff-vpn-select/files/usr/sbin/vpn-configure | 11 +++
.../fff/fff-vpn-select/files/usr/sbin/vpn-select | 87 ------------------
.../fff/fff-vpn-select/files/usr/sbin/vpn-start | 8 ++
.../fff/fff-vpn-select/files/usr/sbin/vpn-stop | 6 ++
7 files changed, 133 insertions(+), 93 deletions(-)
create mode 100644 src/packages/fff/fff-vpn-select/files/lib/functions/fff/vpn-select
create mode 100755 src/packages/fff/fff-vpn-select/files/usr/sbin/vpn-configure
delete mode 100755 src/packages/fff/fff-vpn-select/files/usr/sbin/vpn-select
create mode 100755 src/packages/fff/fff-vpn-select/files/usr/sbin/vpn-start
create mode 100755 src/packages/fff/fff-vpn-select/files/usr/sbin/vpn-stop
diff --git a/src/packages/fff/fff-hoods/files/usr/sbin/configurehood b/src/packages/fff/fff-hoods/files/usr/sbin/configurehood
index 90d81d1..c1c8eeb 100755
--- a/src/packages/fff/fff-hoods/files/usr/sbin/configurehood
+++ b/src/packages/fff/fff-hoods/files/usr/sbin/configurehood
@@ -85,6 +85,7 @@ else
#UPLINK: No uplink download if internet present
#if no Internet, we connect to the hidden AP and download the file from another Node in range
else
+ /usr/sbin/vpn-stop # Stop VPN processes if router has no internet
# connect to wireless hidden ap here and download the json File from the nearest router
# Only do that, when we have no gateway in range. If the Uplinkrouter changed the hood, we lost the GW and do this automatically again, I think! Nice idea?
if ! isGatewayAvailable ; then
@@ -197,6 +198,8 @@ if [ -s "$hoodfile" ]; then
if [ "$sumnew" != "$sumold" ] ; then
echo "New file detected, we reconfigure the Node";
+ /usr/sbin/vpn-stop # stop VPN during reconfiguration (so we can start again with new config)
+
json_select hood
json_get_var hood name
@@ -270,6 +273,8 @@ if [ -s "$hoodfile" ]; then
newntp="${ntpip}" # requires routable address, no link-local
[ "$newntp" = "$oldntp" ] || setTimeserver "${newntp}" # only rewrite if changed
+ /usr/sbin/vpn-configure # Configure VPN, but do not start it
+
# copy the file to webroot so that other mesh routers can download it;
# copy only after all other steps so IF can be reentered if something goes wrong
cp "$hoodfile" "$hoodfilecopy"
@@ -281,12 +286,9 @@ if [ -s "$hoodfile" ]; then
echo "We have no new file. We do nothing. We try it again in 5 minutes...";
fi
- # and now we get to vpn-select script and load VPNs directly from /tmp/keyxchangev2data
+ # Start already configured VPN if router has internet
+ hasInternet && /usr/sbin/vpn-start
- if hasInternet ; then
- sh /usr/sbin/vpn-select
- fi
-
# now we load the prefix from the hoodfile and set this to br-mesh
json_select network
json_get_var prefix ula_prefix
diff --git a/src/packages/fff/fff-vpn-select/Makefile b/src/packages/fff/fff-vpn-select/Makefile
index 4e2d89b..27cff09 100644
--- a/src/packages/fff/fff-vpn-select/Makefile
+++ b/src/packages/fff/fff-vpn-select/Makefile
@@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=fff-vpn-select
-PKG_VERSION:=1
+PKG_VERSION:=3
PKG_RELEASE:=1
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
diff --git a/src/packages/fff/fff-vpn-select/files/lib/functions/fff/vpn-select b/src/packages/fff/fff-vpn-select/files/lib/functions/fff/vpn-select
new file mode 100644
index 0000000..72022f4
--- /dev/null
+++ b/src/packages/fff/fff-vpn-select/files/lib/functions/fff/vpn-select
@@ -0,0 +1,100 @@
+#!/bin/sh
+# Copyright 2018 Adrian Schmutzler
+# License GPLv3
+
+. /lib/functions/fff/keyxchange
+. /usr/share/libubox/jshn.sh
+
+make_config() {
+ # Create VPN config
+ #
+ # Call without parameters
+
+ index_l2tp=0
+ index_json=1
+ json_load "$(cat "$hoodfile")"
+ json_select vpn
+ # get VPN peers
+ while json_select "$index_json" > /dev/null
+ do
+ json_get_var protocol protocol
+ # Current design requires "fastd" for both fastd and L2TP, decision is made by gateway
+ if [ "$protocol" == "fastd" ]; then
+ json_get_var servername name
+ json_get_var key key
+ json_get_var address address
+ json_get_var port port
+
+ if [ "l2tp" = "$(wget -T10 "${address}/vpn.txt" -O - 2>/dev/null)" ]; then
+ # Setup L2TP
+ make_l2tp "$address" "$port" "$index_l2tp"
+ index_l2tp=$((index_l2tp + 1))
+ else
+ # Setup fastd
+ make_fastd "$servername" "$address" "$port" "$key"
+ fi
+ fi
+ json_select ".." # back to vpn
+ index_json=$(( index_json + 1 ))
+ done
+ json_select ".." # back to root
+}
+
+make_fastd() {
+ # Create fastd config
+ #
+ # Syntax: make_fastd <servername> <address> <port> <key>
+
+ if [ $# -ne "4" ]
+ then
+ return 1
+ fi
+
+ local servername=$1
+ local address=$2
+ local port=$3
+ local key=$4
+
+ filename="/etc/fastd/fff/peers/$servername"
+ echo "#name \"${servername}\";" > "$filename"
+ echo "key \"${key}\";" >> "$filename"
+ echo "remote ipv4 \"${address}\" port ${port};" >> "$filename"
+ echo "" >> "$filename"
+ echo "float yes;" >> "$filename"
+
+ return 0
+}
+
+make_l2tp() {
+ # Create L2TP config
+ #
+ # Syntax: make_l2tp <address> <port> <count>
+
+ if [ $# -ne "3" ]
+ then
+ return 1
+ fi
+
+ local address=$1
+ local port=$2
+ local count=$3
+
+ # Use MAC address as hostname if not set
+ hostname="$(cat /proc/sys/kernel/hostname)"
+ [ "$hostname" = "LEDE" ] && hostname=""
+ [ "$hostname" = "" ] && hostname="$(awk '{ mac=toupper($1); gsub(":", "", mac); print mac }' /sys/class/net/br-mesh/address 2>/dev/null)"
+
+ L2PORT=$((port + 10000))
+
+ uci -q set "tunneldigger.$count=broker"
+ uci -q set "tunneldigger.$count.address=${address}:$L2PORT"
+ uci -q set "tunneldigger.$count.uuid=$hostname"
+ uci -q set "tunneldigger.$count.interface=l2tp$count"
+ uci -q set "tunneldigger.$count.enabled=1"
+ uci -q set "tunneldigger.$count.hook_script=/etc/tunneldigger/tunneldigger.hook"
+ uci -c /tmp commit tunneldigger
+
+ return 0
+}
+
+# vim: set noexpandtab:tabstop=4
diff --git a/src/packages/fff/fff-vpn-select/files/usr/sbin/vpn-configure b/src/packages/fff/fff-vpn-select/files/usr/sbin/vpn-configure
new file mode 100755
index 0000000..cb488ce
--- /dev/null
+++ b/src/packages/fff/fff-vpn-select/files/usr/sbin/vpn-configure
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+. /lib/functions/fff/vpn-select
+
+# remove old config in any case
+>/etc/config/tunneldigger
+[ ! -d /tmp/fastd_fff_peers ] && mkdir /tmp/fastd_fff_peers
+rm /tmp/fastd_fff_peers/*
+
+# Only write config if hood file is present and greater 0 byte
+[ -s "$hoodfile" ] && make_config
diff --git a/src/packages/fff/fff-vpn-select/files/usr/sbin/vpn-select b/src/packages/fff/fff-vpn-select/files/usr/sbin/vpn-select
deleted file mode 100755
index 85930a8..0000000
--- a/src/packages/fff/fff-vpn-select/files/usr/sbin/vpn-select
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/bin/sh
-
-. /lib/functions/fff/keyxchange
-. /usr/share/libubox/jshn.sh
-
-make_config() {
-# remove old config
->/etc/config/tunneldigger
-rm /tmp/fastd_fff_peers/*
-count=0
-Index=1
-json_load "$(cat "$hoodfile")"
-json_select vpn
-# get fastd peers
-while json_select "$Index" > /dev/null
-do
- json_get_var protocol protocol
- if [ "$protocol" == "fastd" ]; then
- json_get_var servername name
- filename="/etc/fastd/fff/peers/$servername"
- echo "#name \"${servername}\";" > "$filename"
- json_get_var key key
- echo "key \"${key}\";" >> "$filename"
- json_get_var address address
- json_get_var port port
- echo "remote ipv4 \"${address}\" port ${port};" >> "$filename"
- echo "" >> "$filename"
- echo "float yes;" >> "$filename"
-
- # ask for Broker and select the tunnel
- if [ "l2tp" = "$(wget -T10 "${address}/vpn.txt" -O - 2>/dev/null)" ]; then
- # Gateway offers l2tp
- L2PORT=$((port + 10000))
- UUID=$hostname
-
- uci set tunneldigger.$count=broker
- uci set tunneldigger.$count.address="${address}:$L2PORT"
- uci set tunneldigger.$count.uuid="$UUID"
- uci set tunneldigger.$count.interface="l2tp$count"
- uci set tunneldigger.$count.enabled="1"
- uci set tunneldigger.$count.hook_script='/etc/tunneldigger/tunneldigger.hook'
- uci -c /tmp commit tunneldigger
- count=$((count + 1))
- # remove this fastd-peer
- rm "$filename"
- fi
- fi
- json_select ".." # back to vpn
- Index=$(( Index + 1 ))
-done
-json_select ".." # back to root
-}
-
-# main
-
-# Only do something when file is here and greater 0 byte
-if [ -s "$hoodfile" ]; then
- # set some vars
- hostname=$(cat /proc/sys/kernel/hostname)
- mac=$(awk '{ mac=toupper($1); gsub(":", "", mac); print mac }' /sys/class/net/br-mesh/address 2>/dev/null)
- [ "$hostname" = "LEDE" ] && hostname=""
- [ "$hostname" = "" ] && hostname="$mac"
-
- if [ ! -d /tmp/fastd_fff_peers ]; then
- # first run after reboot
- mkdir /tmp/fastd_fff_peers
- make_config
- # start fastd only if there are some peers left
- [ "$(ls /etc/fastd/fff/peers/* 2>/dev/null)" ] && /etc/init.d/fastd start
- /etc/init.d/tunneldigger start
- else
- # check if new tunneldigger conf is different
- sumold=$(sha256sum /etc/config/tunneldigger)
- make_config
- sumnew=$(sha256sum /etc/config/tunneldigger)
- [ "$sumnew" != "$sumold" ] && /etc/init.d/tunneldigger restart
- /etc/init.d/fastd reload
-
- # fastd start/stop for various situations
- pidfile="/tmp/run/fastd.fff.pid"
- if [ "$(ls /etc/fastd/fff/peers/* 2>/dev/null)" ]; then
- ([ -s "$pidfile" ] && [ -d "/proc/$(cat "$pidfile")" ]) || /etc/init.d/fastd start
- else
- ([ -s "$pidfile" ] && [ -d "/proc/$(cat "$pidfile")" ]) && /etc/init.d/fastd stop
- fi
- fi
-fi
diff --git a/src/packages/fff/fff-vpn-select/files/usr/sbin/vpn-start b/src/packages/fff/fff-vpn-select/files/usr/sbin/vpn-start
new file mode 100755
index 0000000..592b871
--- /dev/null
+++ b/src/packages/fff/fff-vpn-select/files/usr/sbin/vpn-start
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+if [ "$(ls /etc/fastd/fff/peers/* 2>/dev/null)" ] ; then
+ pidfile="/tmp/run/fastd.fff.pid"
+ ([ -s "$pidfile" ] && [ -d "/proc/$(cat "$pidfile")" ]) || /etc/init.d/fastd start
+fi
+
+uci -q get tunneldigger. at broker[0] > /dev/null && /etc/init.d/tunneldigger start
diff --git a/src/packages/fff/fff-vpn-select/files/usr/sbin/vpn-stop b/src/packages/fff/fff-vpn-select/files/usr/sbin/vpn-stop
new file mode 100755
index 0000000..f931d7e
--- /dev/null
+++ b/src/packages/fff/fff-vpn-select/files/usr/sbin/vpn-stop
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+/etc/init.d/tunneldigger stop
+
+pidfile="/tmp/run/fastd.fff.pid"
+([ -s "$pidfile" ] && [ -d "/proc/$(cat "$pidfile")" ]) && /etc/init.d/fastd stop
--
2.7.4
Mehr Informationen über die Mailingliste franken-dev