Expand README with desktop platform requirements (Windows x86, macOS ARM), helper build commands, gateway utility scripts, and updated local test flow. Add realistic MVP usage section clarifying current platform build status, gateway configuration needs, and admin debug profile behavior with client private key handling.
105 lines
3.1 KiB
Bash
105 lines
3.1 KiB
Bash
#!/usr/bin/env bash
|
|
set -eu
|
|
|
|
echo "NexaVPN gateway helper starting"
|
|
mkdir -p /var/lib/nexavpn
|
|
|
|
IFACE="${NEXAVPN_GATEWAY_INTERFACE:-wg0}"
|
|
UPLINK_IFACE="${NEXAVPN_UPLINK_INTERFACE:-eth0}"
|
|
ENABLE_MASQUERADE="${NEXAVPN_ENABLE_MASQUERADE:-true}"
|
|
|
|
if [ -z "${NEXAVPN_GATEWAY_ID:-}" ] || [ -z "${NEXAVPN_API_TOKEN:-}" ] || [ -z "${NEXAVPN_GATEWAY_PRIVATE_KEY:-}" ]; then
|
|
echo "Gateway sync is not configured yet."
|
|
echo "Set NEXAVPN_GATEWAY_ID, NEXAVPN_API_TOKEN and NEXAVPN_GATEWAY_PRIVATE_KEY."
|
|
echo "Gateway apply state will be written to /var/lib/nexavpn when configured."
|
|
tail -f /dev/null
|
|
exit 0
|
|
fi
|
|
|
|
SYNC_URL="${NEXAVPN_GATEWAY_SYNC_URL}/${NEXAVPN_GATEWAY_ID}/sync"
|
|
STATE_JSON="/var/lib/nexavpn/sync-bundle.json"
|
|
WG_CONF="/etc/wireguard/${IFACE}.conf"
|
|
WG_GENERATED="/var/lib/nexavpn/${IFACE}.generated.conf"
|
|
NFT_CONF="/var/lib/nexavpn/nftables.generated.conf"
|
|
|
|
mkdir -p /etc/wireguard
|
|
|
|
apply_bundle() {
|
|
echo "Fetching bundle from ${SYNC_URL}"
|
|
curl -fsSL \
|
|
-H "Authorization: Bearer ${NEXAVPN_API_TOKEN}" \
|
|
"${SYNC_URL}" \
|
|
-o "${STATE_JSON}"
|
|
|
|
INTERFACE_ADDRESS=$(jq -r '.interface.address' "${STATE_JSON}")
|
|
NETWORK_CIDR=$(jq -r '.interface.network_cidr' "${STATE_JSON}")
|
|
LISTEN_PORT=$(jq -r '.interface.listen_port' "${STATE_JSON}")
|
|
|
|
cat > "${WG_GENERATED}" <<EOF
|
|
[Interface]
|
|
Address = ${INTERFACE_ADDRESS}
|
|
ListenPort = ${LISTEN_PORT}
|
|
PrivateKey = ${NEXAVPN_GATEWAY_PRIVATE_KEY}
|
|
|
|
EOF
|
|
|
|
jq -c '.peers[]?' "${STATE_JSON}" | while read -r peer; do
|
|
PUBLIC_KEY=$(printf '%s' "${peer}" | jq -r '.public_key')
|
|
ASSIGNED_IP=$(printf '%s' "${peer}" | jq -r '.assigned_ip')
|
|
|
|
cat >> "${WG_GENERATED}" <<EOF
|
|
[Peer]
|
|
PublicKey = ${PUBLIC_KEY}
|
|
AllowedIPs = ${ASSIGNED_IP}
|
|
|
|
EOF
|
|
done
|
|
|
|
cp "${WG_GENERATED}" "${WG_CONF}"
|
|
|
|
{
|
|
echo "flush ruleset"
|
|
echo "table inet nexavpn {"
|
|
echo " chain forward {"
|
|
echo " type filter hook forward priority 0;"
|
|
echo " policy drop;"
|
|
echo " ct state established,related accept"
|
|
echo " iifname \"${IFACE}\" ip saddr ${NETWORK_CIDR} oifname \"${UPLINK_IFACE}\" accept"
|
|
|
|
jq -c '.peers[]?' "${STATE_JSON}" | while read -r peer; do
|
|
ASSIGNED_IP=$(printf '%s' "${peer}" | jq -r '.assigned_ip')
|
|
printf '%s' "${peer}" | jq -r '.allowed_destinations[]?' | while read -r destination; do
|
|
echo " iifname \"${IFACE}\" ip saddr ${ASSIGNED_IP} ip daddr ${destination} accept"
|
|
done
|
|
done
|
|
|
|
echo " }"
|
|
if [ "${ENABLE_MASQUERADE}" = "true" ]; then
|
|
echo " chain postrouting {"
|
|
echo " type nat hook postrouting priority 100;"
|
|
echo " oifname \"${UPLINK_IFACE}\" ip saddr ${NETWORK_CIDR} masquerade"
|
|
echo " }"
|
|
fi
|
|
echo "}"
|
|
} > "${NFT_CONF}"
|
|
|
|
sysctl -w net.ipv4.ip_forward=1 >/dev/null
|
|
|
|
nft -f "${NFT_CONF}"
|
|
|
|
if ip link show "${IFACE}" >/dev/null 2>&1; then
|
|
wg syncconf "${IFACE}" <(wg-quick strip "${WG_CONF}")
|
|
ip link set "${IFACE}" up
|
|
else
|
|
wg-quick up "${WG_CONF}"
|
|
fi
|
|
|
|
echo "Applied WireGuard config from ${WG_CONF}"
|
|
echo "Applied nftables config from ${NFT_CONF}"
|
|
}
|
|
|
|
while true; do
|
|
apply_bundle || echo "Gateway apply failed; retrying in 15 seconds"
|
|
sleep 15
|
|
done
|