Skip to main content

Registration Port Check

Port Check PE ↔ PC

Checks reachability between Prism Element and Prism Central before/while registering: ping, TCP 9440 (required, both directions), TCP 22/443 (optional), Prism API response and clock skew. Plain bash (/dev/tcp) — no nc/nmap needed.

Run on a PE CVM against the PC IP, then on the PCVM against all CVM IPs + cluster VIP

bash pc_port_check.sh <PC_IP>
bash pc_port_check.sh <CVM1> <CVM2> <CVM3> <CLUSTER_VIP>

Only TCP 9440 (both directions) is a confirmed hard requirement — check the full list for your PC version in the Nutanix portal (Ports and Protocols → Prism Central) and extend PORTS_OPTIONAL if needed. If all ports are open and registration still fails: check DNS/NTP on the PCVM and ncli multicluster get-cluster-state on the CVM (still registered elsewhere?).

Script: pc_port_check.sh

#!/usr/bin/env bash
# pc_port_check.sh – checks whether Prism Element (PE) and Prism Central (PC) can reach each other.
#
# Usage:
#   On a PE CVM:   bash pc_port_check.sh <PC_IP>
#   On the PCVM:   bash pc_port_check.sh <CVM_IP> [<CVM_IP> ... <CLUSTER_VIP>]
#
# Registration requires TCP 9440 in BOTH directions,
# so run the script on both sides.

PORTS_REQUIRED="9440"          # Prism / API – mandatory
PORTS_OPTIONAL="22 443"        # SSH (troubleshooting), HTTPS (newer PC versions / CMSP)
TIMEOUT=3                      # seconds per test

if [ $# -lt 1 ]; then
  echo "Usage: bash $0 <TARGET_IP> [<TARGET_IP> ...]"
  exit 1
fi

GREEN='\033[32m'; RED='\033[31m'; YELLOW='\033[33m'; NC='\033[0m'
FAILED=0

# Tests a TCP port with plain bash – works without nc/nmap
check_port() {
  local host=$1 port=$2 art=$3
  if timeout "$TIMEOUT" bash -c "echo > /dev/tcp/$host/$port" 2>/dev/null; then
    echo -e "  ${GREEN}OPEN${NC}       TCP $port ($art)"
  elif [ "$art" = "required" ]; then
    echo -e "  ${RED}CLOSED${NC}     TCP $port ($art)  <-- check firewall/routing!"
    FAILED=1
  else
    echo -e "  ${YELLOW}CLOSED${NC}     TCP $port ($art)"
  fi
}

for TARGET in "$@"; do
  echo "================================================="
  echo " Target: $TARGET   (from $(hostname))"
  echo "================================================="

  # 1) Basic reachability
  if ping -c 2 -W 2 "$TARGET" >/dev/null 2>&1; then
    echo -e "  ${GREEN}OK${NC}         Ping"
  else
    echo -e "  ${YELLOW}NO PING${NC}    (ICMP may be filtered – not necessarily an error)"
  fi

  # 2) Ports
  for p in $PORTS_REQUIRED; do check_port "$TARGET" "$p" "required"; done
  for p in $PORTS_OPTIONAL; do check_port "$TARGET" "$p" "optional"; done

  # 3) Is it really Prism answering on 9440? (HTTP 401 = login required = good)
  CODE=$(curl -sk -o /dev/null -w '%{http_code}' --max-time 5 "https://$TARGET:9440/api/nutanix/v3/clusters/list" -X POST -H 'Content-Type: application/json' -d '{}')
  case "$CODE" in
    401|200) echo -e "  ${GREEN}OK${NC}         Prism API responds (HTTP $CODE)" ;;
    000)     echo -e "  ${RED}FAILED${NC}     Prism API no response (timeout/TLS)"; FAILED=1 ;;
    *)       echo -e "  ${YELLOW}NOTE${NC}       Prism API responds with HTTP $CODE" ;;
  esac

  # 4) Clock comparison – a skew of more than a few minutes makes registration fail
  REMOTE_DATE=$(curl -sk -I --max-time 5 "https://$TARGET:9440/" | grep -i '^date:' | cut -d' ' -f2- | tr -d '\r')
  if [ -n "$REMOTE_DATE" ]; then
    DIFF=$(( $(date -u +%s) - $(date -u -d "$REMOTE_DATE" +%s) ))
    DIFF=${DIFF#-}
    if [ "$DIFF" -le 60 ]; then
      echo -e "  ${GREEN}OK${NC}         time skew ${DIFF}s"
    else
      echo -e "  ${RED}FAILED${NC}     time skew ${DIFF}s – check NTP on both sides!"; FAILED=1
    fi
  else
    echo -e "  ${YELLOW}?${NC}          could not compare clocks"
  fi
  echo
done

if [ $FAILED -eq 0 ]; then
  echo -e "${GREEN}All required checks passed.${NC} Now test the opposite direction, if not done yet."
else
  echo -e "${RED}At least one required check failed${NC} – see red lines above."
fi
exit $FAILED