#!/bin/bash # WireGuard install hooks — host-conflict guard, tunnel subnet generation, # WG_HOST resolution, IP forwarding setup, and a post-start restart so # the firewall rules from wg-easy take effect cleanly. wireguard_install_pre() { local app_name="$1" ((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 [[ -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 } wireguard_install_post_compose() { local app_name="$1" ((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 )) local _wg_third=$(( RANDOM % 256 )) 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 `.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 result=$(runAppCfg wireguard-ip-forward) checkSuccess "Enabling IPv4 IP Forwarding (sysctl drop-in + reload)" } wireguard_install_post_start() { local app_name="$1" ((menu_number++)) echo "" echo "---- $menu_number. Restarting $app_name after firewall changes" echo "" dockerComposeRestart $app_name }