ispmanager 6

/
/
Bulk adding of domains in ispmanager 6

Bulk adding of domains in ispmanager 6

To bulk add domains in ispmanager 6, you can use the script below. The script allows you to add domains via the CLI in a semi-automated mode.

The script

#!/bin/bash

set -euo pipefail

# Configuration parameters
DEFAULT_USER="www-root"              # Name of the dafault user
AVAILABLE_PHP_MODES=(php_mode_fcgi_nginxfpm php_mode_fcgi_apache php_mode_cgi php_mode_mod)
AVAILABLE_TECHNOLOGIES=(nodejs python)  # Supported alternative technologies

# Checking for mgrctl
if ! command -v /usr/local/mgr5/sbin/mgrctl &>/dev/null; then
   echo "Error: mgrctl not found. Please check ispmanager installation."
   exit 1
fi

# Checking for the domains.txt file
if [[ ! -f "domains.txt" ]]; then
   echo "Error: File 'domains.txt' not found."
   exit 1
fi

# Function to check if NAT is enabled
is_nat_enabled() {
   local nat_settings=$(/usr/local/mgr5/sbin/mgrctl -m ispmgr nat.settings 2>/dev/null)
   if echo "$nat_settings" | grep -q 'use_nat=on'; then
       return 0  # NAT enabled
   else
       return 1  # NAT disabled
   fi
}

# Function for obtaining NAT settings (external IP)
get_nat_public_ip() {
   /usr/local/mgr5/sbin/mgrctl -m ispmgr nat.settings 2>/dev/null | grep -oP 'public_ip_0=\K[0-9.]+' || true
}

# Function for obtaining private IP
get_nat_private_ip() {
   /usr/local/mgr5/sbin/mgrctl -m ispmgr nat.settings 2>/dev/null | grep -oP 'private_ip_0=\K[0-9.]+' || true
}

# Function for obtaining a list of IP addresses from the control panel
get_available_ips() {
   /usr/local/mgr5/sbin/mgrctl -m ispmgr ipaddrlist 2>/dev/null | grep -oP 'name=\K[0-9.]+' || true
}

# Function for obtaining a default IP from the control panel
get_default_ip() {
   /usr/local/mgr5/sbin/mgrctl -m ispmgr ipaddrlist 2>/dev/null | grep 'default=yes' | grep -oP 'name=\K[0-9.]+' || true
}

# Loading domains from a file, skipping empty lines
mapfile -t DOMAINS_RAW < domains.txt
DOMAINS=()
for DOMAIN in "${DOMAINS_RAW[@]}"; do
   DOMAIN=$(echo "$DOMAIN" | tr -d '\r' | xargs)
   if [[ -n "$DOMAIN" ]]; then
       DOMAINS+=("$DOMAIN")
   fi
done

