fix(wg): harden clusev-wg.sh — read EOF, awk ENVIRON, endpoint + wg.env guards (review)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>feat/v1-foundation
parent
dd964a2e8b
commit
8caa78b2b3
|
|
@ -95,6 +95,7 @@ cmd_down() {
|
||||||
next_free_ip() {
|
next_free_ip() {
|
||||||
# shellcheck disable=SC1090
|
# shellcheck disable=SC1090
|
||||||
. "$WG_ENV"
|
. "$WG_ENV"
|
||||||
|
[ -n "${WG_SUBNET:-}" ] || die "WG_SUBNET fehlt in ${WG_ENV} — Setup erneut ausfuehren."
|
||||||
local prefix="${WG_SUBNET%%/*}"; prefix="${prefix%.*}" # first three octets (SP1: /24)
|
local prefix="${WG_SUBNET%%/*}"; prefix="${prefix%.*}" # first three octets (SP1: /24)
|
||||||
local used; used="$(awk -F= '/AllowedIPs/{gsub(/[ \t]/,"",$2);split($2,a,"/");print a[1]}' "$WG_CONF" 2>/dev/null || true)"
|
local used; used="$(awk -F= '/AllowedIPs/{gsub(/[ \t]/,"",$2);split($2,a,"/");print a[1]}' "$WG_CONF" 2>/dev/null || true)"
|
||||||
used="$(printf '%s\n%s\n' "$used" "${WG_SERVER_IP:-}")"
|
used="$(printf '%s\n%s\n' "$used" "${WG_SERVER_IP:-}")"
|
||||||
|
|
@ -112,6 +113,7 @@ cmd_add_peer() {
|
||||||
require_setup
|
require_setup
|
||||||
# shellcheck disable=SC1090
|
# shellcheck disable=SC1090
|
||||||
. "$WG_ENV"
|
. "$WG_ENV"
|
||||||
|
[ -n "${WG_SUBNET:-}" ] && [ -n "${WG_SERVER_PUBKEY:-}" ] && [ -n "${WG_ENDPOINT:-}" ] || die "wg.env unvollstaendig — Setup erneut ausfuehren."
|
||||||
grep -qF "# clusev-peer: ${name}" "$WG_CONF" 2>/dev/null && die "Peer '${name}' existiert bereits."
|
grep -qF "# clusev-peer: ${name}" "$WG_CONF" 2>/dev/null && die "Peer '${name}' existiert bereits."
|
||||||
local ip; ip="$(next_free_ip)" || die "Kein freier Adressraum im Subnetz ${WG_SUBNET}."
|
local ip; ip="$(next_free_ip)" || die "Kein freier Adressraum im Subnetz ${WG_SUBNET}."
|
||||||
local cpriv cpub
|
local cpriv cpub
|
||||||
|
|
@ -155,13 +157,13 @@ cmd_remove_peer() {
|
||||||
local name="${1:-}"; [ -n "$name" ] || die "Name fehlt: clusev wg remove-peer <name>"
|
local name="${1:-}"; [ -n "$name" ] || die "Name fehlt: clusev wg remove-peer <name>"
|
||||||
require_setup
|
require_setup
|
||||||
local pub
|
local pub
|
||||||
pub="$(awk -v n="# clusev-peer: ${name}" '$0==n{f=1;next} f&&/PublicKey/{gsub(/[ \t]/,"");sub(/PublicKey=/,"");print;exit}' "$WG_CONF")"
|
pub="$(WANT="# clusev-peer: ${name}" awk '$0==ENVIRON["WANT"]{f=1;next} f&&/PublicKey/{gsub(/[ \t]/,"");sub(/PublicKey=/,"");print;exit}' "$WG_CONF")"
|
||||||
[ -n "$pub" ] || die "Peer '${name}' nicht gefunden."
|
[ -n "$pub" ] || die "Peer '${name}' nicht gefunden."
|
||||||
wg set "$WG_IF" peer "$pub" remove 2>/dev/null || true
|
wg set "$WG_IF" peer "$pub" remove 2>/dev/null || true
|
||||||
# drop the block from the marker comment up to (and including) the trailing blank line
|
# drop the block from the marker comment up to (and including) the trailing blank line
|
||||||
local tmp; tmp="$(mktemp)"
|
local tmp; tmp="$(mktemp)"
|
||||||
awk -v n="# clusev-peer: ${name}" '
|
WANT="# clusev-peer: ${name}" awk '
|
||||||
$0==n {drop=1; next}
|
$0==ENVIRON["WANT"] {drop=1; next}
|
||||||
drop && /^[[:space:]]*$/ {drop=0; next}
|
drop && /^[[:space:]]*$/ {drop=0; next}
|
||||||
drop {next}
|
drop {next}
|
||||||
{print}
|
{print}
|
||||||
|
|
@ -188,26 +190,40 @@ cmd_setup() {
|
||||||
have wg || die "wireguard-tools nicht installiert (erwartet via install.sh)."
|
have wg || die "wireguard-tools nicht installiert (erwartet via install.sh)."
|
||||||
if [ -f "$WG_CONF" ]; then
|
if [ -f "$WG_CONF" ]; then
|
||||||
warn "${WG_CONF} existiert bereits — bestehende Peers gingen bei Neukonfiguration verloren."
|
warn "${WG_CONF} existiert bereits — bestehende Peers gingen bei Neukonfiguration verloren."
|
||||||
read -rp " Trotzdem neu konfigurieren? [reconfigure/abort] (abort): " ans
|
read -rp " Trotzdem neu konfigurieren? [reconfigure/abort] (abort): " ans || ans=abort
|
||||||
[ "${ans:-abort}" = "reconfigure" ] || die "Abgebrochen — bestehende Konfiguration unberuehrt."
|
[ "${ans:-abort}" = "reconfigure" ] || die "Abgebrochen — bestehende Konfiguration unberuehrt."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local subnet default_subnet="10.99.0.0/24"
|
local subnet default_subnet="10.99.0.0/24"
|
||||||
while :; do
|
while :; do
|
||||||
read -rp " WG-Subnetz (privates /24, darf NICHT mit LAN/VPN kollidieren) [${default_subnet}]: " subnet
|
if ! read -rp " WG-Subnetz (privates /24, darf NICHT mit LAN/VPN kollidieren) [${default_subnet}]: " subnet; then
|
||||||
|
subnet="$default_subnet" # closed stdin → take the default once
|
||||||
|
fi
|
||||||
subnet="${subnet:-$default_subnet}"
|
subnet="${subnet:-$default_subnet}"
|
||||||
if subnet_collides "$subnet"; then warn "Subnetz ${subnet} ueberschneidet eine bestehende Route/Adresse — bitte ein anderes waehlen."; continue; fi
|
if subnet_collides "$subnet"; then
|
||||||
|
warn "Subnetz ${subnet} ueberschneidet eine bestehende Route/Adresse — bitte ein anderes waehlen."
|
||||||
|
[ -t 0 ] || die "Subnetz-Kollision und keine interaktive Eingabe moeglich (stdin geschlossen)."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
break
|
break
|
||||||
done
|
done
|
||||||
|
|
||||||
local server_ip default_ip port endpoint default_ep peer1
|
local server_ip default_ip port endpoint peer1
|
||||||
default_ip="$(subnet_first_ip "$subnet")"
|
default_ip="$(subnet_first_ip "$subnet")"
|
||||||
read -rp " Server-Tunnel-IP [${default_ip}]: " server_ip; server_ip="${server_ip:-$default_ip}"
|
read -rp " Server-Tunnel-IP [${default_ip}]: " server_ip || true; server_ip="${server_ip:-$default_ip}"
|
||||||
read -rp " Listen-Port (UDP) [51820]: " port; port="${port:-51820}"
|
read -rp " Listen-Port (UDP) [51820]: " port || true; port="${port:-51820}"
|
||||||
default_ep="$(detect_endpoint_ip):${port}"
|
local ep; ep="$(detect_endpoint_ip)"
|
||||||
info "Hinweis: hinter NAT/Cloud-LB ist die erkannte IP evtl. NICHT die Waehl-Adresse der Clients — vor 'clusev wg up' pruefen."
|
if [ -n "$ep" ]; then
|
||||||
read -rp " Oeffentlicher Endpoint (IP oder DNS:Port) [${default_ep}]: " endpoint; endpoint="${endpoint:-$default_ep}"
|
local default_ep="${ep}:${port}"
|
||||||
read -rp " Name des ersten Peers [client-1]: " peer1; peer1="${peer1:-client-1}"
|
info "Hinweis: hinter NAT/Cloud-LB ist die erkannte IP evtl. NICHT die Waehl-Adresse der Clients — vor 'clusev wg up' pruefen."
|
||||||
|
read -rp " Oeffentlicher Endpoint (IP oder DNS:Port) [${default_ep}]: " endpoint || true
|
||||||
|
endpoint="${endpoint:-$default_ep}"
|
||||||
|
else
|
||||||
|
warn "Oeffentliche IP konnte nicht erkannt werden — bitte Endpoint manuell angeben."
|
||||||
|
read -rp " Oeffentlicher Endpoint (IP oder DNS:Port, erforderlich): " endpoint || true
|
||||||
|
fi
|
||||||
|
[ -n "$endpoint" ] || die "Endpoint erforderlich."
|
||||||
|
read -rp " Name des ersten Peers [client-1]: " peer1 || true; peer1="${peer1:-client-1}"
|
||||||
|
|
||||||
umask 077; mkdir -p "$WG_DIR" "$STATE_DIR"
|
umask 077; mkdir -p "$WG_DIR" "$STATE_DIR"
|
||||||
local srv_priv srv_pub prefix
|
local srv_priv srv_pub prefix
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue