librelad 763092a278 fix(wireguard): move /etc IP-forward edit into libreportal-appcfg
The standalone WireGuard install used to flip net.ipv4.ip_forward by
appending+uncommenting `/etc/sysctl/99-custom.conf` via blanket sudo
(sudo tee, sudo sed, sudo sysctl -p). Two problems with that on a
de-sudoed manager:
  - The path is non-standard. The conventional location is
    /etc/sysctl.d/*.conf (drop-ins, loaded by sysctl --system) — the
    old file may not even exist, leaving forwarding silently off.
  - `sudo tee /etc` and `sudo sed -i /etc` are not in LP_SYSTEM. The
    manager has lost the broad sudo it once had, so this would now
    fail outright on every wireguard install.

Add a `wireguard-ip-forward` action to libreportal-appcfg that:
  - writes /etc/sysctl.d/99-libreportal-wireguard.conf (a drop-in we
    own and rewrite idempotently), and
  - reloads via `sysctl --system` (with a `sysctl -p <dropin>` fallback).

containers/wireguard/wireguard.sh now calls `runAppCfg wireguard-ip-forward`
through the existing helper-dispatch path — the whole edit runs as root
in one validated step, no `sudo` in the per-app script.

Same de-sudo pattern as adguard-auth / crowdsec-priority / owncloud-config
already use.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-26 17:48:43 +01:00

202 lines
6.5 KiB
Bash
Executable File

#!/bin/bash
# Category : Networking
# Description : Wireguard Easy - VPN Server (c/u/s/r/i):
installWireguard()
{
local config_variables="$1"
if [[ "$wireguard" == *[cCtTuUsSrRiI]* ]]; then
dockerConfigSetupToContainer silent wireguard;
local app_name=$CFG_WIREGUARD_APP_NAME
initializeAppVariables $app_name;
fi
if [[ "$wireguard" == *[cC]* ]]; then
editAppConfig $app_name;
fi
if [[ "$wireguard" == *[uU]* ]]; then
dockerUninstallApp $app_name;
fi
if [[ "$wireguard" == *[sS]* ]]; then
dockerComposeDown $app_name;
fi
if [[ "$wireguard" == *[rR]* ]]; then
dockerComposeRestart $app_name;
fi
if [[ "$wireguard" == *[iI]* ]]; then
isHeader "Install $app_name"
((menu_number++))
echo ""
echo "---- $menu_number. Checking if $app_name can be installed."
echo ""
# Host-conflict guard: a host-level WireGuard (e.g. the angristan
# wireguard-install script — marker /etc/wireguard/params) collides with
# this container on the wg kernel module + UDP 51820. Abort if present.
if [[ -e /etc/wireguard/params ]]; then
isError "WireGuard is already installed on the host — this conflicts with the $app_name app."
isError "Installation is now aborting..."
dockerUninstallApp "$app_name"
return 1
fi
((menu_number++))
echo ""
echo "---- $menu_number. Setting up install folder and config file for $app_name."
echo ""
dockerConfigSetupToContainer "loud" "$app_name" "install" "$config_variables";
isSuccessful "Install folders and Config files have been setup for $app_name."
((menu_number++))
echo ""
((menu_number++))
echo ""
echo "---- $menu_number. Setting up the $app_name docker-compose.yml file."
echo ""
dockerComposeSetupFile $app_name;
monitoringToggleAppConfig "$app_name" "docker-compose.yml";
((menu_number++))
echo ""
echo "---- $menu_number. Resolving wireguard tunnel subnet (WG_DEFAULT_ADDRESS)"
echo ""
# Generate-once-and-persist tunnel subnet. Second-octet 200-250 is
# outside the docker network generator range (100-149), so the two
# subnets cannot collide. Reusing the persisted value keeps existing
# peer configs valid across reinstalls.
local _wg_compose_for_subnet="$containers_dir$app_name/docker-compose.yml"
if [[ -z "$CFG_WIREGUARD_SUBNET" ]]; then
local _wg_second=$(( RANDOM % 51 + 200 )) # 200-250
local _wg_third=$(( RANDOM % 256 )) # 0-255
CFG_WIREGUARD_SUBNET="10.${_wg_second}.${_wg_third}.0"
updateConfigOption "CFG_WIREGUARD_SUBNET" "$CFG_WIREGUARD_SUBNET"
isSuccessful "Generated wireguard tunnel subnet: $CFG_WIREGUARD_SUBNET"
else
isNotice "Reusing existing wireguard tunnel subnet: $CFG_WIREGUARD_SUBNET"
fi
# wg-easy expects the address pattern `<base>.x` (literal x).
local _wg_addr_pattern="${CFG_WIREGUARD_SUBNET%.0}.x"
tagsManagerUpdateUniversalTag "$_wg_compose_for_subnet" "WIREGUARD_SUBNET_TAG" "$_wg_addr_pattern"
isSuccessful "WG_DEFAULT_ADDRESS set to $_wg_addr_pattern"
((menu_number++))
echo ""
echo "---- $menu_number. Resolving WG_HOST for peer configs"
echo ""
local wg_compose_file="$containers_dir$app_name/docker-compose.yml"
local wg_host_value=""
local _wg_traefik_installed=0
if declare -f checkServiceInstalled >/dev/null 2>&1 && checkServiceInstalled "traefik"; then
_wg_traefik_installed=1
fi
if [[ -n "$domain_full" && $_wg_traefik_installed -eq 1 ]]; then
wg_host_value="$host_setup"
isNotice "Domain + Traefik present — peer configs will use $wg_host_value"
else
wg_host_value="${public_ip_v4:-127.0.0.1}"
if [[ -n "$domain_full" && $_wg_traefik_installed -eq 0 ]]; then
isNotice "Domain configured but Traefik not installed — falling back to IP $wg_host_value so peer configs actually resolve."
else
isNotice "No domain configured — peer configs will use IP $wg_host_value (LAN only)"
fi
fi
tagsManagerUpdateUniversalTag "$wg_compose_file" "PUBLIC_IP_TAG" "$wg_host_value"
isSuccessful "WG_HOST set to $wg_host_value"
((menu_number++))
echo ""
echo "---- $menu_number. Enabling IP forwarding"
echo ""
# Drop in /etc/sysctl.d/99-libreportal-wireguard.conf + reload — the
# whole thing runs as root through libreportal-appcfg so the manager
# never needs blanket /etc write or `sudo sysctl` itself.
local result=$(runAppCfg wireguard-ip-forward)
checkSuccess "Enabling IPv4 IP Forwarding (sysctl drop-in + reload)"
((menu_number++))
echo ""
echo "---- $menu_number. Updating file permissions before starting."
echo ""
fixPermissionsBeforeStart $app_name;
((menu_number++))
echo ""
echo "---- $menu_number. Running the docker-compose.yml to Install $app_name"
echo ""
dockerComposeUpdateAndStartApp $app_name install;
((menu_number++))
echo ""
echo "---- $menu_number. Restarting $app_name after firewall changes"
echo ""
dockerComposeRestart $app_name;
((menu_number++))
echo ""
echo "---- $menu_number. Running Application specific updates (if required)"
echo ""
appUpdateSpecifics $app_name;
((menu_number++))
echo ""
echo "---- $menu_number. Running Headscale setup (if required)"
echo ""
setupHeadscale $app_name;
((menu_number++))
echo ""
echo "---- $menu_number. Adding $app_name to the Apps Database table."
echo ""
databaseInstallApp $app_name;
((menu_number++))
echo ""
echo "---- $menu_number. Updating WebUI config file."
echo ""
webuiContainerSetup $app_name install;
((menu_number++))
echo ""
echo "---- $menu_number. Refreshing monitoring integration."
echo ""
monitoringRefreshAll;
((menu_number++))
echo ""
echo "---- $menu_number. You can find $app_name files at $containers_dir$app_name"
echo ""
echo " You can now navigate to your $app_name service using any of the options below : "
echo ""
menuShowFinalMessages $app_name;
menu_number=0
#sleep 3s
cd
fi
wireguard=n
}