Last active 2 months ago

Revision 1e185436e80d3be797c4f156d7408e33092afda4

config.module.sh Raw
1#!/usr/bin/env bash
2
3# ============================================
4# Lifecycle
5# ============================================
6
7function config::on_load() {
8 config::validate
9}
10
11# ============================================
12# Server
13# ============================================
14
15WG_INTERFACE="wg0"
16WG_CONFIG="$(ctx::wg)/${WG_INTERFACE}.conf"
17WG_SERVER_PUBLIC_KEY_FILE="$(ctx::wg)/server_public.key"
18WG_SERVER_PRIVATE_KEY_FILE="$(ctx::wg)/server_private.key"
19WG_ENDPOINT="wg.krilio.net:51820"
20WG_DNS="10.0.0.103"
21WG_LISTEN_PORT="51820"
22WG_SUBNET="10.1.0.0/16"
23WG_LAN="10.0.0.0/24"
24
25# ============================================
26# Device Type → Subnet Mapping
27# ============================================
28
29declare -gA DEVICE_SUBNETS=(
30 [desktop]="10.1.1"
31 [laptop]="10.1.2"
32 [phone]="10.1.3"
33 [tablet]="10.1.4"
34 [guest]="10.1.100"
35)
36
37# ============================================
38# Tunnel Modes
39# ============================================
40
41# split — route only VPN subnet + LAN through WireGuard
42# full — route all traffic through WireGuard
43WG_TUNNEL_SPLIT="${WG_SUBNET}, ${WG_LAN}"
44WG_TUNNEL_FULL="0.0.0.0/0, ::/0"
45
46# Default tunnel mode per device type
47declare -gA DEVICE_TUNNEL_MODE=(
48 [desktop]="split"
49 [laptop]="split"
50 [phone]="split"
51 [tablet]="split"
52 [guest]="split"
53)
54
55# ============================================
56# Accessors
57# ============================================
58
59function config::interface() { echo "$WG_INTERFACE"; }
60function config::config_file() { echo "$WG_CONFIG"; }
61function config::endpoint() { echo "$WG_ENDPOINT"; }
62function config::dns() { echo "$WG_DNS"; }
63function config::listen_port() { echo "$WG_LISTEN_PORT"; }
64function config::subnet() { echo "$WG_SUBNET"; }
65function config::lan() { echo "$WG_LAN"; }
66function config::tunnel_split() { echo "$WG_TUNNEL_SPLIT"; }
67function config::tunnel_full() { echo "$WG_TUNNEL_FULL"; }
68
69function config::server_public_key() {
70 cat "$WG_SERVER_PUBLIC_KEY_FILE"
71}
72
73function config::device_types() {
74 local types
75 { set +u; types="${!DEVICE_SUBNETS[@]}"; set -u; }
76 echo "$types"
77}
78
79function config::is_valid_type() {
80 local type="$1"
81 local subnet
82 subnet=$(config::subnet_for "$type")
83 [[ -n "$subnet" ]]
84}
85
86function config::subnet_for() {
87 local type="$1"
88 local result
89 { set +u; result="${DEVICE_SUBNETS[$type]:-}"; set -u; }
90 echo "$result"
91}
92
93function config::default_tunnel_for() {
94 local type="$1"
95 local result
96 { set +u; result="${DEVICE_TUNNEL_MODE[$type]:-split}"; set -u; }
97 echo "$result"
98}
99
100function config::allowed_ips_for() {
101 local type="$1"
102 local tunnel="${2:-}"
103
104 # If tunnel mode not specified, use device default
105 if [[ -z "$tunnel" ]]; then
106 tunnel=$(config::default_tunnel_for "$type")
107 fi
108
109 case "$tunnel" in
110 full) echo "$WG_TUNNEL_FULL" ;;
111 split) echo "$WG_TUNNEL_SPLIT" ;;
112 *)
113 log::error "Unknown tunnel mode: ${tunnel} (use 'split' or 'full')"
114 return 1
115 ;;
116 esac
117}
118
119# ============================================
120# Validation
121# ============================================
122
123function config::validate() {
124 if [[ ! -f "$WG_SERVER_PUBLIC_KEY_FILE" ]]; then
125 log::error "Server public key not found: ${WG_SERVER_PUBLIC_KEY_FILE}"
126 exit 1
127 fi
128
129 if [[ ! -f "$WG_SERVER_PRIVATE_KEY_FILE" ]]; then
130 log::error "Server private key not found: ${WG_SERVER_PRIVATE_KEY_FILE}"
131 exit 1
132 fi
133
134 if [[ ! -f "$WG_CONFIG" ]]; then
135 log::error "WireGuard config not found: ${WG_CONFIG}"
136 exit 1
137 fi
138}