Dernière activité 1 month ago

nuno a révisé ce gist 1 month ago. Aller à la révision

1 file changed, 237 insertions

gistfile1.txt(fichier créé)

@@ -0,0 +1,237 @@
1 + #!/usr/bin/env bash
2 +
3 + function cmd::inspect::on_load() {
4 + flag::register --name
5 + flag::register --type
6 + flag::register --config
7 + flag::register --qr
8 + }
9 +
10 + function cmd::inspect::help() {
11 + cat <<EOF
12 + Usage: wgctl inspect --name <name> [--type <type>]
13 + wgctl inspect <full-name>
14 +
15 + Show detailed information for a single client.
16 +
17 + Options:
18 + --name <name> Client name
19 + --type <type> Device type (optional, combines with --name)
20 + --config Show raw client config
21 + --qr Show QR code
22 +
23 + Examples:
24 + wgctl inspect --name phone-nuno
25 + wgctl inspect --name nuno --type phone
26 + wgctl inspect --name phone-nuno --config
27 + wgctl inspect --name phone-nuno --qr
28 + EOF
29 + }
30 +
31 + # ============================================
32 + # Private helpers
33 + # ============================================
34 +
35 + function cmd::inspect::_section() {
36 + local title="$1"
37 + printf "\n \033[0;37m── %s ──────────────────────────────────\033[0m\n" "$title"
38 + }
39 +
40 + function cmd::inspect::_peer_info() {
41 + local name="${1:-}"
42 +
43 + local ip type rule public_key allowed_ips
44 + ip=$(peers::get_ip "$name")
45 + type=$(peers::get_type "$name")
46 + rule=$(peers::get_meta "$name" "rule")
47 + public_key=$(keys::public "$name" 2>/dev/null || echo "")
48 + allowed_ips=$(grep "^AllowedIPs" "$(ctx::clients)/${name}.conf" \
49 + 2>/dev/null | cut -d'=' -f2- | xargs)
50 +
51 + # Status
52 + local handshake_ts is_blocked last_ts
53 + handshake_ts=$(monitor::get_handshake_ts "$public_key")
54 + peers::is_blocked "$name" && is_blocked="true" || is_blocked="false"
55 + last_ts=$(monitor::last_attempt "$name")
56 +
57 + local status last_seen endpoint
58 + status=$(peers::format_status "$name" "$public_key" \
59 + "$is_blocked" "false" "$handshake_ts" "$last_ts")
60 + last_seen=$(peers::format_last_seen "$name" "$public_key" \
61 + "$is_blocked" "$last_ts" "" "$handshake_ts")
62 + endpoint=$(monitor::get_cached_endpoint "$name")
63 +
64 + local activity_total
65 + activity_total=$(peers::format_activity_total "$public_key")
66 +
67 + local activity_current
68 + activity_current=$(peers::format_activity_current "$public_key")
69 +
70 + local subtype
71 + subtype=$(peers::get_meta "$name" "subtype")
72 +
73 + cmd::inspect::_section "Client"
74 + ui::row "Name" "$name"
75 + ui::row "IP" "$ip"
76 + ui::row "Type" "$(peers::display_type "$type" "$subtype")"
77 + ui::row "Rule" "${rule:-—}"
78 + ui::row "Status" "$(echo -e "$status")"
79 + ui::row "Endpoint" "${endpoint:-—}"
80 + ui::row "Last seen" "$last_seen"
81 + ui::row "AllowedIPs" "$allowed_ips"
82 + ui::row "Public key" "${public_key:-—}"
83 + ui::row "Activity" "Total: $activity_total | Current: $activity_current"
84 + }
85 +
86 + function cmd::inspect::_rule_info() {
87 + local name="$1"
88 + local rule
89 + rule=$(peers::get_meta "$name" "rule")
90 + [[ -z "$rule" ]] && return 0
91 +
92 + rule::exists "$rule" || return 0
93 +
94 + local rule_file
95 + rule_file="$(ctx::rule::path "${rule}.rule")"
96 +
97 + ui::section "Rule: ${rule}"
98 +
99 + local desc dns_redirect
100 + desc=$(json::get "$rule_file" "desc")
101 + dns_redirect=$(json::get "$rule_file" "dns_redirect")
102 + ui::row "Description" "${desc:-—}"
103 + ui::row "DNS Redirect" "${dns_redirect:-false}"
104 +
105 + local allow_ports allow_ips block_ips block_ports
106 + allow_ports=$(json::get "$rule_file" "allow_ports")
107 + allow_ips=$(json::get "$rule_file" "allow_ips")
108 + block_ips=$(json::get "$rule_file" "block_ips")
109 + block_ports=$(json::get "$rule_file" "block_ports")
110 +
111 + if [[ -n "$allow_ports" || -n "$allow_ips" ]]; then
112 + printf " %-20s\n" "Allows:"
113 + ui::print_list "+" "$allow_ports"
114 + ui::print_list "+" "$allow_ips"
115 + else
116 + ui::row "Allows" "—"
117 + fi
118 +
119 + if [[ -n "$block_ips" || -n "$block_ports" ]]; then
120 + printf " %-20s\n" "Blocks:"
121 + ui::print_list "-" "$block_ips"
122 + ui::print_list "-" "$block_ports"
123 + else
124 + ui::row "Blocks" "—"
125 + fi
126 + }
127 +
128 + function cmd::inspect::_group_info() {
129 + local name="$1"
130 +
131 + ui::section "Groups"
132 +
133 + local groups=()
134 + mapfile -t groups < <(json::peer_groups "$(ctx::groups)" "$name")
135 +
136 + if [[ ${#groups[@]} -eq 0 ]] || [[ -z "${groups[0]:-}" ]]; then
137 + printf " —\n"
138 + return 0
139 + fi
140 +
141 + for g in "${groups[@]}"; do
142 + [[ -z "$g" ]] && continue
143 + local count
144 + count=$(json::count "$(group::path "$g")" "peers")
145 + printf " %-20s %s peers\n" "$g" "$count"
146 + done
147 + }
148 +
149 + function cmd::inspect::_firewall_info() {
150 + local name="$1" show_nflog="${2:-false}"
151 + local ip
152 + ip=$(peers::get_ip "$name")
153 +
154 + ui::section "Firewall"
155 +
156 + local count=0
157 + while IFS=":" read -r pname pcount; do
158 + [[ "$pname" == "$name" ]] && count="$pcount" && break
159 + done < <(json::audit_fw_counts "$(ctx::clients)")
160 +
161 + ui::row "Active rules" "$count"
162 +
163 + if [[ "$count" -gt 0 ]]; then
164 + printf "\n"
165 + iptables -L FORWARD -n </dev/null | grep -F "$ip" | while IFS= read -r rule; do
166 + [[ -z "$rule" ]] && continue
167 + echo "$rule" | grep -q "NFLOG" && continue # skip NFLOG
168 + ui::firewall_rule "$rule"
169 + done
170 + fi
171 + }
172 +
173 + function cmd::inspect::_config() {
174 + local name="$1"
175 + cmd::inspect::_section "Config"
176 + printf "\n"
177 + cat "$(ctx::clients)/${name}.conf"
178 + printf "\n"
179 + }
180 +
181 + # ============================================
182 + # Run
183 + # ============================================
184 +
185 + function cmd::inspect::run() {
186 + local name="" type="" show_config=false show_qr=false
187 +
188 + if [[ $# -gt 0 && "$1" != "--"* ]]; then
189 + name="$1"
190 + shift
191 + fi
192 +
193 + while [[ $# -gt 0 ]]; do
194 + case "$1" in
195 + --name) name="$2"; shift 2 ;;
196 + --type) type="$2"; shift 2 ;;
197 + --config) show_config=true; shift ;;
198 + --qr) show_qr=true; shift ;;
199 + --help) cmd::inspect::help; return ;;
200 + *)
201 + log::error "Unknown flag: $1"
202 + cmd::inspect::help
203 + return 1
204 + ;;
205 + esac
206 + done
207 +
208 + if [[ -z "$name" ]]; then
209 + log::error "Missing required flag: --name"
210 + cmd::inspect::help
211 + return 1
212 + fi
213 +
214 + name=$(peers::resolve_and_require "$name" "$type") || return 1
215 +
216 + load_command list
217 +
218 + log::section "Inspect: ${name}"
219 +
220 + cmd::inspect::_peer_info "$name"
221 + cmd::inspect::_rule_info "$name"
222 + cmd::inspect::_group_info "$name"
223 + cmd::inspect::_firewall_info "$name"
224 +
225 + if $show_config; then
226 + cmd::inspect::_config "$name"
227 + fi
228 +
229 + if $show_qr; then
230 + cmd::inspect::_section "QR Code"
231 + printf "\n"
232 + load_command qr
233 + cmd::qr::run --name "$name"
234 + fi
235 +
236 + printf "\n"
237 + }
Plus récent Plus ancien