|
#!/bin/bash |
|
|
|
# whois.sh - Check whoisServer hostnames in metadata JSON files and optionally remove unresolvable ones |
|
# |
|
# This script scans all JSON files in the metadata/ directory, extracts whoisServer values, |
|
# and tests their DNS resolution. It can optionally remove entries that fail DNS checks. |
|
# |
|
# DNS Logic: A whoisServer is considered valid unless dig returns NXDOMAIN status. |
|
# This handles cases where servers exist but have no A records, CNAME-only records, etc. |
|
# |
|
# Concurrency: Uses xargs -P 10 to run up to 10 DNS checks in parallel for speed. |
|
# |
|
# Usage: |
|
# ./scripts/whois.sh # Show only failed DNS resolutions |
|
# ./scripts/whois.sh --show-all # Show both successful and failed resolutions |
|
# ./scripts/whois.sh --remove-broken # Remove failed whoisServer entries from JSON files |
|
# ./scripts/whois.sh --remove-broken --show-all # Remove broken entries and show all results |
|
|
|
set -euo pipefail # Exit on error, undefined vars, or pipe failures |
|
|
|
# ANSI color codes for colored output |
|
RED='\033[0;31m' |
|
GREEN='\033[0;32m' |
|
YELLOW='\033[1;33m' |
|
BLUE='\033[0;34m' |
|
NC='\033[0m' # No Color |
|
|
|
# Parse command line arguments |
|
REMOVE_BROKEN=false # Whether to actually remove broken whoisServer entries from JSON files |
|
SHOW_ALL=false # Whether to show successful DNS resolutions (default: only show failures) |
|
|
|
for arg in "$@"; do |
|
case $arg in |
|
--remove-broken) |
|
REMOVE_BROKEN=true |
|
;; |
|
--show-all) |
|
SHOW_ALL=true |
|
;; |
|
*) |
|
echo "Usage: $0 [--remove-broken] [--show-all]" |
|
echo " --remove-broken: Remove whoisServer entries that fail DNS resolution" |
|
echo " --show-all: Show both successful and failed DNS resolutions (default: only failed)" |
|
exit 1 |
|
;; |
|
esac |
|
done |
|
|
|
# Counters for final summary statistics |
|
total_files=0 # Total JSON files processed (not used currently) |
|
files_with_whois=0 # Total files containing whoisServer entries (not used currently) |
|
removed_servers=0 # Number of whoisServer entries actually removed from JSON files |
|
failed_dns=0 # Number of whoisServer hostnames that failed DNS resolution |
|
successful_dns=0 # Number of whoisServer hostnames that passed DNS resolution |
|
|
|
# Display startup banner and configuration |
|
echo "Checking whoisServer DNS resolution in metadata files..." |
|
if [[ "$REMOVE_BROKEN" == "true" ]]; then |
|
echo -e "${YELLOW}--remove-broken flag detected: will remove failed whoisServer entries${NC}" |
|
fi |
|
if [[ "$SHOW_ALL" == "true" ]]; then |
|
echo -e "${BLUE}--show-all flag detected: will show both successful and failed resolutions${NC}" |
|
else |
|
echo -e "${BLUE}Showing only failed DNS resolutions (use --show-all to see successful ones)${NC}" |
|
fi |
|
echo |
|
|
|
# DNS resolution test function - uses same logic as check_domain.sh |
|
# Returns true (0) if the hostname exists in DNS, false (1) if NXDOMAIN |
|
check_dns() { |
|
local server="$1" |
|
local rcode |
|
|
|
# Get the DNS response code (NXDOMAIN, NOERROR, etc.) |
|
rcode=$(timeout 5 dig "$server" A +noall +comments 2>/dev/null | grep 'status:' | awk '{print $6}' | tr -d ',') |
|
|
|
# Only consider NXDOMAIN as a failure (domain doesn't exist) |
|
# NOERROR means domain exists, even if it has no A records |
|
[[ "$rcode" != "NXDOMAIN" ]] |
|
} |
|
|
|
# Create temporary file to store file:whoisServer pairs for batch processing |
|
temp_file=$(mktemp) |
|
|
|
echo -e "${BLUE}Scanning JSON files...${NC}" |
|
|
|
# STEP 1: Find all JSON files that contain "whoisServer" key |
|
# Using grep -l for speed (only returns filenames, doesn't read file contents) |
|
# Then extract the actual whoisServer value using jq for each matching file |
|
grep -l '"whoisServer"' metadata/*.json 2>/dev/null | while read -r file; do |
|
# Extract whoisServer value, handling cases where it might be null or missing |
|
whois_server=$(jq -r '.whoisServer // empty' "$file" 2>/dev/null) |
|
if [[ -n "$whois_server" && "$whois_server" != "null" ]]; then |
|
# Store as "filename:hostname" for later processing |
|
echo "$file:$whois_server" >> "$temp_file" |
|
fi |
|
done |
|
|
|
# Count how many whoisServer entries we found |
|
file_count=$(wc -l < "$temp_file" 2>/dev/null || echo "0") |
|
|
|
if [[ $file_count -eq 0 ]]; then |
|
echo "No files with whoisServer entries found." |
|
exit 0 |
|
fi |
|
|
|
echo -e "${BLUE}Found $file_count files with whoisServer entries. Checking DNS resolution...${NC}" |
|
echo |
|
|
|
# STEP 2: Define function for concurrent DNS checking |
|
# This function will be exported and run in parallel subprocesses |
|
check_single_server() { |
|
local line="$1" |
|
# Parse the "filename:hostname" format |
|
IFS=':' read -r file whois_server <<< "$line" |
|
|
|
if [[ -z "$file" || -z "$whois_server" ]]; then return; fi |
|
|
|
# Use same DNS logic as check_domain.sh - only fail on NXDOMAIN |
|
local rcode |
|
rcode=$(timeout 5 dig "$whois_server" A +noall +comments 2>/dev/null | grep 'status:' | awk '{print $6}' | tr -d ',') |
|
|
|
# Only consider NXDOMAIN as a failure (domain doesn't exist) |
|
# NOERROR, SERVFAIL, REFUSED, etc. all mean the domain exists in some form |
|
if [[ "$rcode" != "NXDOMAIN" ]]; then |
|
echo "SUCCESS:$whois_server:$file" |
|
else |
|
echo "FAILED:$whois_server:$file" |
|
fi |
|
} |
|
|
|
# Export function so it's available to parallel subprocesses created by xargs |
|
export -f check_single_server |
|
|
|
# Create temporary file to store DNS check results |
|
results_file=$(mktemp) |
|
# Ensure both temp files are cleaned up when script exits |
|
trap "rm -f $temp_file $results_file" EXIT |
|
|
|
# STEP 3: Run DNS checks concurrently |
|
# Use xargs -P 10 to run up to 10 DNS checks in parallel for speed |
|
# Each line from temp_file becomes an argument to check_single_server function |
|
# Results are captured in results_file for processing |
|
cat "$temp_file" | xargs -I {} -P 10 bash -c 'check_single_server "{}"' > "$results_file" |
|
|
|
# STEP 4: Process DNS check results and optionally modify JSON files |
|
# Read results in format "STATUS:hostname:filename" and parse each line |
|
while IFS=':' read -r status whois_server file; do |
|
if [[ -z "$status" ]]; then continue; fi # Skip empty lines |
|
|
|
if [[ "$status" == "SUCCESS" ]]; then |
|
# DNS resolution succeeded - hostname has valid DNS records |
|
successful_dns=$((successful_dns + 1)) |
|
# Only show successful results if --show-all flag is set |
|
if [[ "$SHOW_ALL" == "true" ]]; then |
|
echo -e "${GREEN}✓${NC} $whois_server ($(basename "$file"))" |
|
fi |
|
elif [[ "$status" == "FAILED" ]]; then |
|
# DNS resolution failed - hostname has no DNS records (likely doesn't exist) |
|
failed_dns=$((failed_dns + 1)) |
|
# Always show failed results (this is what users care about) |
|
echo -e "${RED}✗${NC} $whois_server ($(basename "$file")) - DNS failed" |
|
|
|
# If --remove-broken flag is set, actually remove the whoisServer key from JSON |
|
if [[ "$REMOVE_BROKEN" == "true" ]]; then |
|
removed_servers=$((removed_servers + 1)) |
|
|
|
# Use jq to create a new JSON file without the whoisServer key |
|
# This preserves all other data and maintains proper JSON formatting |
|
json_temp=$(mktemp) |
|
jq 'del(.whoisServer)' "$file" > "$json_temp" |
|
|
|
# Atomically replace the original file with the modified version |
|
mv "$json_temp" "$file" |
|
|
|
echo -e "${YELLOW} Removed $whois_server from $(basename "$file")${NC}" |
|
fi |
|
fi |
|
done < "$results_file" |
|
|
|
# STEP 5: Display final summary statistics |
|
echo |
|
echo "Summary:" |
|
echo "=========" |
|
echo "Files with whoisServer: $file_count" |
|
echo -e "${GREEN}DNS resolution successful: $successful_dns${NC}" |
|
echo -e "${RED}DNS resolution failed: $failed_dns${NC}" |
|
|
|
# Show additional information based on flags used |
|
if [[ "$REMOVE_BROKEN" == "true" ]]; then |
|
echo -e "${YELLOW}whoisServer entries removed: $removed_servers${NC}" |
|
if [[ $removed_servers -gt 0 ]]; then |
|
echo |
|
echo -e "${YELLOW}Modified files should be reviewed and committed.${NC}" |
|
fi |
|
else |
|
# If user didn't use --remove-broken, remind them how to actually fix the issues |
|
if [[ $failed_dns -gt 0 ]]; then |
|
echo |
|
echo -e "${YELLOW}To remove failed whoisServer entries, run with --remove-broken flag${NC}" |
|
fi |
|
fi |