Erreur32 revised this gist 4 months ago. Go to revision
No changes
Erreur32 revised this gist 4 months ago. Go to revision
1 file changed, 138 insertions
bash_scan_docker_network_ip_port.sh(file created)
| @@ -0,0 +1,138 @@ | |||
| 1 | + | /home/tools/SH/docker_network_port_ip.sh | |
| 2 | + | #!/usr/bin/env bash | |
| 3 | + | ||
| 4 | + | COMPOSE_PATH="/home/docker/*/docker-compose.y*ml" | |
| 5 | + | ||
| 6 | + | # ===== ANSI COLORS ===== | |
| 7 | + | ESC=$'\033' | |
| 8 | + | RESET="${ESC}[0m" | |
| 9 | + | BOLD="${ESC}[1m" | |
| 10 | + | GRAY="${ESC}[90m" | |
| 11 | + | RED="${ESC}[91m" | |
| 12 | + | GREEN="${ESC}[92m" | |
| 13 | + | YELLOW="${ESC}[93m" | |
| 14 | + | BLUE="${ESC}[94m" | |
| 15 | + | MAGENTA="${ESC}[95m" | |
| 16 | + | CYAN="${ESC}[96m" | |
| 17 | + | ||
| 18 | + | C_IP="$CYAN" | |
| 19 | + | C_PORT_EXT="$RED" | |
| 20 | + | C_PORT_INT="$BLUE" | |
| 21 | + | ||
| 22 | + | NET_COLORS=("$BLUE" "$MAGENTA" "$CYAN" "$YELLOW") | |
| 23 | + | declare -A NET_COLOR_MAP | |
| 24 | + | net_index=0 | |
| 25 | + | ||
| 26 | + | get_net_color() { | |
| 27 | + | local net="$1" | |
| 28 | + | if [[ -z "${NET_COLOR_MAP[$net]}" ]]; then | |
| 29 | + | NET_COLOR_MAP[$net]="${NET_COLORS[$net_index]}" | |
| 30 | + | net_index=$(( (net_index + 1) % ${#NET_COLORS[@]} )) | |
| 31 | + | fi | |
| 32 | + | echo "${NET_COLOR_MAP[$net]}" | |
| 33 | + | } | |
| 34 | + | ||
| 35 | + | clear | |
| 36 | + | printf "%b\n" "${BOLD}🐳 Docker Network / IP / Port Audit${RESET}" | |
| 37 | + | printf "%b\n" "${GRAY}────────────────────────────────────────────────────────────────────────────${RESET}" | |
| 38 | + | ||
| 39 | + | # ============================================================================= | |
| 40 | + | # CONTAINERS ACTIFS (AVEC PORTS EXTERNES) | |
| 41 | + | # ============================================================================= | |
| 42 | + | printf "%b\n" "${BOLD}📊 Containers actifs (triés réseau/IP)${RESET}" | |
| 43 | + | printf "%-34s %-30s %-18s %-45s\n" "CONTAINER" "NETWORK" "IP" "PORTS EXTERNES" | |
| 44 | + | printf "%-34s %-30s %-18s %-45s\n" "---------" "-------" "--" "--------------" | |
| 45 | + | ||
| 46 | + | docker inspect $(docker ps -q) | jq -r ' | |
| 47 | + | .[] | .Name[1:] as $n | .NetworkSettings.Networks | to_entries[] | | |
| 48 | + | "\(.key)|\(.value.IPAddress)|\($n)"' | sort -t"|" -k1,1 -k2,2r | while IFS="|" read -r net ip name; do | |
| 49 | + | ||
| 50 | + | net_color=$(get_net_color "$net") | |
| 51 | + | ||
| 52 | + | if [[ "$net" == "host" ]]; then | |
| 53 | + | ip_host=$(ip -4 route get 1 | awk '{print $7; exit}') | |
| 54 | + | ip="$ip_host (host)" | |
| 55 | + | ip_color="$GREEN" | |
| 56 | + | else | |
| 57 | + | [[ "$ip" =~ ^10\. ]] && ip_color="$GREEN" || ip_color="$YELLOW" | |
| 58 | + | fi | |
| 59 | + | ||
| 60 | + | # SEULEMENT PORTS EXTERNES (0.0.0.0:XXXX->) | |
| 61 | + | ports_raw=$(docker ps --filter "name=^/${name}$" --format "{{.Ports}}" | grep -o "0\.0\.0\.0:[0-9]\+->[0-9]\+/tcp\|0\.0\.0\.0:[0-9]\+->[0-9]\+/udp" | tr '\n' ', ' | sed 's/, $//') | |
| 62 | + | ports_colored=$(printf '%s' "$ports_raw" | sed -E \ | |
| 63 | + | -e "s/([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+):/${C_IP}\1${RESET}:/g" \ | |
| 64 | + | -e "s/([0-9]+)->/${C_PORT_EXT}\1${RESET}->/g") | |
| 65 | + | ||
| 66 | + | printf "%s%-34s%s %s%-30s%s %s%-18s%s %-45s\n" \ | |
| 67 | + | "" "🟢 $name" "$RESET" \ | |
| 68 | + | "$net_color" "$net" "$RESET" \ | |
| 69 | + | "$ip_color" "$ip" "$RESET" \ | |
| 70 | + | "${ports_colored:-aucun}" | |
| 71 | + | done | |
| 72 | + | ||
| 73 | + | # ============================================================================= | |
| 74 | + | # AUDIT CONFLITS IP (FIXÉ) | |
| 75 | + | # ============================================================================= | |
| 76 | + | printf "%b\n" "${BOLD}🔍 AUDIT IP CONFLITS / CHEVAUCHEMENTS${RESET}" | |
| 77 | + | printf "%-25s %-40s %-25s\n" "IP" "CONTAINERS" "RÉSEAUX" | |
| 78 | + | printf "%-25s %-40s %-25s\n" "--" "----------" "-------" | |
| 79 | + | ||
| 80 | + | declare -A ip_containers | |
| 81 | + | declare -A ip_networks | |
| 82 | + | ||
| 83 | + | docker inspect $(docker ps -q) | jq -r ' | |
| 84 | + | .[] | .Name[1:] as $n | .NetworkSettings.Networks | to_entries[] | | |
| 85 | + | select(.value.IPAddress != null and .value.IPAddress != "") | | |
| 86 | + | "\(.value.IPAddress)|\(.key)|\($n)"' | while IFS="|" read -r ip net name; do | |
| 87 | + | [[ -n "$ip" && "$ip" != "N/A" ]] || continue | |
| 88 | + | ip_containers["$ip"]+="$name " | |
| 89 | + | ip_networks["$ip"]="$net" | |
| 90 | + | done | |
| 91 | + | ||
| 92 | + | conflits=0 | |
| 93 | + | for ip in "${!ip_containers[@]}"; do | |
| 94 | + | # FIX: compte mots (containers) pas caractères | |
| 95 | + | if [[ $(echo "${ip_containers[$ip]}" | wc -w) -gt 1 ]]; then | |
| 96 | + | printf "${RED}%-25s${RESET} %-40s ${YELLOW}%-25s${RESET}\n" \ | |
| 97 | + | "$ip" "${ip_containers[$ip]}" "${ip_networks[$ip]}" | |
| 98 | + | ((conflits++)) | |
| 99 | + | fi | |
| 100 | + | done | |
| 101 | + | ||
| 102 | + | [[ $conflits -eq 0 ]] && printf "%b\n" "${GREEN}✅ Aucune duplication IP${RESET}" | |
| 103 | + | ||
| 104 | + | # ============================================================================= | |
| 105 | + | # COMPOSE vs LIVE (STATUS EN 1er) | |
| 106 | + | # ============================================================================= | |
| 107 | + | echo | |
| 108 | + | printf "%b\n" "${BOLD}🔎 docker-compose ↔ LIVE${RESET}" | |
| 109 | + | printf "%-10s %-30s %-18s %-18s\n" "STATUS" "STACK" "IP COMPOSE" "IP LIVE" | |
| 110 | + | printf "%-10s %-30s %-18s %-18s\n" "------" "-----" "----------" "-------" | |
| 111 | + | ||
| 112 | + | for file in $COMPOSE_PATH; do | |
| 113 | + | stack=$(basename "$(dirname "$file")") | |
| 114 | + | ip_compose=$(grep -A5 "\[[:space:]]*networks:" "$file" 2>/dev/null | \ | |
| 115 | + | grep "ipv4_address:" | head -1 | \ | |
| 116 | + | sed 's/.*ipv4_address:[[:space:]]*//; s/[ "'\'']//g') | |
| 117 | + | [[ -z "$ip_compose" ]] && ip_compose="—" | |
| 118 | + | ||
| 119 | + | container=$(docker ps --format '{{.Names}}' | grep -i "^${stack}" | head -n1) | |
| 120 | + | ||
| 121 | + | if [[ -n "$container" ]]; then | |
| 122 | + | ip_live=$(docker inspect -f '{{range $net, $conf := .NetworkSettings.Networks}}{{if $conf.IPAddress}}{{$conf.IPAddress}}{{end}}{{end}}' "$container" | head -1) | |
| 123 | + | [[ -z "$ip_live" ]] && ip_live="invalid IP" | |
| 124 | + | else | |
| 125 | + | ip_live="—" | |
| 126 | + | fi | |
| 127 | + | ||
| 128 | + | if [[ "$ip_compose" != "—" && "$ip_live" != "—" && "$ip_live" != "invalid IP" && "$ip_compose" != "$ip_live" ]]; then | |
| 129 | + | status="${RED}⚠️ ALERTE${RESET}" | |
| 130 | + | else | |
| 131 | + | status="${GREEN}✅ OK${RESET}" | |
| 132 | + | fi | |
| 133 | + | ||
| 134 | + | printf "%b %-30s %-18s %-18s\n" "$status" "$stack" "$ip_compose" "$ip_live" | |
| 135 | + | done | |
| 136 | + | ||
| 137 | + | echo | |
| 138 | + | printf "%b\n" "${BOLD}✅ Audit terminé${RESET}" | |
Newer
Older