Adding domains to DNSBL from a file
To add domains to DNSBL using a list from a file, use the script below.
#!/bin/bash
# =============================================================================
# Script for adding DNSBL domains to ispmanager from a text file
# =============================================================================
# Usage:
# 1. Create a dnsbl_list.txt file with DNSBL domains (one per line)
# 2. Run the script: ./add_dnsbl.sh
# 3. The script will add all domains from the list to ispmanager
# =============================================================================
# File name with the list of DNSBL domains (by default)
DNSBL_FILE="dnsbl_list.txt"
# Path to mgrctl
MGRCTL="/usr/local/mgr5/sbin/mgrctl"
# =============================================================================
# Dependency check
# =============================================================================
# Checking for mgrctl
if ! command -v "$MGRCTL" &>/dev/null; then
echo "Error: mgrctl is not found. Check ispmanager installation."
echo "Expected path: $MGRCTL"
exit 1
fi
# =============================================================================
# Functions
# =============================================================================
# Function for domain name validation
validate_domain() {
local domain="$1"
# Checking for empty strings
if [[ -z "$domain" ]]; then
return 1
fi
# Maximum domain length (253 characters according to RFC 1035)
if [[ ${#domain} -gt 253 ]]; then
return 1
fi
# Maximum length of one domain part (63 characters according to RFC 1035)
local IFS='.'
local -a parts
read -ra parts <<< "$domain"
for part in "${parts[@]}"; do
if [[ ${#part} -gt 63 ]] || [[ ${#part} -lt 1 ]]; then
return 1
fi
# Each part must contain only letters, numbers, and hyphens
# It cannot begin or end with a hyphen
if [[ ! "$part" =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$ ]]; then
return 1
fi
done
# The domain must have at least two parts (e.g., example.com)
if [[ ${#parts[@]} -lt 2 ]]; then
return 1
fi
# The last part (TLD) must be at least 2 characters long and contain only letters
local tld="${parts[-1]}"
if [[ ${#tld} -lt 2 ]] || [[ ! "$tld" =~ ^[a-zA-Z]+$ ]]; then
return 1
fi
# Checking the full domain format
if [[ ! "$domain" =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*\.[a-zA-Z]{2,}$ ]]; then
return 1
fi
return 0
}
# A function for obtaining a list of existing DNSBL domains
get_existing_dnsbl() {
$MGRCTL -m ispmgr emaildnsbl 2>/dev/null | grep -oP 'name=\K[^\s]+' || true
}
# Function for checking the existence of a DNSBL domain
dnsbl_exists() {
local domain="$1"
local existing
existing=$(get_existing_dnsbl)
if echo "$existing" | grep -qFx "$domain"; then
return 0 # Domain exists
else
return 1 # Domain does not exist
fi
}
# Function for adding DNSBL domain
add_dnsbl() {
local domain="$1"
local result
result=$($MGRCTL -m ispmgr emaildnsbl.edit name="$domain" sok=ok 2>&1)
echo "$result"
}
# Function for removing a DNSBL domain
delete_dnsbl() {
local domain="$1"
local result
result=$($MGRCTL -m ispmgr emaildnsbl.delete elid="$domain" 2>&1)
echo "$result"
}
# Function for displaying help
show_help() {
echo "Usage: $0 [options]"
echo ""
echo "Options:"
echo " -f, --file <path> Path to the file with the list of DNSBL domains"
echo " (by default: dnsbl_list.txt)"
echo " -c, --check Check the list without making any changes"
echo " -d, --delete Remove domains from the list instead of adding"
echo " -l, --list Show the current list of DNSBL domains in ispmanager"
echo " -h, --help Show help"
echo ""
echo "Примеры:"
echo " $0 # Add domains from dnsbl_list.txt"
echo " $0 -f my_dnsbl.txt # Add domains from my_dnsbl.txt"
echo " $0 -f /path/to/list.txt -c # heck domains from the specified file"
echo " $0 -d # Delete domains from dnsbl_list.txt"
}
# Function to display the current DNSBL list
show_list() {
echo "Current list of DNSBL domains in ispmanager:"
echo "=========================================="
local existing
existing=$(get_existing_dnsbl)
if [[ -z "$existing" ]]; then
echo "(list is empty)"
else
echo "$existing" | while read -r domain; do
echo " - $domain"
done
fi
}
# =============================================================================
# Processing command line arguments
# =============================================================================
MODE="add" # Default mode: add
FILE_SPECIFIED=false # Flag: whether the file was specified via -f
while [[ $# -gt 0 ]]; do
case $1 in
-f|--file)
if [[ -z "${2:-}" ]]; then
echo "Error: No file path specified for option $1"
exit 1
fi
DNSBL_FILE="$2"
FILE_SPECIFIED=true
shift 2
;;
-h|--help)
show_help
exit 0
;;
-l|--list)
show_list
exit 0
;;
-d|--delete)
MODE="delete"
shift
;;
-c|--check)
MODE="check"
shift
;;
-*)
echo "Error: Unknown option: $1"
show_help
exit 1
;;
*)
# Positional argument can be used as a file path
if [[ "$FILE_SPECIFIED" == false ]]; then
DNSBL_FILE="$1"
FILE_SPECIFIED=true
else
echo "Error: Unexpected argument: $1"
show_help
exit 1
fi
shift
;;
esac
done
# Checking for a file with a list of DNSBL domains
if [[ ! -f "$DNSBL_FILE" ]]; then
echo "Error: FIle '$DNSBL_FILE' not found."
echo ""
echo "Create a file with a list of DNSBL domains or specify the path using -f."
echo "File contents example:"
echo " zen.spamhaus.org"
echo " bl.spamcop.net"
echo " dnsbl.sorbs.net"
exit 1
fi
# =============================================================================
# Loading and validating a list of DNSBL domains from a file
# =============================================================================
# Loading domains from a file, skipping empty lines and comments
mapfile -t DNSBL_RAW < "$DNSBL_FILE"
DNSBL_LIST=()
INVALID_LINES=()
for LINE in "${DNSBL_RAW[@]}"; do
# Removing extra characters and spaces
LINE=$(echo "$LINE" | tr -d '\r' | xargs)
# Skipping empty lines and comments
if [[ -z "$LINE" ]] || [[ "$LINE" =~ ^[[:space:]]*# ]]; then
continue
fi
# Checking the validity of a domain name
if validate_domain "$LINE"; then
DNSBL_LIST+=("$LINE")
else
INVALID_LINES+=("$LINE")
fi
done
# Showing invalid strings, if any
if (( ${#INVALID_LINES[@]} > 0 )); then
echo "============================================"
echo " Warning: Invalid strings found"
echo "============================================"
echo ""
echo "The following strings are not valid domain names and will be skipped:"
for line in "${INVALID_LINES[@]}"; do
echo " ✗ $line"
done
echo ""
fi
# Checking if there is at least one valid domain
if (( ${#DNSBL_LIST[@]} == 0 )); then
echo "Error: No valid DNSBL domains found in the file '$DNSBL_FILE'."
echo ""
echo "Domain name requirements:"
echo " - Contains only letters, numbers, periods, and hyphens."
echo " - Minimum 2 parts (e.g., example.com)"
echo " - TLD (last part) minimum 2 letters"
echo " - Total length no more than 253 characters"
echo " - Each part no more than 63 characters"
exit 1
fi
# =============================================================================
# Basic logic
# =============================================================================
echo "============================================"
echo " Script for adding DNSBL domains"
echo "============================================"
echo ""
echo "Mode: $MODE"
echo "File: $DNSBL_FILE"
echo "Valid domains: ${#DNSBL_LIST[@]}"
if (( ${#INVALID_LINES[@]} > 0 )); then
echo "Invalid lines skipped: ${#INVALID_LINES[@]}"
fi
echo ""
# Showing a list of domains to process
echo "Domains to process:"
echo "---------------------"
for domain in "${DNSBL_LIST[@]}"; do
echo " - $domain"
done
echo ""
# Getting a list of existing DNSBL domains
EXISTING_DNSBL=$(get_existing_dnsbl)
if [[ -n "$EXISTING_DNSBL" ]]; then
EXISTING_COUNT=$(echo "$EXISTING_DNSBL" | wc -l)
echo "Current number of DNSBL domains in ispmanager: $EXISTING_COUNT"
else
echo "Current number of DNSBL domains in ispmanager: 0"
fi
# Check mode
if [[ "$MODE" == "check" ]]; then
echo ""
echo "============================================"
echo " Check mode (unchanged)"
echo "============================================"
NEW_COUNT=0
EXISTS_COUNT=0
for domain in "${DNSBL_LIST[@]}"; do
if dnsbl_exists "$domain"; then
echo " [ALREADY EXISTS] $domain"
((EXISTS_COUNT++))
else
echo " [NEW] $domain"
((NEW_COUNT++))
fi
done
echo ""
echo "Check result:"
echo " New domains: $NEW_COUNT"
echo " Already exists: $EXISTS_COUNT"
exit 0
fi
# Confirmation before execution
read -p "Resume? (y/n) [default: y]: " CONFIRM
CONFIRM=${CONFIRM:-y}
if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then
echo "Operation canceled."
exit 0
fi
echo ""
echo "============================================"
echo " Executing operation"
echo "============================================"
# Counters
SUCCESS_COUNT=0
SKIP_COUNT=0
ERROR_COUNT=0
# Обработка каждого домена
for domain in "${DNSBL_LIST[@]}"; do
echo ""
echo "Processing: $domain"
echo "----------------------------------------"
if [[ "$MODE" == "add" ]]; then
# Checking if the domain exists yet
if dnsbl_exists "$domain"; then
echo " ⚠ The domain is already on the DNSBL list."
((SKIP_COUNT++))
continue
fi
# Adding the domain
echo " Adding the DNSBL domain..."
RESULT=$(add_dnsbl "$domain")
# Checking the result
if echo "$RESULT" | grep -qi "error\|Error\|ERROR"; then
echo " ✗ Error: $RESULT"
((ERROR_COUNT++))
else
echo " ✓ Added successfully"
((SUCCESS_COUNT++))
fi
elif [[ "$MODE" == "delete" ]]; then
# Checking if the domain exists
if ! dnsbl_exists "$domain"; then
echo " ⚠ The domain is not on the DNSBL list."
((SKIP_COUNT++))
continue
fi
# Deleting the domain
echo " Deleting the DNSBL domain..."
RESULT=$(delete_dnsbl "$domain")
# Checking the result
if echo "$RESULT" | grep -qi "error\|Error\|ERROR"; then
echo " ✗ Error: $RESULT"
((ERROR_COUNT++))
else
echo " ✓ Deleted successfully"
((SUCCESS_COUNT++))
fi
fi
done
# =============================================================================
# Output report
# =============================================================================
echo ""
echo "============================================"
echo " Output report"
echo "============================================"
echo ""
echo "Mode: $MODE"
echo "Total processed: ${#DNSBL_LIST[@]}"
echo ""
if [[ "$MODE" == "add" ]]; then
echo " ✓ Deleted: $SUCCESS_COUNT"
echo " ⚠ Skipped: $SKIP_COUNT"
echo " ✗ Errors: $ERROR_COUNT"
elif [[ "$MODE" == "delete" ]]; then
echo " ✓ Deleted: $SUCCESS_COUNT"
echo " ⚠ Skipped: $SKIP_COUNT"
echo " ✗ Errors: $ERROR_COUNT"
fi
echo ""
echo "============================================"
echo " The operation is complete."
echo "============================================"
# Showing the updated list
echo ""
echo "Current list of DNSBL domains:"
show_list
exit 0
Create a file named add_dnsbl.sh in any directory:
touch add_dnsbl.shAdd the contents of the script to the file, then make the file executable:
chmod +x add_dnsbl.shBy default, the script takes domains from the dnsbl_list.txt file, which should be located in the same directory as the script: each individual domain should be written on a separate line.
To add domains from a specific text file, run the script with only the -f or --file option, for example:
./add_dnsbl.sh -f /home/user/dnsbl-domains.txtTo run the script in domain list check mode without adding, use the -c or --check option, for example:
./add_dnsbl.sh -cAdditional script options can be found by specifying the -h or --help option:
./add_dnsbl.sh -h