ispmanager 6

/
/
Добавление доменов в DNSBL из файла

Добавление доменов в DNSBL из файла

Чтобы добавить домены в DNSBL списком из файла, воспользуйтесь нашим скриптом.

Содержимое скрипта

#!/bin/bash

# =============================================================================
# Скрипт для добавления DNSBL доменов в ispmanager из списка в текстовом файле
# =============================================================================
# Использование:
#   1. Создайте файл dnsbl_list.txt с доменами DNSBL (по одному на строку)
#   2. Запустите скрипт: ./add_dnsbl.sh
#   3. Скрипт добавит все домены из списка в ispmanager
# =============================================================================

# Имя файла со списком DNSBL доменов (по умолчанию)
DNSBL_FILE="dnsbl_list.txt"

# Путь к mgrctl
MGRCTL="/usr/local/mgr5/sbin/mgrctl"

# =============================================================================
# Проверка зависимостей
# =============================================================================

# Проверяем наличие mgrctl
if ! command -v "$MGRCTL" &>/dev/null; then
   echo "Ошибка: mgrctl не найден. Проверьте установку ispmanager."
   echo "Ожидаемый путь: $MGRCTL"
   exit 1
fi

# =============================================================================
# Функции
# =============================================================================

# Функция для валидации доменного имени
validate_domain() {
   local domain="$1"
   
   # Проверка на пустоту
   if [[ -z "$domain" ]]; then
       return 1
   fi
   
   # Максимальная длина домена (253 символа по RFC 1035)
   if [[ ${#domain} -gt 253 ]]; then
       return 1
   fi
   
   # Максимальная длина одной части домена (63 символа по 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
       # Каждая часть должна содержать только буквы, цифры и дефисы
       # Не может начинаться или заканчиваться дефисом
       if [[ ! "$part" =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$ ]]; then
           return 1
       fi
   done
   
   # Домен должен иметь минимум 2 части (например, example.com)
   if [[ ${#parts[@]} -lt 2 ]]; then
       return 1
   fi
   
   # Последняя часть (TLD) должна быть минимум 2 символа и содержать только буквы
   local tld="${parts[-1]}"
   if [[ ${#tld} -lt 2 ]] || [[ ! "$tld" =~ ^[a-zA-Z]+$ ]]; then
       return 1
   fi
   
   # Проверка полного формата домена
   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
}

# Функция для получения списка существующих DNSBL доменов
get_existing_dnsbl() {
   $MGRCTL -m ispmgr emaildnsbl 2>/dev/null | grep -oP 'name=\K[^\s]+' || true
}

# Функция для проверки существования DNSBL домена
dnsbl_exists() {
   local domain="$1"
   local existing
   existing=$(get_existing_dnsbl)
   if echo "$existing" | grep -qFx "$domain"; then
       return 0  # Домен существует
   else
       return 1  # Домен не существует
   fi
}

# Функция для добавления DNSBL домена
add_dnsbl() {
   local domain="$1"
   local result
   result=$($MGRCTL -m ispmgr emaildnsbl.edit name="$domain" sok=ok 2>&1)
   echo "$result"
}

# Функция для удаления DNSBL домена
delete_dnsbl() {
   local domain="$1"
   local result
   result=$($MGRCTL -m ispmgr emaildnsbl.delete elid="$domain" 2>&1)
   echo "$result"
}

# Функция для показа справки
show_help() {
   echo "Использование: $0 [опции]"
   echo ""
   echo "Опции:"
   echo "  -f, --file <путь>   Путь к файлу со списком DNSBL доменов"
   echo "                      (по умолчанию: dnsbl_list.txt)"
   echo "  -c, --check         Проверить список без внесения изменений"
   echo "  -d, --delete        Удалить домены из списка вместо добавления"
   echo "  -l, --list          Показать текущий список DNSBL доменов в ispmanager"
   echo "  -h, --help          Показать эту справку"
   echo ""
   echo "Примеры:"
   echo "  $0                              # Добавить домены из dnsbl_list.txt"
   echo "  $0 -f my_dnsbl.txt              # Добавить домены из my_dnsbl.txt"
   echo "  $0 -f /path/to/list.txt -c      # Проверить домены из указанного файла"
   echo "  $0 -d                           # Удалить домены из dnsbl_list.txt"
}

# Функция для показа текущего списка DNSBL
show_list() {
   echo "Текущий список DNSBL доменов в ispmanager:"
   echo "=========================================="
   local existing
   existing=$(get_existing_dnsbl)
   if [[ -z "$existing" ]]; then
       echo "(список пуст)"
   else
       echo "$existing" | while read -r domain; do
           echo "  - $domain"
       done
   fi
}

# =============================================================================
# Обработка аргументов командной строки
# =============================================================================

MODE="add"  # Режим по умолчанию: добавление
FILE_SPECIFIED=false  # Флаг: был ли указан файл через -f

while [[ $# -gt 0 ]]; do
   case $1 in
       -f|--file)
           if [[ -z "${2:-}" ]]; then
               echo "Ошибка: Не указан путь к файлу для опции $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 "Ошибка: Неизвестная опция: $1"
           show_help
           exit 1
           ;;
       *)
           # Позиционный аргумент - можно использовать как путь к файлу
           if [[ "$FILE_SPECIFIED" == false ]]; then
               DNSBL_FILE="$1"
               FILE_SPECIFIED=true
           else
               echo "Ошибка: Неожиданный аргумент: $1"
               show_help
               exit 1
           fi
           shift
           ;;
   esac
done

# Проверяем наличие файла со списком DNSBL доменов
if [[ ! -f "$DNSBL_FILE" ]]; then
   echo "Ошибка: Файл '$DNSBL_FILE' не найден."
   echo ""
   echo "Создайте файл со списком DNSBL доменов или укажите путь через -f."
   echo "Пример содержимого файла:"
   echo "  zen.spamhaus.org"
   echo "  bl.spamcop.net"
   echo "  dnsbl.sorbs.net"
   exit 1
fi

# =============================================================================
# Загрузка и валидация списка DNSBL доменов из файла
# =============================================================================

# Загружаем домены из файла, пропуская пустые строки и комментарии
mapfile -t DNSBL_RAW < "$DNSBL_FILE"
DNSBL_LIST=()
INVALID_LINES=()

for LINE in "${DNSBL_RAW[@]}"; do
   # Удаляем лишние символы и пробелы
   LINE=$(echo "$LINE" | tr -d '\r' | xargs)
   
   # Пропускаем пустые строки и комментарии
   if [[ -z "$LINE" ]] || [[ "$LINE" =~ ^[[:space:]]*# ]]; then
       continue
   fi
   
   # Проверяем валидность доменного имени
   if validate_domain "$LINE"; then
       DNSBL_LIST+=("$LINE")
   else
       INVALID_LINES+=("$LINE")
   fi
done

# Показываем невалидные строки, если есть
if (( ${#INVALID_LINES[@]} > 0 )); then
   echo "============================================"
   echo "  Предупреждение: найдены некорректные строки"
   echo "============================================"
   echo ""
   echo "Следующие строки не являются валидными доменными именами и будут пропущены:"
   for line in "${INVALID_LINES[@]}"; do
       echo "  ✗ $line"
   done
   echo ""
fi

# Проверяем, есть ли хоть один валидный домен
if (( ${#DNSBL_LIST[@]} == 0 )); then
   echo "Ошибка: В файле '$DNSBL_FILE' не найдено ни одного корректного DNSBL домена."
   echo ""
   echo "Требования к доменному имени:"
   echo "  - Содержит только буквы, цифры, точки и дефисы"
   echo "  - Минимум 2 части (например: example.com)"
   echo "  - TLD (последняя часть) минимум 2 буквы"
   echo "  - Общая длина не более 253 символов"
   echo "  - Каждая часть не более 63 символов"
   exit 1
fi

# =============================================================================
# Основная логика
# =============================================================================

echo "============================================"
echo "  Скрипт добавления DNSBL доменов"
echo "============================================"
echo ""
echo "Режим: $MODE"
echo "Файл: $DNSBL_FILE"
echo "Валидных доменов: ${#DNSBL_LIST[@]}"
if (( ${#INVALID_LINES[@]} > 0 )); then
   echo "Пропущено некорректных строк: ${#INVALID_LINES[@]}"
fi
echo ""

# Показываем список доменов для обработки
echo "Домены для обработки:"
echo "---------------------"
for domain in "${DNSBL_LIST[@]}"; do
   echo "  - $domain"
done
echo ""

# Получаем список существующих DNSBL доменов
EXISTING_DNSBL=$(get_existing_dnsbl)
if [[ -n "$EXISTING_DNSBL" ]]; then
   EXISTING_COUNT=$(echo "$EXISTING_DNSBL" | wc -l)
   echo "Текущее количество DNSBL доменов в ispmanager: $EXISTING_COUNT"
else
   echo "Текущее количество DNSBL доменов в ispmanager: 0"
fi

# Режим проверки
if [[ "$MODE" == "check" ]]; then
   echo ""
   echo "============================================"
   echo "  Режим проверки (без изменений)"
   echo "============================================"
   
   NEW_COUNT=0
   EXISTS_COUNT=0
   
   for domain in "${DNSBL_LIST[@]}"; do
       if dnsbl_exists "$domain"; then
           echo "  [УЖЕ ЕСТЬ] $domain"
           ((EXISTS_COUNT++))
       else
           echo "  [НОВЫЙ]    $domain"
           ((NEW_COUNT++))
       fi
   done
   
   echo ""
   echo "Результат проверки:"
   echo "  Новых доменов: $NEW_COUNT"
   echo "  Уже существует: $EXISTS_COUNT"
   exit 0
fi

# Подтверждение перед выполнением
read -p "Продолжить? (y/n) [default: y]: " CONFIRM
CONFIRM=${CONFIRM:-y}
if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then
   echo "Операция отменена."
   exit 0
fi

echo ""
echo "============================================"
echo "  Выполнение операции"
echo "============================================"

# Счётчики
SUCCESS_COUNT=0
SKIP_COUNT=0
ERROR_COUNT=0

# Обработка каждого домена
for domain in "${DNSBL_LIST[@]}"; do
   echo ""
   echo "Обработка: $domain"
   echo "----------------------------------------"
   
   if [[ "$MODE" == "add" ]]; then
       # Проверяем, существует ли уже домен
       if dnsbl_exists "$domain"; then
           echo "  ⚠ Домен уже существует в списке DNSBL"
           ((SKIP_COUNT++))
           continue
       fi
       
       # Добавляем домен
       echo "  Добавление DNSBL домена..."
       RESULT=$(add_dnsbl "$domain")
       
       # Проверяем результат
       if echo "$RESULT" | grep -qi "error\|Error\|ERROR"; then
           echo "  ✗ Ошибка: $RESULT"
           ((ERROR_COUNT++))
       else
           echo "  ✓ Успешно добавлен"
           ((SUCCESS_COUNT++))
       fi
       
   elif [[ "$MODE" == "delete" ]]; then
       # Проверяем, существует ли домен
       if ! dnsbl_exists "$domain"; then
           echo "  ⚠ Домен не найден в списке DNSBL"
           ((SKIP_COUNT++))
           continue
       fi
       
       # Удаляем домен
       echo "  Удаление DNSBL домена..."
       RESULT=$(delete_dnsbl "$domain")
       
       # Проверяем результат
       if echo "$RESULT" | grep -qi "error\|Error\|ERROR"; then
           echo "  ✗ Ошибка: $RESULT"
           ((ERROR_COUNT++))
       else
           echo "  ✓ Успешно удалён"
           ((SUCCESS_COUNT++))
       fi
   fi
done

# =============================================================================
# Итоговый отчёт
# =============================================================================

echo ""
echo "============================================"
echo "  Итоговый отчёт"
echo "============================================"
echo ""
echo "Режим: $MODE"
echo "Всего обработано: ${#DNSBL_LIST[@]}"
echo ""

if [[ "$MODE" == "add" ]]; then
   echo "  ✓ Добавлено:   $SUCCESS_COUNT"
   echo "  ⚠ Пропущено:   $SKIP_COUNT"
   echo "  ✗ Ошибок:      $ERROR_COUNT"
elif [[ "$MODE" == "delete" ]]; then
   echo "  ✓ Удалено:     $SUCCESS_COUNT"
   echo "  ⚠ Пропущено:   $SKIP_COUNT"
   echo "  ✗ Ошибок:      $ERROR_COUNT"
fi

echo ""
echo "============================================"
echo "  Операция завершена"
echo "============================================"

# Показываем обновлённый список
echo ""
echo "Текущий список DNSBL доменов:"
show_list

exit 0

Создайте файл с именеме add_dnsbl.sh в любой директории:

touch add_dnsbl.sh

Внести в файле содержимое скрипта, а затем сделайте файл исполняемым:

chmod +x add_dnsbl.sh

По умолчанию скрипт берет домены из файла dnsbl_list.txt, который должен быть расположен в одном каталоге со скриптом: каждый отдельный домен должен быть записан в отдельную строку.

Чтобы добавить домены из определенного текстового файла, запустите скрипт только с ключом для указания файла -fили --file например:

./add_dnsbl.sh -f /home/user/dnsbl-domains.txt

Чтобы запустить скрипт в режиме проверки списка доменов без их добавления, используйте ключ -c или --check, например:

./add_dnsbl.sh -c

Дополнительные ключи скрипта можно узнать, указав ключ -h или --help:

./add_dnsbl.sh -h