if (( ${#DOMAINS[@]} == 0 )); then
   echo "Error: No domains found in domains.txt"
   exit 1
fi

echo "Processing ${#DOMAINS[@]} domains..."

# Checking NAT settings
NAT_PUBLIC_IP=$(get_nat_public_ip)
NAT_PRIVATE_IP=$(get_nat_private_ip)
PANEL_IPS=$(get_available_ips)
DEFAULT_IP=$(get_default_ip)

# Defining IP for domain creation
if is_nat_enabled && [[ -n "$NAT_PUBLIC_IP" ]]; then
   echo -e "\nNAT configuration detected:"
   echo "  Private IP: $NAT_PRIVATE_IP"
   echo "  Public IP:  $NAT_PUBLIC_IP"
   DOMAIN_IP="$NAT_PUBLIC_IP"
   echo -e "\nUsing public IP for domains: $DOMAIN_IP"
else
   # Without NAT, using the IP from the panel
   if [[ -z "$PANEL_IPS" ]]; then
       echo "Error: No IP addresses found in ispmanager!"
       echo "Please add IP addresses first: ispmanager → Settings → IP addresses"
       exit 1
   fi
   
   mapfile -t IP_LIST <<< "$PANEL_IPS"
   
   echo -e "\nAvailable IP addresses in ispmanager:"
   for i in "${!IP_LIST[@]}"; do
       ip="${IP_LIST[$i]}"
       mark=""
       if [[ "$ip" == "$DEFAULT_IP" ]]; then
           mark=" [DEFAULT]"
       fi
       echo "  $((i+1))) ${ip}${mark}"
   done
   
   if (( ${#IP_LIST[@]} == 1 )); then
       DOMAIN_IP="${IP_LIST[0]}"
       echo -e "\nUsing IP: $DOMAIN_IP"
   else
       # If there is a default IP, we suggest it as the default choice
       if [[ -n "$DEFAULT_IP" ]]; then
           echo -e "\nDefault IP detected: $DEFAULT_IP"
           read -p "Use default IP for all domains? (y/n) [default: y]: " USE_DEFAULT
           USE_DEFAULT=${USE_DEFAULT:-y}
           if [[ "$USE_DEFAULT" =~ ^[Yy]$ ]]; then
               DOMAIN_IP="$DEFAULT_IP"
               echo "Using default IP: $DOMAIN_IP"
           else
               echo -e "\nSelect IP for all domains:"
               select IP_CHOICE in "${IP_LIST[@]}"; do
                   if [[ -n "$IP_CHOICE" ]]; then
                       DOMAIN_IP="$IP_CHOICE"
                       echo "Selected IP: $DOMAIN_IP"
                       break
                   fi
                   echo "Invalid selection. Try again."
               done
           fi
       else
           echo -e "\nSelect IP for all domains:"
           select IP_CHOICE in "${IP_LIST[@]}"; do
               if [[ -n "$IP_CHOICE" ]]; then
                   DOMAIN_IP="$IP_CHOICE"
                   echo "Selected IP: $DOMAIN_IP"
                   break
               fi
               echo "Invalid selection. Try again."
           done
       fi
   fi
fi

for DOMAIN in "${DOMAINS[@]}"; do
   echo -e "\n========================================"
   echo "Processing domain: $DOMAIN"
   echo "========================================"
   
   # Initializing variables for each iteration
   PHP_MODE=""
   TECHNOLOGY=""
   HANDLER=""
   CMD_ARGS=""
   SSL_ALLOWED=false
   
   # Requesting a user for a domain (with a repeated request if an error occurs)
   while true; do
       read -p "Enter user for the domain ($DOMAIN) [default: ${DEFAULT_USER}]: " USERNAME
       if [[ -z "$USERNAME" ]]; then
           USERNAME="${DEFAULT_USER}"
       fi

       # Checking that the username is not a number (UID)
       if [[ "$USERNAME" =~ ^[0-9]+$ ]]; then
           echo "Error: Username cannot be a number. Please enter a valid username."
           read -p "Try again? (y/n) [default: y]: " TRY_AGAIN
           if [[ -z "$TRY_AGAIN" ]] || [[ "$TRY_AGAIN" =~ ^[Yy]$ ]]; then
               continue
           else
               echo "Skipping domain creation."
               continue 2
           fi
       fi

       # Checking the existence of a user by name
       if getent passwd "$USERNAME" &>/dev/null; then
           echo "User exists: $USERNAME"
           break
       else
           echo "Error: User does not exist: $USERNAME"
           read -p "Try again? (y/n) [default: y]: " TRY_AGAIN
           if [[ -z "$TRY_AGAIN" ]] || [[ "$TRY_AGAIN" =~ ^[Yy]$ ]]; then
               continue
           else
               echo "Skipping domain creation."
               continue 2  # Skipping the current iteration of the for loop
           fi
       fi
   done

   # Retrieving information about user capabilities
   USER_PROFILE=$(/usr/local/mgr5/sbin/mgrctl -m ispmgr user.edit elid="$USERNAME" 2>&1)

   # Checking if the user is allowed to use SSL/Let's Encrypt
   if echo "$USER_PROFILE" | grep -q "limit_ssl=on"; then
       SSL_ALLOWED=true
       echo "✓ SSL certificates allowed for user $USERNAME"
   else
       SSL_ALLOWED=false
       echo "⚠ SSL certificates DISABLED for user $USERNAME (limit_ssl=off)"
   fi

   # Checking for available technologies
   ENABLED_PHP_MODES=()
   ENABLED_TECHNOLOGIES=()
   
   # Checking available PHP modes
   for MODE in "${AVAILABLE_PHP_MODES[@]}"; do
       if echo "$USER_PROFILE" | grep -q "$MODE=on"; then
           ENABLED_PHP_MODES+=( "$MODE" )
       fi
   done
   
   # Checking for available alternative technologies
   for TECH in "${AVAILABLE_TECHNOLOGIES[@]}"; do
       if echo "$USER_PROFILE" | grep -q "limit_$TECH=on"; then
           ENABLED_TECHNOLOGIES+=( "$TECH" )
       fi
   done

   # Collecting all available technology options
   AVAILABLE_OPTIONS=()
   
   if (( ${#ENABLED_PHP_MODES[@]} > 0 )); then
       AVAILABLE_OPTIONS+=( "php" )
   fi
   
   for TECH in "${ENABLED_TECHNOLOGIES[@]}"; do
       AVAILABLE_OPTIONS+=( "$TECH" )
   done

   # If there are no available technologies
   if (( ${#AVAILABLE_OPTIONS[@]} == 0 )); then
       echo "Error: No technologies enabled for user $USERNAME."
       echo "   Please enable at least one of: PHP, Node.js, or Python"
       continue
   fi

   # If only one technology is available
   if (( ${#AVAILABLE_OPTIONS[@]} == 1 )); then
       TECHNOLOGY="${AVAILABLE_OPTIONS[0]}"
       echo "Using technology: $TECHNOLOGY"
   else
       # If several technologies are available, offering options
       echo "Available technologies for user $USERNAME:"
       select TECH_SELECTION in "${AVAILABLE_OPTIONS[@]}"; do
           if [[ -n "$TECH_SELECTION" ]]; then
               TECHNOLOGY="$TECH_SELECTION"
               echo "Selected technology: $TECHNOLOGY"
               break
           fi
           echo "Invalid selection. Try again."
       done
   fi

   # Creating parameters depending on the selected technology
   if [[ "$TECHNOLOGY" == "php" ]]; then
       # Selection of PHP mode
       if (( ${#ENABLED_PHP_MODES[@]} > 1 )); then
           echo -e "\nAvailable PHP modes:"
           select MODE in "${ENABLED_PHP_MODES[@]}"; do
               if [[ -n "$MODE" ]]; then
                   PHP_MODE="$MODE"
                   break
               fi
               echo "Invalid selection. Try again."
           done
       else
           PHP_MODE="${ENABLED_PHP_MODES[0]}"
       fi
       echo "Using PHP mode: $PHP_MODE"
       HANDLER="handler_php"
       CMD_ARGS="site_php=on site_nodejs=off site_python=off site_php_mode=$PHP_MODE"
       
   elif [[ "$TECHNOLOGY" == "nodejs" ]]; then
       NODEJS_VERSION=$(echo "$USER_PROFILE" | grep -Eo 'limit_nodejs_version=[^[:space:]]+' | cut -d '=' -f 2)
       HANDLER="handler_nodejs"
       if [[ -n "$NODEJS_VERSION" ]]; then
           CMD_ARGS="site_php=off site_nodejs=on site_python=off site_nodejs_version=$NODEJS_VERSION"
           echo "Using Node.js version: $NODEJS_VERSION"
       else
           CMD_ARGS="site_php=off site_nodejs=on site_python=off"
           echo "Using Node.js (default version)"
       fi
       
   elif [[ "$TECHNOLOGY" == "python" ]]; then
       PYTHON_VERSION=$(echo "$USER_PROFILE" | grep -Eo 'limit_python_version=[^[:space:]]+' | cut -d '=' -f 2)
       HANDLER="handler_python"
       if [[ -n "$PYTHON_VERSION" ]]; then
           CMD_ARGS="site_php=off site_nodejs=off site_python=on site_python_version=$PYTHON_VERSION site_python_server_path=server.py"
           echo "Using Python version: $PYTHON_VERSION"
       else
           CMD_ARGS="site_php=off site_nodejs=off site_python=on site_python_server_path=server.py"
           echo "Using Python (default version)"
       fi
   fi

   # Defining the site's home directory
   HOME_DIR="www/$DOMAIN"
   
   #Creating a domain via site.edit
   echo -e "\nCreating domain '$DOMAIN' with user '$USERNAME'..."
   echo "Home: $HOME_DIR"
   echo "IP Address: $DOMAIN_IP"
   echo "Handler: $HANDLER"
   if [[ -n "$CMD_ARGS" ]]; then
       echo "Parameters: $CMD_ARGS"
   fi
   
   if RESULT=$(/usr/local/mgr5/sbin/mgrctl -m ispmgr site.edit \
       site_name="$DOMAIN" \
       site_home="$HOME_DIR" \
       site_ipaddrs="$DOMAIN_IP" \
       site_ipsrc=manual \
       site_owner="$USERNAME" \
       site_email="webmaster@$DOMAIN" \
       site_handler="$HANDLER" \
       $CMD_ARGS \
       sok=ok 2>&1); then
       
       echo "✓ Domain created successfully."
       
       # Generating of SSL certificate (only if allowed for user)
       echo -e "\nSSL Certificate:"
       if [[ "$SSL_ALLOWED" == false ]]; then
           echo "⚠ SSL certificate requestion SKIPPED: SSL is disabled in user profile ($USERNAME)"
           echo "   To enable: ispmanager → Users → Edit user → Access → 'SSL' option"
       else
           read -p "Request SSL certificate for this domain? (y/n) [default: y]: " CERTIFICATE
           if [[ -z "$CERTIFICATE" ]] || [[ "$CERTIFICATE" =~ ^[Yy]$ ]]; then
               echo "Requesting SSL certificate for domain '$DOMAIN'..."
               
               if GEN_RESULT=$(/usr/local/mgr5/sbin/mgrctl -m ispmgr letsencrypt.generate \
                   username="$USERNAME" \
                   domain_name="$DOMAIN" \
                   domain="$DOMAIN" \
                   email="webmaster@$DOMAIN" \
                   enable_cert=on \
                   sok=ok 2>&1); then
                   
                   echo "✓ SSL certificate requested successfully."
               else
                   echo "✗ Error generating SSL certificate:"
                   echo "$GEN_RESULT"
                   echo "   Hint: Check if 'SSL' option is enabled for user $USERNAME"
               fi
           else
               echo "SSL certificate requestion skipped by user request."
           fi
       fi
   else
       echo "✗ Error creating domain:"
       echo "$RESULT"
       continue
   fi

done

echo -e "\n========================================"
echo "✓ All domains have been processed!"
echo "========================================"

To bulk add domains, follow these steps:

  1. Connect to the server via SSH as the root user;
  2. Download and place the script in any accessible directory, such as /root;
  3. Make the script executable by running chmod +x add_domains_ispmgr.sh;
  4. Prepare and place a text file named domains.txt next to it, containing the names of the desired domains (one line per domain);
  5. Run the script with the command ./sh add_domains_ispmgr.sh and go through all the steps for each domain:
    1. Enter the username of the user the domain will be added to;
    2. Select a handler;
    3. Select the handler mode;
    4. Determine whether to add a Let's Encrypt SSL certificate.

For example, this is what adding the domain domain.com with PHP-FPM mode and issuing a certificate for user user01 would look like:

Processing domain: domain.com 
========================================
Enter user for the domain (domain.com ) [default: www-root]: 
User exists: user01
✓ SSL certificates allowed for user user01
Available technologies for user user01:
1) php
2) nodejs
3) python
#? 1
Selected technology: php

Available PHP modes:
1) php_mode_fcgi_nginxfpm
2) php_mode_cgi
3) php_mode_mod
#? 1
Using PHP mode: php_mode_fcgi_nginxfpm

Creating domain 'domain.com' with user 'user01'...
Docroot: /var/www/user01/data/www/domain.com
Parameters: php=on php_mode=php_mode_fcgi_nginxfpm
✓ Domain created successfully.

SSL Certificate:
Request SSL certificate for this domain? (y/n) [default: y]: y
Requesting SSL certificate for domain 'domain.com'...
✓ SSL certificate requested successfully.