/home/tools/SH/docker_network_port_ip.sh #!/usr/bin/env bash COMPOSE_PATH="/home/docker/*/docker-compose.y*ml" # ===== ANSI COLORS ===== ESC=$'\033' RESET="${ESC}[0m" BOLD="${ESC}[1m" GRAY="${ESC}[90m" RED="${ESC}[91m" GREEN="${ESC}[92m" YELLOW="${ESC}[93m" BLUE="${ESC}[94m" MAGENTA="${ESC}[95m" CYAN="${ESC}[96m" C_IP="$CYAN" C_PORT_EXT="$RED" C_PORT_INT="$BLUE" NET_COLORS=("$BLUE" "$MAGENTA" "$CYAN" "$YELLOW") declare -A NET_COLOR_MAP net_index=0 get_net_color() { local net="$1" if [[ -z "${NET_COLOR_MAP[$net]}" ]]; then NET_COLOR_MAP[$net]="${NET_COLORS[$net_index]}" net_index=$(( (net_index + 1) % ${#NET_COLORS[@]} )) fi echo "${NET_COLOR_MAP[$net]}" } clear printf "%b\n" "${BOLD}🐳 Docker Network / IP / Port Audit${RESET}" printf "%b\n" "${GRAY}────────────────────────────────────────────────────────────────────────────${RESET}" # ============================================================================= # CONTAINERS ACTIFS (AVEC PORTS EXTERNES) # ============================================================================= printf "%b\n" "${BOLD}πŸ“Š Containers actifs (triΓ©s rΓ©seau/IP)${RESET}" printf "%-34s %-30s %-18s %-45s\n" "CONTAINER" "NETWORK" "IP" "PORTS EXTERNES" printf "%-34s %-30s %-18s %-45s\n" "---------" "-------" "--" "--------------" docker inspect $(docker ps -q) | jq -r ' .[] | .Name[1:] as $n | .NetworkSettings.Networks | to_entries[] | "\(.key)|\(.value.IPAddress)|\($n)"' | sort -t"|" -k1,1 -k2,2r | while IFS="|" read -r net ip name; do net_color=$(get_net_color "$net") if [[ "$net" == "host" ]]; then ip_host=$(ip -4 route get 1 | awk '{print $7; exit}') ip="$ip_host (host)" ip_color="$GREEN" else [[ "$ip" =~ ^10\. ]] && ip_color="$GREEN" || ip_color="$YELLOW" fi # SEULEMENT PORTS EXTERNES (0.0.0.0:XXXX->) 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/, $//') ports_colored=$(printf '%s' "$ports_raw" | sed -E \ -e "s/([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+):/${C_IP}\1${RESET}:/g" \ -e "s/([0-9]+)->/${C_PORT_EXT}\1${RESET}->/g") printf "%s%-34s%s %s%-30s%s %s%-18s%s %-45s\n" \ "" "🟒 $name" "$RESET" \ "$net_color" "$net" "$RESET" \ "$ip_color" "$ip" "$RESET" \ "${ports_colored:-aucun}" done # ============================================================================= # AUDIT CONFLITS IP (FIXΓ‰) # ============================================================================= printf "%b\n" "${BOLD}πŸ” AUDIT IP CONFLITS / CHEVAUCHEMENTS${RESET}" printf "%-25s %-40s %-25s\n" "IP" "CONTAINERS" "RΓ‰SEAUX" printf "%-25s %-40s %-25s\n" "--" "----------" "-------" declare -A ip_containers declare -A ip_networks docker inspect $(docker ps -q) | jq -r ' .[] | .Name[1:] as $n | .NetworkSettings.Networks | to_entries[] | select(.value.IPAddress != null and .value.IPAddress != "") | "\(.value.IPAddress)|\(.key)|\($n)"' | while IFS="|" read -r ip net name; do [[ -n "$ip" && "$ip" != "N/A" ]] || continue ip_containers["$ip"]+="$name " ip_networks["$ip"]="$net" done conflits=0 for ip in "${!ip_containers[@]}"; do # FIX: compte mots (containers) pas caractΓ¨res if [[ $(echo "${ip_containers[$ip]}" | wc -w) -gt 1 ]]; then printf "${RED}%-25s${RESET} %-40s ${YELLOW}%-25s${RESET}\n" \ "$ip" "${ip_containers[$ip]}" "${ip_networks[$ip]}" ((conflits++)) fi done [[ $conflits -eq 0 ]] && printf "%b\n" "${GREEN}βœ… Aucune duplication IP${RESET}" # ============================================================================= # COMPOSE vs LIVE (STATUS EN 1er) # ============================================================================= echo printf "%b\n" "${BOLD}πŸ”Ž docker-compose ↔ LIVE${RESET}" printf "%-10s %-30s %-18s %-18s\n" "STATUS" "STACK" "IP COMPOSE" "IP LIVE" printf "%-10s %-30s %-18s %-18s\n" "------" "-----" "----------" "-------" for file in $COMPOSE_PATH; do stack=$(basename "$(dirname "$file")") ip_compose=$(grep -A5 "\[[:space:]]*networks:" "$file" 2>/dev/null | \ grep "ipv4_address:" | head -1 | \ sed 's/.*ipv4_address:[[:space:]]*//; s/[ "'\'']//g') [[ -z "$ip_compose" ]] && ip_compose="β€”" container=$(docker ps --format '{{.Names}}' | grep -i "^${stack}" | head -n1) if [[ -n "$container" ]]; then ip_live=$(docker inspect -f '{{range $net, $conf := .NetworkSettings.Networks}}{{if $conf.IPAddress}}{{$conf.IPAddress}}{{end}}{{end}}' "$container" | head -1) [[ -z "$ip_live" ]] && ip_live="invalid IP" else ip_live="β€”" fi if [[ "$ip_compose" != "β€”" && "$ip_live" != "β€”" && "$ip_live" != "invalid IP" && "$ip_compose" != "$ip_live" ]]; then status="${RED}⚠️ ALERTE${RESET}" else status="${GREEN}βœ… OK${RESET}" fi printf "%b %-30s %-18s %-18s\n" "$status" "$stack" "$ip_compose" "$ip_live" done echo printf "%b\n" "${BOLD}βœ… Audit terminΓ©${RESET}"