#!/usr/bin/env bash # Script Name: dockernet-inspector.v1.sh # Beschreibung: Dockernet Inspector - Verwaltet und inspiziert Docker-Netzwerke # - Alle Netzwerke auflisten # - Details zu einem spezifischen Docker-Netzwerk anzeigen # - Belegte IPs je Netzwerk und netzwerkuebergreifend ausgeben # Verwendung: bash ./dockernet-inspector.v1.sh [BEFEHL] [OPTIONS] # Befehle: # networks - Alle Docker Netzwerke auflisten # inspect - Details zu einem Netzwerk anzeigen (Standard) # ips - Belegte IPs in einem Netzwerk # ips-all - Belegte IPs in allen Netzwerken # help, -h, --help - Diese Hilfe anzeigen # Autor: Patrick Asmus # Web: https://www.cleveradmin.de # Git-Reposit.: https://git.techniverse.net/scriptos/dockernet-inspector.git # Version: 1.2.0 # Datum: 18.02.2026 # Modifikation: IP-Listen pro Netzwerk und netzwerkuebergreifend hinzugefuegt ##################################################### set -euo pipefail TABLE_LINE_WIDTH=80 print_rule() { local char="$1" printf '%*s\n' "$TABLE_LINE_WIDTH" '' | tr ' ' "$char" } print_table_title() { local title="$1" echo "$title" print_rule "=" } # Hilfe-Funktion show_help() { cat < - Details zu einem Netzwerk anzeigen $0 ips - Belegte IPs in einem Netzwerk anzeigen $0 ips-all - Belegte IPs in allen Netzwerken anzeigen $0 - Alias fuer 'inspect ' $0 help - Diese Hilfe anzeigen BEFEHLE: networks Listet alle verfuegbaren Docker Netzwerke auf ips Zeigt Containername und IPv4-Adresse im angegebenen Netzwerk ips-all Zeigt alle belegten IPv4-Adressen in allen Netzwerken (aufsteigend) inspect Zeigt detaillierte Informationen zu einem Netzwerk: - Netzwerktyp (Driver) - Bridge-Interface - Subnetz und Gateway - Interface-Status - Netzwerk-Statistiken (RX/TX bytes und packets) help Zeigt diese Hilfe an BEISPIELE: $0 networks $0 ips mynetwork $0 ips-all $0 inspect mynetwork $0 mynetwork $0 -h HELP } # Funktion zum Auflisten aller Docker Netzwerke list_networks() { local table_output header print_table_title "Verfuegbare Docker Netzwerke:" table_output="$(docker network ls --format "table {{.ID}}\t{{.Name}}\t{{.Driver}}\t{{.Scope}}")" || { echo "Fehler: Docker Netzwerke konnten nicht abgerufen werden." exit 2 } header="$(printf "%s\n" "$table_output" | head -n 1)" printf "%s\n" "$header" print_rule "-" printf "%s\n" "$table_output" | tail -n +2 } print_dynamic_table() { local data="$1" local formatted local header if command -v column >/dev/null 2>&1; then formatted="$(printf "%b" "$data" | column -t -s $'\t')" else formatted="$(printf "%b" "$data")" fi header="$(printf "%s\n" "$formatted" | head -n 1)" printf "%s\n" "$header" print_rule "-" printf "%s\n" "$formatted" | tail -n +2 } list_ips_in_network() { local net="$1" local rows table_data rows="$(docker network inspect "$net" --format '{{range $id, $c := .Containers}}{{println $c.Name $c.IPv4Address}}{{end}}' 2>/dev/null || true)" [[ -z "$rows" ]] && { echo "Keine Container mit IPv4-Adresse im Netzwerk '$net' gefunden." exit 0 } print_table_title "Belegte IP-Adressen im Netzwerk '$net':" table_data=$'CONTAINER\tIP\n' while read -r cname ipcidr; do [[ -z "${cname:-}" || -z "${ipcidr:-}" ]] && continue table_data+="${cname}"$'\t'"${ipcidr%%/*}"$'\n' done < <(printf "%s\n" "$rows" | sort -k2,2V) print_dynamic_table "$table_data" } list_ips_all_networks() { local nets rows table_data rows="" nets="$(docker network ls --format '{{.Name}}' 2>/dev/null || true)" [[ -z "$nets" ]] && { echo "Fehler: Docker Netzwerke konnten nicht abgerufen werden." exit 2 } while read -r net; do [[ -z "${net:-}" ]] && continue while read -r cname ipcidr; do [[ -z "${cname:-}" || -z "${ipcidr:-}" ]] && continue rows+="${net}"$'\t'"${cname}"$'\t'"${ipcidr%%/*}"$'\n' done < <(docker network inspect "$net" --format '{{range $id, $c := .Containers}}{{println $c.Name $c.IPv4Address}}{{end}}' 2>/dev/null || true) done < <(printf "%s\n" "$nets") [[ -z "$rows" ]] && { echo "Keine belegten IPv4-Adressen in Docker Netzwerken gefunden." exit 0 } print_table_title "Belegte IP-Adressen in allen Netzwerken (aufsteigend):" table_data=$'NETZWERK\tCONTAINER\tIP\n' while IFS=$'\t' read -r net cname ip; do [[ -z "${net:-}" || -z "${cname:-}" || -z "${ip:-}" ]] && continue table_data+="${net}"$'\t'"${cname}"$'\t'"${ip}"$'\n' done < <(printf "%s" "$rows" | sort -t $'\t' -k3,3V -k1,1 -k2,2) print_dynamic_table "$table_data" } # Argument-Verarbeitung COMMAND="${1:-}" case "$COMMAND" in networks) list_networks exit 0 ;; ips) NET="${2:-}" [[ -z "$NET" ]] && { echo "Fehler: Netzwerkname erforderlich. Verwendung: $0 ips "; exit 1; } list_ips_in_network "$NET" exit 0 ;; ips-all) list_ips_all_networks exit 0 ;; help | -h | --help) show_help exit 0 ;; inspect) NET="${2:-}" [[ -z "$NET" ]] && { echo "Fehler: Netzwerkname erforderlich. Verwendung: $0 inspect "; exit 1; } ;; "") echo "Fehler: Befehl erforderlich. Verwendung: $0 networks|inspect|ips|ips-all|help" exit 1 ;; *) # Kompatibilitaet: Wenn erstes Argument kein bekannter Befehl ist, behandle es als Netzwerkname NET="$COMMAND" ;; esac # Hauptlogik fuer die Inspektion eines Netzwerks [[ -z "${NET:-}" ]] && { echo "Fehler: Netzwerkname erforderlich. Verwendung: $0 "; exit 1; } # 1) Netzwerk-ID und Bridge-Name separat holen ID="$(docker network inspect "$NET" --format '{{.Id}}' 2>/dev/null || true)" [[ -z "$ID" ]] && { echo "Fehler: Netzwerk '$NET' nicht gefunden."; exit 2; } BR_RAW="$(docker network inspect "$NET" --format '{{index .Options "com.docker.network.bridge.name"}}' 2>/dev/null || true)" # 2) Falls kein eigener Bridge-Name: Standardname br- if [[ -z "$BR_RAW" || "$BR_RAW" == "" ]]; then IF="br-${ID:0:12}" else IF="$BR_RAW" fi # 3) Subnet/Gateway SUBNET="$(docker network inspect "$NET" --format '{{(index .IPAM.Config 0).Subnet}}' 2>/dev/null || true)" GATEWAY="$(docker network inspect "$NET" --format '{{(index .IPAM.Config 0).Gateway}}' 2>/dev/null || true)" # 4) Interface-Status & Stats state="unknown"; rxb=0; txb=0; rxp=0; txp=0 if ip link show "$IF" &>/dev/null; then state="$(cat /sys/class/net/"$IF"/operstate 2>/dev/null || echo unknown)" rxb="$(cat /sys/class/net/"$IF"/statistics/rx_bytes 2>/dev/null || echo 0)" txb="$(cat /sys/class/net/"$IF"/statistics/tx_bytes 2>/dev/null || echo 0)" rxp="$(cat /sys/class/net/"$IF"/statistics/rx_packets 2>/dev/null || echo 0)" txp="$(cat /sys/class/net/"$IF"/statistics/tx_packets 2>/dev/null || echo 0)" else echo "WARN: Interface $IF existiert (noch) nicht auf dem Host." fi cat <