summaryrefslogtreecommitdiffstats
path: root/roles/gateway/templates
diff options
context:
space:
mode:
authorAhmed Abdelhalim <[email protected]>2025-09-12 00:17:35 +0200
committerAhmed Abdelhalim <[email protected]>2025-09-12 00:17:35 +0200
commit4a812a999a79dae501db62e0eeb9e33e34282b83 (patch)
tree7843b04b7f6be1eac6d5d4e421b38a5e12bb4fec /roles/gateway/templates
parentd8bd623f3a86e7f472cd034f627a86dc8ccf4955 (diff)
Implement the gateway role (replacing old wireguard-gateway)
Diffstat (limited to 'roles/gateway/templates')
-rw-r--r--roles/gateway/templates/99-wireguard-gateway.rules.j22
-rw-r--r--roles/gateway/templates/gateway-apply-rules.sh.j293
-rw-r--r--roles/gateway/templates/gateway-direct-mode.service.j214
-rw-r--r--roles/gateway/templates/gateway-init.service.j215
-rw-r--r--roles/gateway/templates/gateway-vpn-mode.service.j214
5 files changed, 138 insertions, 0 deletions
diff --git a/roles/gateway/templates/99-wireguard-gateway.rules.j2 b/roles/gateway/templates/99-wireguard-gateway.rules.j2
new file mode 100644
index 00000000..a4164bc3
--- /dev/null
+++ b/roles/gateway/templates/99-wireguard-gateway.rules.j2
@@ -0,0 +1,2 @@
+ACTION=="add", SUBSYSTEM=="net", KERNEL=="wg*", TAG+="systemd", ENV{SYSTEMD_WANTS}="gateway-vpn-mode.service"
+ACTION=="remove", SUBSYSTEM=="net", KERNEL=="wg*", TAG+="systemd", ENV{SYSTEMD_WANTS}="gateway-direct-mode.service"
diff --git a/roles/gateway/templates/gateway-apply-rules.sh.j2 b/roles/gateway/templates/gateway-apply-rules.sh.j2
new file mode 100644
index 00000000..d79f2279
--- /dev/null
+++ b/roles/gateway/templates/gateway-apply-rules.sh.j2
@@ -0,0 +1,93 @@
+#!/bin/bash
+
+set -euo pipefail
+
+SCRIPT_NAME="gateway-apply-rules"
+LOG_FACILITY="local0.info"
+
+# Ansible template variables - configured at deployment time
+GATEWAY_SUBNET="{{ gateway_local_ipv4_subnet }}"
+GATEWAY_INTERFACE="{{ gateway_router_interface }}"
+log_message() {
+ echo "[$SCRIPT_NAME] $1" | logger -t "$SCRIPT_NAME" -p "$LOG_FACILITY"
+ echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
+}
+
+detect_vpn_interfaces() {
+ ip link show | grep -E '^[0-9]+: wg.*:.*UP' | cut -d: -f2 | tr -d ' ' || true
+}
+
+clear_rules() {
+ log_message "Clearing existing gateway rules"
+ iptables -F FORWARD 2>/dev/null || true
+ iptables -t nat -D POSTROUTING -s "$GATEWAY_SUBNET" -o wg+ -j MASQUERADE 2>/dev/null || true
+ iptables -t nat -D POSTROUTING -s "$GATEWAY_SUBNET" -o "$GATEWAY_INTERFACE" -j MASQUERADE 2>/dev/null || true
+ iptables -D OUTPUT -o wg+ -j ACCEPT 2>/dev/null || true
+ iptables -D OUTPUT -o "$GATEWAY_INTERFACE" -j ACCEPT 2>/dev/null || true
+}
+
+apply_vpn_mode() {
+ local vpn_interfaces="$1"
+ log_message "Applying VPN mode rules for interfaces: $vpn_interfaces"
+ iptables -t nat -A POSTROUTING -s "$GATEWAY_SUBNET" -o wg+ -j MASQUERADE
+ iptables -A OUTPUT -o wg+ -j ACCEPT
+ iptables -A FORWARD -s "$GATEWAY_SUBNET" -o wg+ -j ACCEPT
+ iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
+ log_message "VPN mode rules applied - traffic routed through VPN"
+}
+
+apply_direct_rules() {
+ log_message "Applying direct mode rules"
+ iptables -t nat -A POSTROUTING -s "$GATEWAY_SUBNET" -o "$GATEWAY_INTERFACE" -j MASQUERADE
+ iptables -A OUTPUT -o "$GATEWAY_INTERFACE" -j ACCEPT
+ iptables -A FORWARD -s "$GATEWAY_SUBNET" -o "$GATEWAY_INTERFACE" -j ACCEPT
+ iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
+ log_message "Direct mode rules applied - normal routing active"
+}
+
+handle_vpn_mode() {
+ local vpn_interfaces
+ vpn_interfaces=$(detect_vpn_interfaces)
+
+ if [ -n "$vpn_interfaces" ]; then
+ clear_rules
+ apply_vpn_mode "$vpn_interfaces"
+ log_message "Switched to VPN mode"
+ else
+ log_message "No VPN interfaces found, ignoring VPN mode request"
+ fi
+}
+
+handle_direct_mode() {
+ local vpn_interfaces
+ vpn_interfaces=$(detect_vpn_interfaces)
+
+ if [ -z "$vpn_interfaces" ]; then
+ clear_rules
+ apply_direct_rules
+ log_message "Switched to direct mode"
+ else
+ log_message "VPN interfaces still active: $vpn_interfaces"
+ fi
+}
+
+main() {
+ local mode="$1"
+
+ case "$mode" in
+ "vpn")
+ handle_vpn_mode
+ ;;
+ "direct")
+ handle_direct_mode
+ ;;
+ *)
+ log_message "Unknown mode: $mode"
+ exit 1
+ ;;
+ esac
+}
+
+trap 'log_message "Script failed with error on line $LINENO"' ERR
+
+main "$@"
diff --git a/roles/gateway/templates/gateway-direct-mode.service.j2 b/roles/gateway/templates/gateway-direct-mode.service.j2
new file mode 100644
index 00000000..5d708f84
--- /dev/null
+++ b/roles/gateway/templates/gateway-direct-mode.service.j2
@@ -0,0 +1,14 @@
+[Unit]
+Description=Gateway Direct Mode Service
+Documentation=man:systemd.service(5)
+After=network.target
+
+[Service]
+Type=oneshot
+ExecStart=/usr/local/bin/gateway-apply-rules direct
+User=root
+StandardOutput=journal
+StandardError=journal
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/gateway/templates/gateway-init.service.j2 b/roles/gateway/templates/gateway-init.service.j2
new file mode 100644
index 00000000..8b4635d8
--- /dev/null
+++ b/roles/gateway/templates/gateway-init.service.j2
@@ -0,0 +1,15 @@
+[Unit]
+Description=Gateway Init Service
+Documentation=man:systemd.service(5)
+After=network.target
+
+[Service]
+Type=oneshot
+ExecStart=/usr/local/bin/gateway-apply-rules vpn
+ExecStart=/usr/local/bin/gateway-apply-rules direct
+User=root
+StandardOutput=journal
+StandardError=journal
+
+[Install]
+WantedBy=multi-user.target \ No newline at end of file
diff --git a/roles/gateway/templates/gateway-vpn-mode.service.j2 b/roles/gateway/templates/gateway-vpn-mode.service.j2
new file mode 100644
index 00000000..7816e6d5
--- /dev/null
+++ b/roles/gateway/templates/gateway-vpn-mode.service.j2
@@ -0,0 +1,14 @@
+[Unit]
+Description=Gateway VPN Mode Service
+Documentation=man:systemd.service(5)
+After=network.target
+
+[Service]
+Type=oneshot
+ExecStart=/usr/local/bin/gateway-apply-rules vpn
+User=root
+StandardOutput=journal
+StandardError=journal
+
+[Install]
+WantedBy=multi-user.target