Chapter 14Lesson 01~95 minutes

DNS, TCP, and Endpoint Checks from Bash

Network automation is reliable only when it asks the right question at the right layer. DNS resolution, TCP reachability, TLS negotiation, and application health are related but distinct signals.

IntermediateNetworking & remote automationHands-on lab

Learning objectives

By the end of this lesson

  • Differentiate DNS, TCP, TLS, and application health.
  • Use portable capability checks for networking tools.
  • Apply explicit timeout budgets.
  • Avoid treating ping as service readiness.
  • Report the exact failing network layer.

1. Network checks answer different questions

LayerQuestionWhat it proves
DNSCan the hostname resolve?Name service and resolver path
TCPCan a connection reach host:port?Routing, firewall, listener
TLSCan a secure session be negotiated?Certificates/protocol/ciphers
HTTPDoes the application respond correctly?Service-level health

A successful DNS lookup does not prove a TCP listener exists, and an open TCP port does not prove the application is healthy.

2. Resolve hostnames with system tools

host=example.com

if command -v getent >/dev/null 2>&1; then
  getent ahosts "$host"
elif command -v nslookup >/dev/null 2>&1; then
  nslookup "$host"
else
  printf 'no supported DNS query tool found\n' >&2
  exit 69
fi

Tool availability varies across Linux, macOS, WSL, and Git Bash. A production script should either define a support matrix or provide a capability check.

3. getent follows the system name-service configuration

if getent hosts "$host" >/dev/null 2>&1; then
  printf 'dns=ok host=%s\n' "$host"
else
  printf 'dns=failed host=%s\n' "$host" >&2
fi

On Linux systems, getent can reflect NSS configuration rather than querying DNS alone, which is often exactly what application resolution uses.

4. Test TCP reachability without pretending it is application health

host=example.com
port=443

if command -v nc >/dev/null 2>&1; then
  if nc -z -w 3 "$host" "$port"; then
    printf 'tcp=ok host=%s port=%s\n' "$host" "$port"
  else
    printf 'tcp=failed host=%s port=%s\n' "$host" "$port" >&2
  fi
fi
Implementation differences

nc options differ between netcat variants. Validate flags on supported systems instead of assuming one implementation.

5. Bash /dev/tcp is convenient but Bash-specific

host=example.com
port=443

if timeout 3 bash -c \
  'exec 3<>/dev/tcp/"$1"/"$2"' _ "$host" "$port"; then
  printf 'tcp=ok\n'
else
  printf 'tcp=failed\n' >&2
fi

/dev/tcp is a Bash feature on builds that enable it. It is not a real filesystem path and it is not portable POSIX shell.

6. Use curl for application endpoint checks

if curl \
  --connect-timeout 3 \
  --max-time 5 \
  --fail \
  --silent \
  --show-error \
  https://example.com/health >/dev/null; then
  printf 'http_health=ok\n'
else
  status=$?
  printf 'http_health=failed curl_status=%d\n' "$status" >&2
fi

7. TLS checks need TLS-aware tooling

openssl s_client \
  -connect example.com:443 \
  -servername example.com \
  </dev/null 2>/dev/null |
openssl x509 -noout -subject -issuer -dates

This can inspect the presented certificate, but a robust certificate-validation workflow should define trust-store, hostname, expiry, and chain expectations explicitly.

8. ping tests ICMP reachability, not service readiness

ping -c 1 -W 2 example.com

ICMP may be blocked even when applications are healthy. Do not make ping a mandatory prerequisite for TCP or HTTP unless your environment guarantees ICMP behavior.

9. Every network probe needs a time budget

Network failures are often slow rather than immediate. Connection and total-operation timeouts keep health checks from hanging an entire deployment or CI stage.

10. Report the layer that failed

printf 'check=dns host=%s status=failed\n' "$host" >&2
printf 'check=tcp host=%s port=%s status=failed\n' "$host" "$port" >&2
printf 'check=http url=%s status=failed\n' "$url" >&2

Layer-specific diagnostics are more actionable than a generic “network failed.”

11. Hands-on lab: layered endpoint checker

mkdir -p "$HOME/devops-academy/bash/chapter14/lesson01"
cd "$HOME/devops-academy/bash/chapter14/lesson01"

cat > endpoint-check.sh <<'EOF'
#!/usr/bin/env bash
set -u
set -o pipefail

host=${1:-example.com}
url=${2:-https://example.com}

if command -v getent >/dev/null 2>&1; then
  if getent hosts "$host" >/dev/null 2>&1; then
    printf 'DNS OK host=%s\n' "$host"
  else
    printf 'DNS FAIL host=%s\n' "$host" >&2
  fi
fi

if command -v curl >/dev/null 2>&1; then
  if curl \
    --connect-timeout 3 \
    --max-time 5 \
    --fail \
    --silent \
    --show-error \
    "$url" >/dev/null; then
    printf 'HTTP OK url=%s\n' "$url"
  else
    status=$?
    printf 'HTTP FAIL url=%s status=%d\n' "$url" "$status" >&2
  fi
fi
EOF

chmod u+x endpoint-check.sh
./endpoint-check.sh

Verification checklist

12. Knowledge check

Question 1. Does successful DNS resolution prove the service is healthy?

Question 2. Why can ping be a misleading prerequisite?

Question 3. What should every network probe have?

Question 4. Why identify the failed network layer?

13. Summary

Network automation should test the layer you actually care about: DNS, TCP, TLS, or application protocol. Use timeouts, capability checks, and layer-specific diagnostics, and do not confuse reachability with readiness.

14. Further reading

  • GNU libc/getent documentation.
  • curl documentation — timeouts and failures.
  • OpenSSH and OpenSSL command documentation.
  • Bash Reference Manual — redirections including /dev/tcp.
Next lesson

SSH for Non-Interactive Remote Commands

Continue Chapter 14 by making remote networking and automation boundaries safer and more explicit.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.