#!/usr/bin/env bash function cmd::inspect::on_load() { flag::register --name flag::register --type flag::register --config flag::register --qr } function cmd::inspect::help() { cat < [--type ] wgctl inspect Show detailed information for a single client. Options: --name Client name --type Device type (optional, combines with --name) --config Show raw client config --qr Show QR code Examples: wgctl inspect --name phone-nuno wgctl inspect --name nuno --type phone wgctl inspect --name phone-nuno --config wgctl inspect --name phone-nuno --qr EOF } # ============================================ # Private helpers # ============================================ function cmd::inspect::_section() { local title="$1" printf "\n \033[0;37m── %s ──────────────────────────────────\033[0m\n" "$title" } function cmd::inspect::_peer_info() { local name="${1:-}" local ip type rule public_key allowed_ips ip=$(peers::get_ip "$name") type=$(peers::get_type "$name") rule=$(peers::get_meta "$name" "rule") public_key=$(keys::public "$name" 2>/dev/null || echo "") allowed_ips=$(grep "^AllowedIPs" "$(ctx::clients)/${name}.conf" \ 2>/dev/null | cut -d'=' -f2- | xargs) # Status local handshake_ts is_blocked last_ts handshake_ts=$(monitor::get_handshake_ts "$public_key") peers::is_blocked "$name" && is_blocked="true" || is_blocked="false" last_ts=$(monitor::last_attempt "$name") local status last_seen endpoint status=$(peers::format_status "$name" "$public_key" \ "$is_blocked" "false" "$handshake_ts" "$last_ts") last_seen=$(peers::format_last_seen "$name" "$public_key" \ "$is_blocked" "$last_ts" "" "$handshake_ts") endpoint=$(monitor::get_cached_endpoint "$name") local activity_total activity_total=$(peers::format_activity_total "$public_key") local activity_current activity_current=$(peers::format_activity_current "$public_key") local subtype subtype=$(peers::get_meta "$name" "subtype") cmd::inspect::_section "Client" ui::row "Name" "$name" ui::row "IP" "$ip" ui::row "Type" "$(peers::display_type "$type" "$subtype")" ui::row "Rule" "${rule:-—}" ui::row "Status" "$(echo -e "$status")" ui::row "Endpoint" "${endpoint:-—}" ui::row "Last seen" "$last_seen" ui::row "AllowedIPs" "$allowed_ips" ui::row "Public key" "${public_key:-—}" ui::row "Activity" "Total: $activity_total | Current: $activity_current" } function cmd::inspect::_rule_info() { local name="$1" local rule rule=$(peers::get_meta "$name" "rule") [[ -z "$rule" ]] && return 0 rule::exists "$rule" || return 0 local rule_file rule_file="$(ctx::rule::path "${rule}.rule")" ui::section "Rule: ${rule}" local desc dns_redirect desc=$(json::get "$rule_file" "desc") dns_redirect=$(json::get "$rule_file" "dns_redirect") ui::row "Description" "${desc:-—}" ui::row "DNS Redirect" "${dns_redirect:-false}" local allow_ports allow_ips block_ips block_ports allow_ports=$(json::get "$rule_file" "allow_ports") allow_ips=$(json::get "$rule_file" "allow_ips") block_ips=$(json::get "$rule_file" "block_ips") block_ports=$(json::get "$rule_file" "block_ports") if [[ -n "$allow_ports" || -n "$allow_ips" ]]; then printf " %-20s\n" "Allows:" ui::print_list "+" "$allow_ports" ui::print_list "+" "$allow_ips" else ui::row "Allows" "—" fi if [[ -n "$block_ips" || -n "$block_ports" ]]; then printf " %-20s\n" "Blocks:" ui::print_list "-" "$block_ips" ui::print_list "-" "$block_ports" else ui::row "Blocks" "—" fi } function cmd::inspect::_group_info() { local name="$1" ui::section "Groups" local groups=() mapfile -t groups < <(json::peer_groups "$(ctx::groups)" "$name") if [[ ${#groups[@]} -eq 0 ]] || [[ -z "${groups[0]:-}" ]]; then printf " —\n" return 0 fi for g in "${groups[@]}"; do [[ -z "$g" ]] && continue local count count=$(json::count "$(group::path "$g")" "peers") printf " %-20s %s peers\n" "$g" "$count" done } function cmd::inspect::_firewall_info() { local name="$1" show_nflog="${2:-false}" local ip ip=$(peers::get_ip "$name") ui::section "Firewall" local count=0 while IFS=":" read -r pname pcount; do [[ "$pname" == "$name" ]] && count="$pcount" && break done < <(json::audit_fw_counts "$(ctx::clients)") ui::row "Active rules" "$count" if [[ "$count" -gt 0 ]]; then printf "\n" iptables -L FORWARD -n