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>
202 lines
6.5 KiB
Bash
Executable File
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
|
|
}
|