From: Michael Tremer Date: Fri, 6 Dec 2024 16:12:16 +0000 (+0100) Subject: wireguard: Install wg-dynamic X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a6568d122d85d447805aa137c68a541c641b3516;p=ipfire-2.x.git wireguard: Install wg-dynamic This is a script that checks if we are connected with the correct peer. Signed-off-by: Michael Tremer --- diff --git a/config/rootfiles/common/wireguard-tools b/config/rootfiles/common/wireguard-tools index f21db9aae..46225828d 100644 --- a/config/rootfiles/common/wireguard-tools +++ b/config/rootfiles/common/wireguard-tools @@ -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 index 000000000..d67abbca2 --- /dev/null +++ b/config/wireguard/wg-dynamic @@ -0,0 +1,122 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2024 Michael Tremer # +# # +# 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 . # +# # +############################################################################### +# # +# 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 $? diff --git a/lfs/wireguard-tools b/lfs/wireguard-tools index 31fc57553..5d0e82094 100644 --- a/lfs/wireguard-tools +++ b/lfs/wireguard-tools @@ -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)