Dernière activité 2 months ago

nuno a révisé ce gist 2 months ago. Aller à la révision

1 file changed, 1 insertion

add.command.sh

@@ -8,6 +8,7 @@ function cmd::add::on_load() {
8 8 flag::register --name
9 9 flag::register --type
10 10 flag::register --subtype
11 + flag::register --rule
11 12 flag::register --ip
12 13 flag::register --preset
13 14 flag::register --guest

nuno a révisé ce gist 2 months ago. Aller à la révision

1 file changed, 230 insertions

add.command.sh(fichier créé)

@@ -0,0 +1,230 @@
1 + #!/usr/bin/env bash
2 +
3 + # ============================================
4 + # Lifecycle
5 + # ============================================
6 +
7 + function cmd::add::on_load() {
8 + flag::register --name
9 + flag::register --type
10 + flag::register --subtype
11 + flag::register --ip
12 + flag::register --preset
13 + flag::register --guest
14 + flag::register --tunnel
15 + flag::register --show-config
16 + flag::register --show-qr
17 + }
18 +
19 + # ============================================
20 + # Help
21 + # ============================================
22 +
23 + function cmd::add::help() {
24 + cat <<EOF
25 + Usage: wgctl add --name <name> --type <type> [options]
26 +
27 + Add a new WireGuard client.
28 +
29 + Options:
30 + --name <name> Client name (e.g. nuno)
31 + --type <type> Device type: desktop, laptop, phone, tablet, guest
32 + --ip <ip> Override auto-assigned IP (optional)
33 + --preset <name> Apply a firewall preset (repeatable)
34 + --guest Shorthand for --type guest
35 + --tunnel <mode> Tunnel mode: split (default) or full
36 + --show-config Shows the WireGuard peer config
37 + --show-qr Shows the WireGuard config in a QR Code
38 +
39 + Device Types and Subnets:
40 + desktop 10.1.1.x
41 + laptop 10.1.2.x
42 + phone 10.1.3.x
43 + tablet 10.1.4.x
44 + guest 10.1.100.x
45 +
46 + Tunnel Modes:
47 + split Route only VPN subnet + LAN through WireGuard (default)
48 + full Route all traffic through WireGuard
49 +
50 + Examples:
51 + wgctl add --name nuno --type phone
52 + wgctl add --name nuno --type laptop --ip 10.1.2.5
53 + wgctl add --name nuno --type phone --tunnel full
54 + wgctl add --name guest1 --type phone --guest
55 + wgctl add --name restricted --type desktop --preset no-docker --preset no-proxmox
56 + EOF
57 + }
58 +
59 + # ============================================
60 + # Validation
61 + # ============================================
62 +
63 + function cmd::add::validate() {
64 + local name="$1"
65 + local type="$2"
66 + local ip="$3"
67 + local tunnel="$4"
68 +
69 + if [[ -z "$name" ]]; then
70 + log::error "Missing required flag: --name"
71 + return 1
72 + fi
73 +
74 + if [[ -z "$type" ]]; then
75 + log::error "Missing required flag: --type"
76 + return 1
77 + fi
78 +
79 + if ! config::is_valid_type "$type"; then
80 + log::error "Invalid device type: ${type}"
81 + log::info "Valid types: $(config::device_types | tr ' ' ', ')"
82 + return 1
83 + fi
84 +
85 + if [[ -n "$tunnel" && "$tunnel" != "split" && "$tunnel" != "full" ]]; then
86 + log::error "Invalid tunnel mode: ${tunnel} (use 'split' or 'full')"
87 + return 1
88 + fi
89 +
90 + if [[ -n "$ip" ]]; then
91 + ip::require_valid "$ip"
92 + fi
93 +
94 + local full_name="${type}-${name}"
95 +
96 + if [[ -f "$(ctx::clients)/${full_name}.conf" ]]; then
97 + log::error "Client already exists: ${full_name}"
98 + return 1
99 + fi
100 + }
101 +
102 + # ============================================
103 + # Display helpers
104 + # ============================================
105 +
106 + function cmd::add::is_mobile() {
107 + local type="$1"
108 + [[ "$type" == "phone" || "$type" == "tablet" ]]
109 + }
110 +
111 + # ============================================
112 + # Run
113 + # ============================================
114 +
115 + function cmd::add::run() {
116 + local name=""
117 + local type=""
118 + local subtype=""
119 + local ip=""
120 + local tunnel=""
121 + local guest=false
122 + local presets=()
123 + local show_config=false
124 + local show_qr=false
125 +
126 + # Parse flags
127 + while [[ $# -gt 0 ]]; do
128 + case "$1" in
129 + --name) name="$2"; shift 2 ;;
130 + --type) type="$2"; shift 2 ;;
131 + --subtype) subtype="$2"; shift 2 ;;
132 + --ip) ip="$2"; shift 2 ;;
133 + --preset) presets+=("$2"); shift 2 ;;
134 + --guest) guest=true; shift ;;
135 + --tunnel) tunnel="$2"; shift 2 ;;
136 + --show-config) show_config=true; shift ;;
137 + --show-qr) show_qr=true; shift ;;
138 + --help) cmd::add::help; return ;;
139 + *)
140 + log::error "Unknown flag: $1"
141 + cmd::add::help
142 + return 1
143 + ;;
144 + esac
145 + done
146 +
147 + # --guest shorthand
148 + if $guest; then
149 + type="guest"
150 + fi
151 +
152 + # Resolve guest subtype
153 + local effective_type="$type"
154 + if [[ "$type" == "guest" && -n "$subtype" ]]; then
155 + # Validate subtype
156 + local valid_subtypes="desktop laptop phone tablet"
157 + if ! echo "$valid_subtypes" | grep -qw "$subtype"; then
158 + log::error "Invalid subtype: ${subtype} (valid: desktop, laptop, phone, tablet)"
159 + return 1
160 + fi
161 + effective_type="guest-${subtype}"
162 + fi
163 +
164 + # Build full client name
165 + local full_name="${type}-${name}"
166 +
167 + # Validate
168 + cmd::add::validate "$name" "$type" "$ip" "$tunnel" || return 1
169 +
170 + # Resolve tunnel mode — flag > device default
171 + if [[ -z "$tunnel" ]]; then
172 + tunnel=$(config::default_tunnel_for "$type")
173 + fi
174 +
175 + local allowed_ips
176 + allowed_ips=$(config::allowed_ips_for "$effective_type" "$tunnel") || return 1
177 +
178 + log::section "Adding client: ${full_name}"
179 +
180 + # Auto-assign IP if not provided
181 + if [[ -z "$ip" ]]; then
182 + ip=$(ip::next_for_type "$effective_type") || return 1
183 + fi
184 +
185 + log::wg_add "Name: ${full_name}"
186 + log::wg_add "Type: ${type}"
187 + log::wg_add "IP: ${ip}"
188 + log::wg_add "Tunnel: ${tunnel} (${allowed_ips})"
189 +
190 + # Generate keys
191 + keys::generate_pair "$full_name" || return 1
192 +
193 + # Create client config
194 + peers::create_client_config "$full_name" "$effective_type" "$ip" "$allowed_ips" || return 1
195 +
196 + # Store subtype in meta
197 + if [[ -n "$subtype" ]]; then
198 + peers::set_meta "$full_name" "subtype" "$subtype"
199 + fi
200 +
201 + # Add peer to server config
202 + local public_key
203 + public_key=$(keys::public "$full_name") || return 1
204 + peers::add_to_server "$full_name" "$public_key" "$ip" || return 1
205 +
206 + # Apply presets
207 + for preset in "${presets[@]}"; do
208 + firewall::apply_preset "$preset" "${ip}" || return 1
209 + done
210 +
211 + # Apply guest rules if guest type
212 + if config::is_guest_type "$type"; then
213 + firewall::apply_guest_rules
214 + fi
215 +
216 + # Reload WireGuard
217 + peers::reload || return 1
218 +
219 + log::wg_success "Client added successfully: ${full_name} (${ip}) [${tunnel} tunnel]"
220 +
221 + # Show QR for mobile by default, config for desktop/laptop
222 + local display_type="${subtype:-$type}"
223 +
224 + if cmd::add::is_mobile "$display_type"; then
225 + keys::qr "$full_name"
226 + else
227 + log::section "Client Config"
228 + cat "$(ctx::clients)/${full_name}.conf"
229 + fi
230 + }
Plus récent Plus ancien