← All posts
NOV 2024

Debug Website DNS, SSL, and Connectivity with Bash Script

A comprehensive bash script to debug website connectivity issues by checking DNS records, SSL certificates, and HTTP responses. Perfect for web developers and system administrators.

Terminal output showing DNS, SSL, and connectivity checks for a website
On this page

Bash Script for Debugging Website DNS, SSL, and Connectivity Issues

When managing websites across different hosting providers, debugging connectivity issues can be challenging. I created a bash script that helps identify DNS configurations, SSL certificate details, and site availability in one go.

What Does This Script Check?

  • DNS records (A, CNAME, NS) from multiple providers
  • SSL certificate information and expiry dates
  • HTTP/HTTPS responses and redirects
  • Website availability across different protocols

The Script

#!/bin/bash

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Function to print section headers
print_header() {
    echo -e "\n${YELLOW}=== $1 ===${NC}\n"
}

# Function to check if a command exists
command_exists() {
    command -v "$1" >/dev/null 2>&1
}

# Check required tools
check_requirements() {
    local missing_tools=()

    for tool in dig curl openssl whois; do
        if ! command_exists "$tool"; then
            missing_tools+=("$tool")
        fi
    done

    if [ ${#missing_tools[@]} -ne 0 ]; then
        echo -e "${RED}Error: The following required tools are missing:${NC}"
        printf '%s\n' "${missing_tools[@]}"
        exit 1
    fi
}

# Function to check DNS records
check_dns() {
    local domain=$1
    print_header "DNS Information for $domain"

    echo "A Record:"
    dig +short A "$domain"

    echo -e "\nCNAME Record:"
    dig +short CNAME "$domain"

    echo -e "\nNS Records:"
    dig +short NS "$domain"

    echo -e "\nDNS Resolution from different locations:"
    echo "Google DNS (8.8.8.8):"
    dig @8.8.8.8 +short "$domain"

    echo -e "\nCloudflare DNS (1.1.1.1):"
    dig @1.1.1.1 +short "$domain"
}

# Function to check SSL certificate
check_ssl() {
    local domain=$1
    print_header "SSL Certificate Information for $domain"

    echo "Attempting to retrieve SSL certificate info..."
    openssl s_client -connect "${domain}:443" -servername "$domain" </dev/null 2>/dev/null | openssl x509 -noout -text | grep -A 2 "Issuer:" -A 2 "Validity"

    echo -e "\nSSL Certificate Expiry:"
    echo | openssl s_client -servername "$domain" -connect "${domain}:443" 2>/dev/null | openssl x509 -noout -dates

    echo -e "\nComplete Certificate Chain:"
    openssl s_client -showcerts -connect "${domain}:443" -servername "$domain" </dev/null 2>/dev/null | grep -A 1 "issuer="
}

# Function to check HTTP response
check_http() {
    local domain=$1
    print_header "HTTP Response Information for $domain"

    echo "HTTP Response (http):"
    curl -IL "http://${domain}" 2>/dev/null | grep -E "HTTP|Location|Server"

    echo -e "\nHTTP Response (https):"
    curl -IL "https://${domain}" 2>/dev/null | grep -E "HTTP|Location|Server"
}

# Function to check website availability
check_availability() {
    local domain=$1
    print_header "Website Availability Check for $domain"

    local urls=("http://${domain}" "https://${domain}" "http://www.${domain}" "https://www.${domain}")

    for url in "${urls[@]}"; do
        echo -n "Testing $url: "
        http_code=$(curl -o /dev/null -s -w "%{http_code}" "$url")
        if [ "$http_code" -eq 200 ]; then
            echo -e "${GREEN}Available (HTTP $http_code)${NC}"
        else
            echo -e "${RED}Not available (HTTP $http_code)${NC}"
        fi
    done
}

# Main function
main() {
    if [ -z "$1" ]; then
        echo "Usage: $0 domain.com"
        exit 1
    fi

    local domain=$1

    # Remove protocol if included
    domain=${domain#http://}
    domain=${domain#https://}
    domain=${domain%/}

    # Check for required tools
    check_requirements

    # Run all checks
    check_dns "$domain"
    check_ssl "$domain"
    check_http "$domain"
    check_availability "$domain"
}

# Run the script
main "$@"

Sample Output

Here’s what the script output looks like when checking a domain:

=== DNS Information for shaharia.com ===

A Record:
172.66.46.247
172.66.45.9

CNAME Record:

NS Records:
ernest.ns.cloudflare.com.
noor.ns.cloudflare.com.

DNS Resolution from different locations:
Google DNS (8.8.8.8):
172.66.45.9
172.66.46.247

Cloudflare DNS (1.1.1.1):
172.66.46.247
172.66.45.9

=== SSL Certificate Information for shaharia.com ===

Attempting to retrieve SSL certificate info...
grep: Validity: No such file or directory

SSL Certificate Expiry:
notBefore=Nov 27 11:53:45 2024 GMT
notAfter=Feb 25 12:53:44 2025 GMT

Complete Certificate Chain:
issuer=C = US, O = Google Trust Services, CN = WE1
---

=== HTTP Response Information for shaharia.com ===

HTTP Response (http):
HTTP/1.1 301 Moved Permanently
Location: https://shaharia.com/
Server: cloudflare
HTTP/2 200 

HTTP Response (https):
HTTP/2 200 

=== Website Availability Check for shaharia.com ===

Testing http://shaharia.com: Not available (HTTP 301)
Testing https://shaharia.com: Available (HTTP 200)
Testing http://www.shaharia.com: Not available (HTTP 301)
Testing https://www.shaharia.com: Available (HTTP 200)

Usage

  1. Save the script as debug-website.sh
  2. Make it executable: chmod +x debug-website.sh
  3. Run: ./debug-website.sh yourdomain.com

Prerequisites

The script requires these tools:

  • dig
  • curl
  • openssl
  • whois

Feel free to use and modify this script for your needs. It’s especially helpful when migrating between hosting providers or debugging SSL/DNS issues.