|
| 1 | +#!/usr/bin/env bash |
| 2 | +# Fetch WireGuard config from Netmaker via /api/v1/client_conf/{network} and bring it up. |
| 3 | +# Required env: |
| 4 | +# NETMAKER_BASE_URL, NETMAKER_API_JWT, NETMAKER_NETWORK |
| 5 | +# WG_IFACE (default: netmaker), WG_CONF_DIR (default: /etc/wireguard) |
| 6 | + |
| 7 | +set -euo pipefail |
| 8 | + |
| 9 | +# --- Fail fast if mandatory variables missing --- |
| 10 | +: "${NETMAKER_BASE_URL:?ERROR: NETMAKER_BASE_URL not set}" |
| 11 | +: "${NETMAKER_NETWORK:?ERROR: NETMAKER_NETWORK not set}" |
| 12 | +: "${NETMAKER_API_JWT:?ERROR: NETMAKER_API_JWT not set}" |
| 13 | + |
| 14 | +# --- Ensure required packages are present --- |
| 15 | +echo "[*] Checking dependencies ..." |
| 16 | +DEPS=(curl jq wg-quick ip) |
| 17 | +MISSING=() |
| 18 | +for bin in "${DEPS[@]}"; do |
| 19 | + if ! command -v "$bin" >/dev/null 2>&1; then |
| 20 | + MISSING+=("$bin") |
| 21 | + fi |
| 22 | +done |
| 23 | + |
| 24 | +if [[ ${#MISSING[@]} -gt 0 ]]; then |
| 25 | + echo "[*] Installing missing deps: ${MISSING[*]} ..." |
| 26 | + if command -v apt-get >/dev/null 2>&1; then |
| 27 | + sudo apt-get update -y |
| 28 | + sudo apt-get install -y wireguard-tools jq curl iproute2 resolvconf |
| 29 | + elif command -v yum >/dev/null 2>&1; then |
| 30 | + sudo yum install -y wireguard-tools jq curl iproute iproute-tc |
| 31 | + elif command -v dnf >/dev/null 2>&1; then |
| 32 | + sudo dnf install -y wireguard-tools jq curl iproute |
| 33 | + else |
| 34 | + echo "ERROR: Package manager not found. Install ${MISSING[*]} manually." >&2 |
| 35 | + exit 1 |
| 36 | + fi |
| 37 | +else |
| 38 | + echo "[*] All dependencies found." |
| 39 | +fi |
| 40 | + |
| 41 | +# --- Inputs & defaults --- |
| 42 | +BASE_URL="${NETMAKER_BASE_URL:?NETMAKER_BASE_URL not set}" |
| 43 | +NETWORK="${NETMAKER_NETWORK:?NETMAKER_NETWORK not set}" |
| 44 | +JWT="${NETMAKER_API_JWT:?NETMAKER_API_JWT not set}" |
| 45 | +WG_IFACE="${WG_IFACE:-netmaker}" |
| 46 | +WG_CONF_DIR="${WG_CONF_DIR:-/etc/wireguard}" |
| 47 | +TMP_CONF="/tmp/${WG_IFACE}.conf" |
| 48 | + |
| 49 | +EP="${BASE_URL}/api/v1/client_conf/${NETWORK}" |
| 50 | + |
| 51 | +echo "[*] Requesting client configuration from: ${EP}" |
| 52 | + |
| 53 | +HDRS=(-H "Authorization: Bearer ${JWT}") |
| 54 | +[[ -n "${NM_CLIENT_LABEL:-}" ]] && HDRS+=(-H "X-NM-Client-Label: ${NM_CLIENT_LABEL}") |
| 55 | +[[ -n "${NM_REQUESTED_NAME:-}" ]] && HDRS+=(-H "X-NM-Requested-Name: ${NM_REQUESTED_NAME}") |
| 56 | + |
| 57 | +# --- Fetch config --- |
| 58 | +HTTP_STATUS="$(curl -sS -L -w '%{http_code}' -o "${TMP_CONF}" "${HDRS[@]}" "${EP}")" |
| 59 | + |
| 60 | +if [[ "${HTTP_STATUS}" != "200" ]]; then |
| 61 | + echo "ERROR: client_conf returned HTTP ${HTTP_STATUS}" >&2 |
| 62 | + curl -sS -L "${HDRS[@]}" "${EP}" | head -c 400 >&2 || true |
| 63 | + exit 1 |
| 64 | +fi |
| 65 | + |
| 66 | +# --- Sanity check --- |
| 67 | +if ! grep -q "^\[Interface\]" "${TMP_CONF}"; then |
| 68 | + echo "ERROR: Response does not look like a WireGuard config." >&2 |
| 69 | + head -n 20 "${TMP_CONF}" >&2 || true |
| 70 | + exit 1 |
| 71 | +fi |
| 72 | + |
| 73 | +# --- Add interface-name for traceability --- |
| 74 | +if ! grep -q "^#interface-name=" "${TMP_CONF}"; then |
| 75 | + echo "#interface-name=${WG_IFACE}" | cat - "${TMP_CONF}" > "${TMP_CONF}.tmp" && mv "${TMP_CONF}.tmp" "${TMP_CONF}" |
| 76 | +fi |
| 77 | + |
| 78 | +# --- Move into place --- |
| 79 | +sudo mkdir -p "${WG_CONF_DIR}" |
| 80 | +sudo mv "${TMP_CONF}" "${WG_CONF_DIR}/${WG_IFACE}.conf" |
| 81 | +sudo chmod 600 "${WG_CONF_DIR}/${WG_IFACE}.conf" |
| 82 | + |
| 83 | +# --- Bring it up --- |
| 84 | +echo "[*] Bringing up ${WG_IFACE} ..." |
| 85 | +sudo wg-quick up "${WG_IFACE}" |
| 86 | + |
| 87 | +echo "==== ${WG_IFACE} is up ====" |
| 88 | +ip addr show "${WG_IFACE}" || true |
| 89 | +wg show "${WG_IFACE}" || true |
0 commit comments