]> git.ipfire.org Git - people/ms/ipfire-2.x.git/commitdiff
wireguard: Install wg-dynamic
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 6 Dec 2024 16:12:16 +0000 (17:12 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 22 Apr 2025 14:48:53 +0000 (16:48 +0200)
This is a script that checks if we are connected with the correct peer.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
config/rootfiles/common/wireguard-tools
config/wireguard/wg-dynamic [new file with mode: 0644]
lfs/wireguard-tools

index f21db9aae62a5b1e7223cd4bbf1418eed43d9c0e..46225828d76efd0bc1aa4909ed46e1b2117eb71a 100644 (file)
@@ -1,3 +1,4 @@
+etc/fcron.cyclic/wg-dynamic
 usr/bin/wg
 #usr/share/bash-completion/completions/wg
 #usr/share/man/man8/wg.8
diff --git a/config/wireguard/wg-dynamic b/config/wireguard/wg-dynamic
new file mode 100644 (file)
index 0000000..d67abbc
--- /dev/null
@@ -0,0 +1,122 @@
+#!/bin/bash
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2024 Michael Tremer <michael.tremer@ipfire.org>               #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+#                                                                             #
+# This script tries to keep WireGuard connections with dynamic peers alive    #
+#                                                                             #
+# It resolves the endpoint if it is an FQDN, and if so, will check if the     #
+# currently connected endpoint matches any of the resolved IP addresses. If   #
+# not it will reload the WireGuard configuration in the hope that wg will     #
+# update the kernel with the new IP address and the connection comes back up  #
+# again.                                                                      #
+#                                                                             #
+###############################################################################
+
+. /etc/sysconfig/rc
+. ${rc_functions}
+
+# Fetches the first endpoint that is currently active on the given interface
+current_endpoint() {
+       local intf="${1}"
+
+       local pubkey
+       local endpoint
+
+       # List the first endpoint (are there even more than one?)
+       wg show "${intf}" endpoints | while read -r pubkey endpoint; do
+               echo "${endpoint%:*}"
+               break
+       done
+
+       return 0
+}
+
+# Resolves a hostname
+resolve() {
+       local endpoint="${1}"
+
+       dig +short "A" "${endpoint}" 2>/dev/null
+}
+
+main() {
+       local -A settings=()
+
+       # Read WireGuard settings
+       readhash settings /var/ipfire/wireguard/settings
+
+       # Do nothing if WireGuard is not enabled
+       if [ "${settings[ENABLED]}" != "on" ]; then
+               return 0
+       fi
+
+       local line
+       while IFS=',' read -r -a line; do
+               local id="${line[0]}"
+               local enabled="${line[1]}"
+               local type="${line[2]}"
+               local name="${line[3]}"
+               local endpoint="${line[7]}"
+
+               # Only process enabled net-to-net connections
+               case "${enabled},${type}" in
+                       on,net)
+                               ;;
+                       *)
+                               continue
+                               ;;
+               esac
+
+               # The endpoint must be an FQDN
+               case "${endpoint}" in
+                       # Ignore IP addresses
+                       [0-9]*.[0-9]*.[0-9]*.[0-9]*)
+                               continue
+                               ;;
+
+                       # Ignore if we don't know the endpoint
+                       "")
+                               continue
+                               ;;
+               esac
+
+               local address
+               local match=0
+
+               # Fetch the current endpoint address
+               local current_address="$(current_endpoint "wg${id}")"
+
+               # Walk through all IP addresses the FQDN resolves to
+               for address in $(resolve "${endpoint}"); do
+                       if [ "${current_address}" = "${address}" ]; then
+                               match=1
+                               break
+                       fi
+               done
+
+               # If there has been no match, we have to reload everything
+               if [ "${match}" -eq 0 ]; then
+                       exec /etc/init.d/wireguard reload
+               fi
+       done < /var/ipfire/wireguard/peers
+
+       return 0
+}
+
+main "$@" || exit $?
index 31fc575531eaee767f0f7a436bd43fb113f702a4..5d0e820941740ebba4a631b7c0e9b920d94f1e6d 100644 (file)
@@ -75,5 +75,10 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
        @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar axf $(DIR_DL)/$(DL_FILE)
        cd $(DIR_APP)/src && make $(MAKETUNING)
        cd $(DIR_APP)/src && make install
+
+       # Install wg-dynamic
+       install -v -m 755 $(DIR_SRC)/config/wireguard/wg-dynamic \
+               /etc/fcron.cyclic/wg-dynamic
+
        @rm -rf $(DIR_APP)
        @$(POSTBUILD)