#!/bin/bash

#ServerLimit 64
MAX_CONNECTIONS=10000

#MaxRequestWorkers 4096
MAX_CONNECTIONS_WORKERS=10000

KILLBOT_ACCOUNT_TOKEN="p6CmXezQY"

# Maximum number of simultaneous connections for bots
MAX_CONNECTIONS_BOTS=50

# Maximum number of simultaneous connections from a single IP to the verification page
MAX_CONNECTIONS_IP_VP=20

MAX_OPEN_FILES=1000000
MAX_OPEN_FILES_SYS=3000000
MAX_PROCESSES=20000
KILLBOT_SESSION_LIFETIME=86400 #sec

set -e # Exit immediately if any command fails

sudo apt install -y socat curl

CURRENT_SERVER_IP=$(curl -s http://checkip.amazonaws.com)
#echo "Current server IP: $CURRENT_SERVER_IP"

#Get information about the Ubuntu version
OS_ID=$(lsb_release -is)
OS_VERSION=$(lsb_release -rs)

if [ "$(id -u)" -ne 0 ]; then
    echo "This script must be run with sudo!"
    exit 1
fi

# Check that the system is Ubuntu and version is 20.04 or 22.04
if [[ "$OS_ID" == "Ubuntu" && ("$OS_VERSION" == "20.04" || "$OS_VERSION" == "22.04") ]]; then
    echo "Running on Ubuntu $OS_VERSION is allowed."
else
    echo "Error: The script can only run on Ubuntu 20.04 or 22.04."
    exit 1
fi

sudo apt update -y

sudo apt install -y apache2 php libapache2-mod-php

sudo chown -R www-data:www-data /var/www/html

sudo a2enmod ssl
sudo a2enmod rewrite
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod headers
sudo a2dismod status

sudo apt install libapache2-mod-security2 -y

sudo apt install cron -y
sudo systemctl enable cron
sudo systemctl start cron

apache_check=$(sudo apachectl configtest 2>&1)

if echo "$apache_check" | grep -q "Syntax OK"; then
    echo "Apache configuration for $domain_without_www is correct."
else
    echo "Apache configuration error for $domain_without_www: $apache_check"    
    exit 1
fi

# These parameters increase the backlog size for half-open TCP connections
# and enable SYN cookies protection to resist TCP SYN flood attacks.
cat > /etc/sysctl.d/99-syn.conf <<'EOF'
# Tuned to be resilient to SYN floods
net.ipv4.tcp_syncookies = 1
net.core.somaxconn = 8192
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_synack_retries = 3
EOF

sysctl --system
sysctl net.ipv4.tcp_syncookies net.core.somaxconn net.ipv4.tcp_max_syn_backlog net.ipv4.tcp_synack_retries

# Install acme.sh for wildcard SSL certificates

# Check if acme.sh is already installed
if [ ! -f "/root/.acme.sh/acme.sh" ]; then
    echo "Installing acme.sh..."
    curl https://get.acme.sh | sh -s email=admin@killbot.ru
else
    echo "acme.sh is already installed, skipping installation..."
fi

# Create symbolic link (force overwrite if exists)
sudo ln -sf /root/.acme.sh/acme.sh /usr/local/bin/acme.sh
sudo chmod +x /usr/local/bin/acme.sh

echo "Custom DNS hook for Reg.ru with SSL certificate support created successfully!"

# Create DNS hooks for Russian hosting providers
sudo tee /root/.acme.sh/dnsapi/dns_beget.sh > /dev/null <<'EOF'
#!/usr/bin/env sh

# Beget DNS API integration for acme.sh
# Corrected implementation using changeRecords endpoint
# https://beget.com/

sudo systemctl stop nginx
sudo apt remove nginx nginx-common
sudo apt autoremove

# Путь к файлу конфигурации
PORTS_CONF="/etc/apache2/ports.conf"

# Проверяем, существует ли файл и содержит ли он строку с портом 443
if [ -f "$PORTS_CONF" ] && grep -q ":443" "$PORTS_CONF"; then
    echo "Файл $PORTS_CONF уже содержит конфигурацию с портом :443. Ничего не делаем."
else
    echo "Создаем новый файл $PORTS_CONF с нужной конфигурацией..."
    
    # Создаем резервную копию, если файл существует
    if [ -f "$PORTS_CONF" ]; then
        cp "$PORTS_CONF" "$PORTS_CONF.backup.$(date +%Y%m%d_%H%M%S)"
        echo "Создана резервная копия существующего файла"
    fi
    
    # Создаем новый файл с нужным содержимым
    cat > "$PORTS_CONF" << 'EOF'
Listen *:80 backlog=65535
Listen *:443 backlog=65535
EOF
    
    echo "Файл $PORTS_CONF успешно создан/обновлен со следующим содержимым:"
    echo "----------------------------------------"
    cat "$PORTS_CONF"
    echo "----------------------------------------"
fi

dns_beget_add() {
  fulldomain=$1
  txtvalue=$2

  BEGET_LOGIN="${BEGET_LOGIN:-$(_readaccountconf_mutable BEGET_LOGIN)}"
  BEGET_PASSWORD="${BEGET_PASSWORD:-$(_readaccountconf_mutable BEGET_PASSWORD)}"

  if [ -z "$BEGET_LOGIN" ] || [ -z "$BEGET_PASSWORD" ]; then
    _err "You didn't specify Beget login or password."
    return 1
  fi

  _saveaccountconf_mutable BEGET_LOGIN "$BEGET_LOGIN"
  _saveaccountconf_mutable BEGET_PASSWORD "$BEGET_PASSWORD"

  _info "Adding TXT record for $fulldomain"

  # 1️⃣ Получаем все текущие TXT из локального кеша (если есть)
  _readaccountconf BEGET_TXT_CACHE
  if [ -n "$BEGET_TXT_CACHE" ]; then
    current_txts="$BEGET_TXT_CACHE"
  else
    current_txts=""
  fi

  # 2️⃣ Добавляем новое значение в список
  new_txts="${current_txts}${txtvalue} "

  # 3️⃣ Формируем JSON, добавляя все TXT записи
  txt_json=""
  for t in $new_txts; do
    txt_json="${txt_json}{\"priority\":10,\"value\":\"$t\"},"
  done
  txt_json="[${txt_json%,}]"

  input_data=$(printf '{"fqdn":"%s","records":{"TXT":%s}}' "$fulldomain" "$txt_json")

  # 4️⃣ Отправляем запрос
  response=$(curl -s "https://api.beget.com/api/dns/changeRecords" \
    -G \
    --data-urlencode "login=$BEGET_LOGIN" \
    --data-urlencode "passwd=$BEGET_PASSWORD" \
    --data-urlencode "input_format=json" \
    --data-urlencode "output_format=json" \
    --data-urlencode "input_data=$input_data")

  if echo "$response" | grep -q 'true'; then
    _info "✅ TXT record added OK"
    _saveaccountconf_mutable BEGET_TXT_CACHE "$new_txts"
    return 0
  else
    _err "❌ Failed to add TXT record: $response"
    return 1
  fi
}

dns_beget_rm() {
  fulldomain=$1
  txtvalue=$2

  _readaccountconf BEGET_TXT_CACHE
  if [ -n "$BEGET_TXT_CACHE" ]; then
    new_cache=$(echo "$BEGET_TXT_CACHE" | sed "s/$txtvalue//g")
    _saveaccountconf_mutable BEGET_TXT_CACHE "$new_cache"
  fi

  _info "Removing TXT record for $fulldomain (not supported by Beget API)"
  return 0
}

EOF

# Make DNS hooks executable
sudo chmod +x /root/.acme.sh/dnsapi/dns_beget.sh
sudo chmod +x /root/.acme.sh/dnsapi/dns_timeweb.sh

# Create placeholder DNS hooks for other Russian providers
for provider in sprinthost spaceweb fornex adminvps; do
    sudo tee "/root/.acme.sh/dnsapi/dns_${provider}.sh" > /dev/null <<EOF
#!/usr/bin/env sh

# ${provider^} DNS API
# Placeholder implementation - requires provider-specific API integration

dns_${provider}_add() {
    fulldomain=\$1
    txtvalue=\$2
    
    _err "${provider^} DNS API integration not yet implemented"
    _err "Please contact support or use a different DNS provider"
    return 1
}

dns_${provider}_rm() {
    fulldomain=\$1
    txtvalue=\$2
    
    _info "TXT record removal for ${provider^} not implemented"
    return 0
}
EOF
    sudo chmod +x "/root/.acme.sh/dnsapi/dns_${provider}.sh"
done

sudo a2enmod security2
sudo a2enmod reqtimeout
#sudo apt install lua-md5
#sudo apt install luarocks
#sudo luarocks install md5
#sudo a2enmod lua

sudo mkdir -p /var/log/apache2/
sudo chown -R www-data:www-data /var/log/apache2/
sudo chmod -R 755 /var/log/apache2/

#sudo mkdir -p /var/www/html/webroot
#sudo chown -R www-data:www-data /var/www/html/webroot

#####################
#MPM_MODE="mpm_event"  
MPM_MODE="mpm_prefork"   # event by default

#if [[ "$OS_VERSION" == "22.04" ]]; then
#    PHP_VERSION="8.1"
#else
#    PHP_VERSION="7.4"
#fi

PHP_VERSION=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')
echo "PHP version is $PHP_VERSION"

PHP_CONF=$(ls /etc/apache2/mods-enabled/ 2>/dev/null | grep -oE 'php[0-9]+\.[0-9]+\.conf' | head -n1)

if [[ -n "$PHP_CONF" ]]; then
    PHP_VERSION_APACHE=$(echo "$PHP_CONF" | grep -oE '[0-9]+\.[0-9]+')
    echo "✅ Apache PHP $PHP_VERSION_APACHE (mod_php)"
fi

# Если mod_php не найден — ищем php-fpm сокет
FPM_CONF=$(grep -R "php[0-9]\.[0-9]-fpm" /etc/apache2/sites-enabled/ 2>/dev/null | head -n1)
if [[ -n "$FPM_CONF" ]]; then
    PHP_VERSION_APACHE=$(echo "$FPM_CONF" | grep -oE 'php[0-9]+\.[0-9]+')
    echo "✅ Apache PHP $PHP_VERSION_APACHE (php-fpm)"
fi

if [[ "$MPM_MODE" == "mpm_event" ]]; then
    # mpm_event + php-fpm
    echo "Configuring for mpm_event with php-fpm..."        
    sudo a2dismod "php$PHP_VERSION_APACHE"
    sudo apt install -y "php${PHP_VERSION}-fpm"
    sudo a2enconf "php${PHP_VERSION_APACHE}-fpm"
    sudo a2enmod proxy_fcgi setenvif    

    sudo a2dismod mpm_worker    
    sudo a2dismod mpm_prefork

    sudo a2enmod mpm_event
    
elif [[ "$MPM_MODE" == "mpm_prefork" ]]; then

    sudo apt install -y "php${PHP_VERSION}-fpm"
    echo "Configuring for mpm_prefork with mod_php..."        
    sudo a2disconf "php${PHP_VERSION_APACHE}-fpm"
    
    # remove php-fpm if needed
    # sudo apt remove -y "php${PHP_VERSION}-fpm"

    sudo a2dismod mpm_worker    
    sudo a2dismod mpm_event    

    sudo a2dismod proxy_fcgi
    sudo a2enmod "php$PHP_VERSION_APACHE"
    
    sudo a2enmod mpm_prefork
else
    echo "Unknown MPM mode: $MPM_MODE"
    exit 1
fi
#####################

sudo apt install lua5.1
sudo apt install lua-md5
sudo apt install luarocks
sudo luarocks install md5
sudo a2enmod lua

sudo systemctl restart apache2

echo "Apache + PHP is installed."

sudo apt install dnsutils

sudo apt install -y certbot python3-certbot-apache

echo "Certbot for SSL has been installed."

sudo apt install -y curl
sudo apt install jq -y

sudo mkdir -p /opt/killbot
sudo mkdir -p /opt/killbot/php
sudo mkdir -p /opt/killbot/lua
sudo mkdir -p /opt/killbot/sh
sudo mkdir -p /opt/killbot/f2b
sudo mkdir -p /opt/killbot/certs
sudo mkdir -p /var/log/killbot
sudo mkdir -p /var/log/killbot/lua
sudo mkdir -p /opt/killbot/html
sudo chown -R www-data:www-data /var/log/killbot /var/log/killbot/lua /opt/killbot/lua /opt/killbot/php /opt/killbot/sh /opt/killbot/html

sudo touch /opt/killbot/tokens

# Check if file exists, if not create it with the IP address
if [ ! -f "/opt/killbot/wl-ip" ]; then    
    # Default white-list ips
    echo -e "37.140.192.59" > /opt/killbot/wl-ip  # Overwrite existing file
fi

if [ ! -f "/opt/killbot/wl-path" ]; then    
    # Default wl-path
    echo -e "/favicon.ico" > /opt/killbot/wl-path  # Overwrite existing file
fi

if [ ! -f "/opt/killbot/wl-ua" ]; then    
    # Default white-list user agents
    echo -e "yandex.bot\ngoogle.bot\nbaidu.bot\nWhatsApp.W\nbing.bot\nfacebook.bot\nvk.bot\ninstagram.bot\ntwitter.bot\nlinkedin.bot\npinterest.bot\nviber.bot\nslack.bot\nskype.bot\ntelegram.bot\nwhatsapp.bot\nletsencrypt" > /opt/killbot/wl-ua
fi

FILE="/opt/killbot/html/verification.php"
if [ ! -f "$FILE" ]; then    
    curl -o "$FILE" "https://data.killbot.ru/verification.html"
    
    if [ $? -eq 0 ]; then
        echo "The verification page has been successfully loaded."
    else
        echo "Error loading the verification page."
        exit 1
    fi
    #sudo test -f /var/www/html/.htaccess || sudo tee /var/www/html/.htaccess > /dev/null <<EOF
    #<FilesMatch "\.(html|htm)$">
    #    Header set Cache-Control "no-cache, no-store, must-revalidate"
    #    Header set Pragma "no-cache"
    #    Header set Expires 0
    #</FilesMatch>
fi

FILE="/var/www/html/empty.php"
    curl -o "$FILE" "https://data.killbot.ru/killbot_dns/empty.html"
    
    if [ $? -eq 0 ]; then
        echo "The empty php page has been successfully loaded."
    else
        echo "Error loading the empty php page."
        exit 1
    fi

FILE="/var/www/html/empty_ru.html"
    curl -o "$FILE" "https://data.killbot.ru/killbot_dns/empty_ru.html"
    
    if [ $? -eq 0 ]; then
        echo "The empty RU page has been successfully loaded."
    else
        echo "Error loading the empty RU page."
        exit 1
    fi

FILE="/var/www/html/empty_en.html"
    curl -o "$FILE" "https://data.killbot.ru/killbot_dns/empty_en.html"
    
    if [ $? -eq 0 ]; then
        echo "The empty EN page has been successfully loaded."
    else
        echo "Error loading the empty EN page."
        exit 1
    fi

FILE="/opt/killbot/UpdateAll.sh"
    curl -o "$FILE" "https://data.killbot.ru/killbot_dns/UpdateAll.sh"
    
    if [ $? -eq 0 ]; then
        echo "The UpdateAll.sh file has been successfully loaded."
    else
        echo "Error loading the UpdateAll.sh file."
        exit 1
    fi

FILE="/opt/killbot/renew_wildcard.sh"
    curl -o "$FILE" "https://data.killbot.ru/killbot_dns/renew_wildcard.sh"
    
    if [ $? -eq 0 ]; then
        echo "The renew_wildcard.sh file has been successfully loaded."
    else
        echo "Error loading the renew_wildcard.shUpdateAll.sh file."
        exit 1
    fi

FILE="/opt/killbot/acme_check_api.sh"
    curl -o "$FILE" "https://data.killbot.ru/killbot_dns/acme_check_api.sh"
    
    if [ $? -eq 0 ]; then
        echo "The acme_check_api.sh file has been successfully loaded."
    else
        echo "Error loading the acme_check_api.sh file."
        exit 1
    fi

FILE="/opt/killbot/html/FakeBot.php"
if [ ! -f "$FILE" ]; then
    curl -o "$FILE" "https://data.killbot.ru/FakeBot.html"

    if [ $? -eq 0 ]; then
        echo "FakeBot page loaded."
    else
        echo "Error loading the FakeBot page."
        exit 1
    fi
fi


FILE="/opt/killbot/html/BlockBot.html"
if [ ! -f "$FILE" ]; then
    curl -o "$FILE" "https://data.killbot.ru/BlockBot.html"

    if [ $? -eq 0 ]; then
        echo "BlockBot page loaded."
    else
        echo "Error loading the BlockBot page."
        exit 1
    fi
fi

FILE="/opt/killbot/html/Expired.html"
if [ ! -f "$FILE" ]; then
    curl -o "$FILE" "https://data.killbot.ru/Expired.html"

    if [ $? -eq 0 ]; then
        echo "Expired page loaded."
    else
        echo "Error loading the Expired page."
        exit 1
    fi
fi


FILE="/opt/killbot/f2b/subnet-monitor.sh"
if [ ! -f "$FILE" ]; then
    curl -o "$FILE" "https://data.killbot.ru/killbot_dns/subnet-monitor.sh"

    if [ $? -eq 0 ]; then
        echo "subnet-monitor loaded."
    else
        echo "Error loading the subnet-monitor."
        exit 1
    fi
fi

FILE="/root/.acme.sh/dnsapi/dns_nicru.sh"
if [ ! -f "$FILE" ]; then
    curl -o "$FILE" "https://data.killbot.ru/killbot_dns/dnsapi/dns_nicru.sh"

    if [ $? -eq 0 ]; then
        echo "dns_nicru.sh page loaded."
    else
        echo "Error loading the dns_nicru.sh page."
        exit 1
    fi
fi    

FILE="/root/.acme.sh/dnsapi/dns_selectel.sh"
if [ ! -f "$FILE" ]; then
    curl -o "$FILE" "https://data.killbot.ru/killbot_dns/dnsapi/dns_selectel.sh"

    if [ $? -eq 0 ]; then
        echo "dns_selectel.sh page loaded."
    else
        echo "Error loading the dns_selectel.sh page."
        exit 1
    fi
fi  

sudo chown www-data:www-data /opt/killbot/html/FakeBot.php /opt/killbot/html/BlockBot.html /opt/killbot/html/Expired.html /opt/killbot/html/verification.php
sudo chmod +x /root/.acme.sh/dnsapi/dns_nicru.sh /root/.acme.sh/dnsapi/dns_selectel.sh /opt/killbot/f2b/subnet-monitor.sh /opt/killbot/renew_wildcard.sh /opt/killbot/acme_check_api.sh /opt/killbot/UpdateAll.sh


sudo tee /opt/killbot/kbEqual.php > /dev/null <<EOF
#!/usr/bin/php
<?php

\$stdin = fopen("php://stdin", "r");
\$logFile = '/var/log/killbot/kbEqual.log';

while ((\$line = fgets(\$stdin)) !== false) {
    \$line = trim(\$line);
    if (empty(\$line)) {
        continue;
    }
    list(\$value1, \$value2) = explode('.', \$line);
    echo (strcmp(\$value1, \$value2) === 0) ? "true\n" : "false\n";
    fflush(STDOUT);
}

fclose(\$stdin);
EOF

sudo chmod +x /opt/killbot/kbEqual.php


sudo sudo tee /var/www/html/kb.php > /dev/null <<EOF
<?php
\$allowedIps = [
    '37.140.192.59',
    '168.222.192.179'
];

//\$serverIps = array(\$_SERVER['REMOTE_ADDR'],isset(\$_SERVER['HTTP_X_FORWARDED_FOR'])?\$_SERVER['HTTP_X_FORWARDED_FOR']:"127.0.0.1");
\$serverIps = array(\$_SERVER['REMOTE_ADDR']);

if (count(array_intersect(\$serverIps, \$allowedIps))==0) { 
    echo "Access denied: Your IP = ".\$_SERVER['REMOTE_ADDR']." is not allowed to configure KillBot DNS Server.";
    exit;
}

if (is_array(\$_POST)&&(count(\$_POST)>0)){
\$_GET = \$_POST;
}

\$type = \$_GET["type"] ?? null;
if (!\$type) {
    echo "no type arg"; exit;
}

\$domain = \$_GET["domain"] ?? null;
\$email = \$_GET["email"] ?? null;
\$ip = \$_GET["ip"] ?? null;
\$folder = \$_GET["folder"] ?? null;
\$wlip = \$_GET["wlip"] ?? "";
\$wlua = \$_GET["wlua"] ?? "";
\$ah = \$_GET["ah"] ?? "";
\$wlpath = \$_GET["wlpath"] ?? "";
\$t = \$_GET["t"] ?? null;
\$le = \$_GET["le"] ?? "1";
\$www = \$_GET["www"] ?? "0";

// DNS API configuration for wildcard SSL certificates
\$use_sub_domains = \$_GET["use_sub_domains"] ?? "0";
\$api_env_content = \$_GET["api_env_content"] ?? "";
\$dns_provider = \$_GET["dns_provider"] ?? "";

if (!\$le) \$le="0";
if (!\$www) \$www="0";

\$command = "";
if (\$type == "install") {
    \$command = "sudo /opt/killbot/install.sh";
    // Add DNS API configuration if subdomains are enabled
    if (\$use_sub_domains == "1" && !empty(\$api_env_content)) {
        \$command .= " -use_sub_domains \$use_sub_domains";
        \$command .= " -api_env_content \"" . base64_encode(\$api_env_content) . "\"";
        if (!empty(\$dns_provider)) {
            \$command .= " -dns_provider \"" . \$dns_provider . "\"";
        }
    }
}
if (\$type == "ensite") \$command = "sudo kb ensite \$domain";
if (\$type == "ensitep") \$command = "sudo kb ensite \$domain p";
if (\$type == "dissite") \$command = "sudo kb dissite \$domain";
if (\$type == "a2dissite") \$command = "sudo kb a2dissite \$domain";
if (\$type == "cert_del") \$command = "sudo kb cert_del \$domain";

if (!\$command) {
    echo "no command"; exit;
}
if (\$type == "install"){
if (\$domain) \$command .= " -d \$domain";
if (\$email)  \$command .= " -e \$email";
if (\$ip)     \$command .= " -ip \$ip";
if (\$folder) \$command .= " -f \$folder";
if (\$wlip)   \$command .= " -wlip \$wlip";
if (\$wlua)   \$command .= " -wlua \$wlua";
if (\$ah)     \$command .= " -ah \$ah";
if (\$wlpath)   \$command .= " -wlpath \$wlpath";
if (\$t)   \$command .= " -t \$t";
\$command .= " -le \$le";
\$command .= " -www \$www";
}

\$command .= " 2>&1";
#\$command = "sudo /opt/killbot/install.sh -d \$domain -e \$email -ip \$ip 2>&1";
#\$command = "sudo /opt/killbot/install.sh -d erge 2>&1";

\$output = array();
exec(\$command,\$output,\$return_var);

print_r(\$output);
?>
EOF

sudo sudo tee /opt/killbot/kb.lua > /dev/null <<EOF
package.path = "/usr/local/share/lua/5.1/?.lua;" .. package.path
package.cpath = "/usr/local/lib/lua/5.1/?.so;" .. package.cpath

local md5 = require "md5"

local cache = cache or {}
local lastFlush = 0
local lifetime = 86400
local LOG_ENABLED = false

function log_message(message,domain)
    if not LOG_ENABLED then return false end

    local f = io.open("/var/log/killbot/lua/" .. domain .. ".log", "a")
    if f then
        f:write(message .. "\n")
        f:close()
    end
end

kb_lua_agents

kb_lua_paths

kb_lua_ips

kb_lua_ah

local function agent_allowed(agent)
    
    if not agent then return false end

    agent = agent:lower()

    for _, pattern in ipairs(allowed_agents) do
        local all_found = true                
        for word in pattern:gmatch("[^%.]+") do
            if word ~= "" and not agent:find(word:lower(), 1, true) then                
                all_found = false
                break
            end
        end

        if all_found then
            return true
        end
    end

    return false
end

function check_hostname(hostname, allowed_ah)
    if not hostname or hostname == "" then
        return "false"
    end
    
    for _, pattern in ipairs(allowed_ah) do
        if #pattern <= #hostname and hostname:sub(-#pattern) == pattern then
            return "true"
        end
    end
    return "false"
end

function checkIfTrueYandexOrGoogleBots(hostname, user_agent, client_ip)

--    if not hostname or hostname == "" then
--        return "user"
--    end

    if not agent_allowed(user_agent) then return "user" end

    local search_engines = {
        yandex = {bot_pattern = "yandex", hostname_patterns = {".yandex.ru", ".yandex.net", ".yandex.com"}},
        apple = {bot_pattern = "apple", hostname_patterns = {".apple.com"}},
        google = {bot_pattern = "google", hostname_patterns = {".googlebot.com", ".google.com"}},
        baidu = {bot_pattern = "baidu", hostname_patterns = {".baidu.com", ".baiducontent.com"}},
        bing = {bot_pattern = "bing", hostname_patterns = {".bing.com", ".search.msn.com"}},
        facebook = {bot_pattern = "facebook", hostname_patterns = {".facebook.com", ".fb.com"}},
        vk = {bot_pattern = "vk.com", hostname_patterns = {".vk.com", ".vkontakte.ru", ".vkstatic.com", ".go.mail.ru", ".mail.ru"}},
        vk2 = {bot_pattern = "vkShare", hostname_patterns = {".go.mail.ru", ".vkontakte.ru", ".mail.ru"}},
        instagram = {bot_pattern = "instagram", hostname_patterns = {".instagram.com", ".cdninstagram.com"}},
        twitter = {bot_pattern = "twitter", hostname_patterns = {".twitter.com", ".t.co"}},
        linkedin = {bot_pattern = "linkedin", hostname_patterns = {".linkedin.com"}},
        pinterest = {bot_pattern = "pinterest", hostname_patterns = {".pinterest.com", ".pinimg.com"}},
        viber = {bot_pattern = "Viber", hostname_patterns = {".viber.com"}},
        telegram = {bot_pattern = "TelegramBot", hostname_patterns = {".t.me", ".telegram.org"}},
    }
    

    local bot_ua_found = false
    for _, data in pairs(search_engines) do
        if string.find(string.lower(user_agent), string.lower(data.bot_pattern)) then
            bot_ua_found = true
            if hostname then
                for _, pattern in ipairs(data.hostname_patterns) do
                    if hostname:sub(-#pattern) == pattern then
                        return "bot_true"
                    end
                end
            end
        end
    end

    if bot_ua_found == true then
      return "bot_false"
--        return "user"
    end

    return "user"
end

function modifyMd5(input)
    return md5.sumhexa(input)
end


local function ip_allowed(ip)
    for _, pattern in ipairs(allowed_ips) do
        if pattern:sub(-1) == "." then
            if ip:sub(1, #pattern) == pattern then
                return true
            end
        elseif ip == pattern then
            return true
        end
    end
    return false
end

local function path_allowed(path)
    for _, pattern in ipairs(allowed_paths) do
        if pattern:sub(-1) == "$" then
            local exact = pattern:sub(1, -2)
            if path == exact then
                return true
            end
        else
            if path:sub(1, #pattern) == pattern then
                return true
            end
        end
    end
    return false
end

function handle(r)
    local user_agent = r.headers_in["User-Agent"] or ""
    local remote_addr = r.subprocess_env["REAL_REMOTE_ADDR"] or ""
    local kb_session = r.subprocess_env["KBSESSION"] or ""
    local http_host = r.headers_in["Host"] or ""
    local http_host2 = ""

-- deny not exist 1.3 protokol: ddos case
    if r.protocol == "HTTP/1.3" then        
     -- return apache2.DONE
        return apache2.FORBIDDEN --FORCE LUA ERROR TO PREVENT CPU
    end

--[[
--  deny request with any get params: if ddos
    if r.args and #r.args > 0 then
        log_message("ip:" .. (r.subprocess_env["REAL_REMOTE_ADDR"] or "") .. " GET parameters detected: " .. r.args .. " - 403 FORBIDDEN", r.headers_in["Host"] or "")
        -- return apache2.DONE
        return apache2.FORBIDDEN --FORCE LUA ERROR TO PREVENT CPU
    end
]]

--[[
--  deny request with 1 get param and get param len = 4 and get param val = 4 and param val is not int: if ddos
if r.args and #r.args > 0 then
    local params = {}
    for k, v in string.gmatch(r.args, "([^=&]+)=([^&]*)") do
        params[k] = v
    end

    local count = 0
    for _ in pairs(params) do count = count + 1 end

    if count == 1 then
        for key, val in pairs(params) do
            local key_len = #key
            local val_len = #val

            local val_is_number = string.match(val, "^%d+$") ~= nil

            if key_len == 4 and val_len == 4 and not val_is_number then
                -- log_message("ip:" .. (r.subprocess_env["REAL_REMOTE_ADDR"] or "") .. " Suspicious 4=4 GET param detected: " .. key .. "=" .. val .. " - 403 FORBIDDEN", r.headers_in["Host"] or "" )
                -- return apache2.DONE
                return apache2.FORBIDDEN --FORCE LUA ERROR TO PREVENT CPU

            end
        end
    end
end
]]

    -- Extract second-level domain for http_host2
    if http_host ~= "" then
        local host = http_host:gsub(":%d+$", "")
    
        local parts = {}
        for label in host:gmatch("([^.]+)") do
            parts[#parts+1] = label
        end

        if #parts >= 2 then
            http_host2 = parts[#parts-1] .. "." .. parts[#parts]
        else            
            http_host2 = host
        end
    end
    
    local remote_addr_org = remote_addr
    local x_forwarded_for = r.headers_in["X-Forwarded-For"] or ""
    local path = r.uri or ""

    if r.uri == "/verification.php" then
        return apache2.DECLINED
    end

    if r.uri == "/FakeBot.php" then
        return apache2.DECLINED
    end

    if ip_allowed(remote_addr_org) then
        log_message("ip:"  .. remote_addr_org .. " ip_allowed: " .. remote_addr_org .. " DECLINED",http_host)
        return apache2.DECLINED
    end

    if path_allowed(r.unparsed_uri) then
        log_message("ip:"  .. remote_addr_org .. " path_allowed: " .. r.unparsed_uri .. " DECLINED",http_host)
        return apache2.DECLINED
    end

    local hostname = ""
    local handle = io.popen("host " .. remote_addr_org)
    if handle then
        local result = handle:read("*a")
        handle:close()
        if result then
            hostname = string.match(result, "domain name pointer ([^%s]+)%.") or ""
        end
    end

    local is_allowed_host = check_hostname(hostname, allowed_ah)

    if is_allowed_host == "true" then
        r.subprocess_env["KBCHECK_MUST_BE"] = "true"
        log_message("ip:"  .. remote_addr_org .. " trusted host detected: " .. hostname .. " DECLINED",http_host)
        return apache2.DECLINED
    end

    local is_real_bot = checkIfTrueYandexOrGoogleBots(hostname, user_agent, remote_addr_org)
    if is_real_bot == "bot_false" then
--      r.filename = "/opt/killbot/html/FakeBot.php"
--      r.content_type = "text/html"
--      r:sendfile(r.filename)

--        local handle = io.popen("php /opt/killbot/html/FakeBot.php")
        local cmd = string.format('php /opt/killbot/html/FakeBot.php %q %q %q', x_forwarded_for ,remote_addr_org,user_agent)
        local handle = io.popen(cmd)
        local result = handle:read("*a")
        handle:close()
        r.content_type = "text/html"
        r:puts(result)

        log_message("ip:"  .. remote_addr_org .. " fake bot detected: " .. user_agent .. " fake bot page showed DONE",http_host)

        return apache2.DONE
    end

    if is_real_bot == "bot_true" then
        r.subprocess_env["KBCHECK_MUST_BE"] = "true"
        log_message("ip:"  .. remote_addr_org .. " trusted bot detected: " .. user_agent .. " DECLINED",http_host)
        return apache2.DECLINED
    end

    if agent_allowed(user_agent) then
        log_message("ip:"  .. remote_addr_org .. " trusted user agent detected : " .. user_agent .. " DECLINED",http_host)
        return apache2.DECLINED
    end

    r.headers_out["X-Debug-User-Agent"]  = user_agent
    r.headers_out["X-Debug-Remote-Addr"] = remote_addr
    r.headers_out["X-Debug-KB-Session"]  = kb_session
    r.headers_out["X-Debug-Host"]        = http_host

    if #kb_session >=1 then
        local ct = tonumber(string.sub(kb_session, 1, -5))
        local now = math.floor(os.time() * 1000)

        if math.abs(now - ct) > (lifetime * 1000) then
--          r.filename = "/opt/killbot/html/verification.php"
--          r.content_type = "text/html"
--          r:sendfile(r.filename)

            local cmd = string.format('php /opt/killbot/html/verification.php %q %q %q', x_forwarded_for ,remote_addr_org,user_agent)
            local handle = io.popen(cmd)
            local result = handle:read("*a")
            handle:close()
            r.content_type = "text/html"
            r:puts(result)

            log_message("ip:"  .. remote_addr_org .. " kbSession is expired : " .. kb_session .. " VP showed DONE",http_host)

            return apache2.DONE

        end
    end

    local ipParts = {}
    for part in remote_addr:gmatch("([^.]+)") do
        table.insert(ipParts, part)
    end
    table.remove(ipParts)
    remote_addr = table.concat(ipParts, ".")

--    r.headers_out["X-Debug-Remote-Addr-2"] = remote_addr

    local line = table.concat({kb_lua_script}, "")
--    local line2 = table.concat({kb2_lua_script}, "")

    local expected_hash = r.subprocess_env["KBCHECK"] or "123"
    local computed_hash = ""
    if cache[line] ~= nil then
        computed_hash = cache[line]
    end

    local now = os.time()
    if now - lastFlush > 300 then
        cache = {}
        lastFlush = now
    end

    if computed_hash == expected_hash then
        r.subprocess_env["KBCHECK_MUST_BE"] = "true"
        log_message("ip:"  .. remote_addr_org .. " cached computed_hash == expected_hash: '" .. computed_hash .. "' DECLINED",http_host)
        return apache2.DECLINED
    end

    computed_hash = modifyMd5(line)

--    r.headers_out["X-Debug-expected_hash"] = expected_hash
--    r.headers_out["X-Debug-computed_hash"] = computed_hash
--    r.headers_out["X-Debug-computed_line"] = line
--    r.headers_out["X-Debug-Res"] = "NEXT"

    if computed_hash == expected_hash then
        r.subprocess_env["KBCHECK_MUST_BE"] = "true"
        log_message("ip:"  .. remote_addr_org .. " computed computed_hash == expected_hash: " .. computed_hash .. " DECLINED",http_host)
        return apache2.DECLINED
    else
--        if line2 then computed_hash = modifyMd5(line2) end

        if computed_hash == expected_hash then
            r.subprocess_env["KBCHECK_MUST_BE"] = "true"
            log_message("ip:"  .. remote_addr_org .. " computed computed_hash == expected_hash: " .. computed_hash .. " DECLINED",http_host)
            return apache2.DECLINED
        else    
            --local handle = io.popen("php /opt/killbot/html/verification.php")
            local cmd = string.format('php /opt/killbot/html/verification.php %q %q %q', x_forwarded_for ,remote_addr_org, user_agent)
            local handle = io.popen(cmd)
            local result = handle:read("*a")
            handle:close()
            r.content_type = "text/html"
            r:puts(result)

            log_message("ip:"  .. remote_addr_org .. " VP showed DONE line=" .. line,http_host)

            return apache2.DONE
        end
    end
end

EOF

#sudo chmod +x /opt/killbot/kb.lua


sudo sudo tee /opt/killbot/apache443-killbot.sh > /dev/null <<EOF
#!/bin/bash

if [ \$# -ne 8 ]; then
  echo "Usage: \$0 <domain> <main_domain> <secondary_domain> <backend_ip> <user_agent_disallowed> <wlpath> <ip_disallowed> <folder>"
  exit 1
fi

domain=\$1
main_domain=\$2
secondary_domain=\$3
backend_ip=\$4

user_agent_disallowed = "\$5"
wlpath = "\$6"
ip_disallowed = "\$7"

folder=\$8

configFile="/etc/apache2/sites-available/\$domain-killbot.conf"


configContent="<VirtualHost *:443>
    ServerName \$secondary_domain
    ***www_ssl_on***
    SSLCertificateFile ***SSLCertificateFile***
    SSLCertificateKeyFile ***SSLCertificateKeyFile***

    Redirect permanent / https://\$main_domain/
</VirtualHost>

<VirtualHost *:80>
    ServerName \$main_domain
    ServerAlias \$secondary_domain    
    ServerAlias www.\$domain
    ***SubdomainAlias***
   
    RewriteEngine On        
    RewriteCond %{HTTP_HOST} ^(\$main_domain|\$secondary_domain)\$ [NC]
    RewriteRule ^(.*)\$ https://\$main_domain%{REQUEST_URI} [R=301,L]
        
    RewriteCond %{HTTP_HOST} ^(.+)\.\$domain\$ [NC]
    RewriteRule ^(.*)\$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>

<VirtualHost *:443>
    ServerName \$main_domain
    ServerAlias www.\$domain
    ***SubdomainAlias***

    RewriteEngine on

    SSLEngine on
    SSLCertificateFile ***SSLCertificateFile***
    SSLCertificateKeyFile ***SSLCertificateKeyFile***

    ErrorLog /var/log/apache2/\$domain.error.log
    CustomLog /var/log/apache2/\$domain.access.log combined

    # verification.php restrictions
    <Files \"/opt/killbot/html/verification.php\">
        Header set Connection \"close\"        
    </Files>

    Alias /FakeBot.php /opt/killbot/html/FakeBot.php
    <Directory /opt/killbot/html>
        <Files "FakeBot.php">
            Require all granted
        </Files>
        Require all denied
    </Directory>
   
    <Directory "/var/www/html/.well-known">
        Options None
        AllowOverride None
        Require all granted
    </Directory>

#    RewriteCond %{REQUEST_URI} ^/verification\.php [NC]
#    RewriteCond %{REQUEST_METHOD} POST
#    RewriteRule ^(.*)$ /$1 [R=302,L]

    SetEnvIf X-Forwarded-For \"^([0-9\.]+)\" REAL_REMOTE_ADDR=\\\$1

    RewriteCond %{ENV:REAL_REMOTE_ADDR} ^$
    RewriteRule .* - [E=REAL_REMOTE_ADDR:%{REMOTE_ADDR}]

    RewriteCond %{HTTP_COOKIE} (^|;\s*)kbCheck=([^;]+) [NC]
    RewriteRule ^ - [E=KBCHECK:%2]

    RewriteCond %{HTTP_COOKIE} (^|;\s*)kbSession=([^;]+) [NC]
    RewriteRule ^ - [E=KBSESSION:%2]

    RewriteCond %{ENV:KBCHECK} ^Expired\$
    RewriteRule ^(.*)\$ /opt/killbot/html/Expired.html [L]

    RewriteRule ^ - [E=KBCHECK_MUST_BE:true]
    LuaHookFixups /opt/killbot/lua/\$domain.lua handle

    #Define PROXY_ENABLE

    <IfDefine PROXY_ENABLE>
        ProxyPreserveHost On
        SSLProxyEngine On 
        SSLProxyCheckPeerCN Off
        SSLProxyCheckPeerName Off
        SSLProxyCheckPeerExpire Off

        ProxyPass /FakeBot.php !
        ProxyPass /opt/killbot/html/FakeBot.php !

        ProxyPass /.well-known !
        ProxyPass /var/www/html/.well-known !
        
        # set X-Real-IP if not exist
        RequestHeader setIfEmpty X-Real-IP "%{REAL_REMOTE_ADDR}e"

        # Set X-Forwarded-For
        #RewriteRule .* - [E=SERVER_REMOTE_ADDR:%{REMOTE_ADDR}]
        #RequestHeader append X-Forwarded-For "%{SERVER_REMOTE_ADDR}e"

        Header unset X-Frame-Options
        
        ProxyPass / https://\$backend_ip/
        ProxyPassReverse / https://\$backend_ip/
    </IfDefine>

    #DocumentRoot \$folder
    #<Directory \$folder>
    #    Options Indexes FollowSymLinks MultiViews
    #    AllowOverride All
    #    Require all granted
    #</Directory>

    <Directory /opt/killbot/html>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Require all granted

        Order allow,deny
        Allow from all

        Header set Cache-Control \"no-cache, no-store, must-revalidate\"
        Header set Pragma \"no-cache\"
        Header set Expires 0
    </Directory>

</VirtualHost>"

echo -e "\$configContent" | sudo tee "\$configFile" > /dev/null

echo "Configuration for \$domain has been created."
EOF

sudo chmod +x /opt/killbot/apache443-killbot.sh


sudo tee /opt/killbot/apache80_letsencrypt_test.sh > /dev/null <<EOF
#!/bin/bash

if [ \$# -ne 2 ]; then
  echo "Usage: \$0 <domain> <backend_ip>"
  exit 1
fi

domain=\$1
backend_ip=\$2

configFile="/etc/apache2/sites-available/\$domain-le.conf"

configContent="<VirtualHost *:80>
   
    ServerName \$domain
    ServerAlias www.\$domain
    DocumentRoot /var/www/html

    Alias /.well-known /var/www/html/.well-known
    <Directory "/var/www/html/.well-known">
        Options None
        AllowOverride None
        Require all granted
    </Directory>

    RewriteEngine On

    RewriteCond %{REQUEST_URI} !^/kb.php$
    RewriteCond %{REQUEST_URI} !^/empty.php$
    RewriteCond %{REQUEST_URI} !^/\.well-known
    RewriteRule ^ /empty.php [L]

    ErrorLog /var/log/apache2/\$domain-le.error.log
    CustomLog /var/log/apache2/\$domain-le.access.log combined
</VirtualHost>

<VirtualHost *:443>
    ServerName \$domain
    ServerAlias www.\$domain
    DocumentRoot /var/www/html
   
    Alias /.well-known /var/www/html/.well-known
    <Directory "/var/www/html/.well-known">
        Options None
        AllowOverride None
        Require all granted
    </Directory>

    RewriteEngine On

    RewriteCond %{REQUEST_URI} !^/kb.php$
    RewriteCond %{REQUEST_URI} !^/empty.php$
    RewriteCond %{REQUEST_URI} !^/\.well-known
    RewriteRule ^ /empty.php [L]

    
    # SSL Configuration with self-signed certificate
    SSLEngine on
    SSLCertificateFile      /etc/ssl/certs/ssl-cert-snakeoil.pem
    SSLCertificateKeyFile   /etc/ssl/private/ssl-cert-snakeoil.key

    ErrorLog /var/log/apache2/\$domain-le-ssl.error.log
    CustomLog /var/log/apache2/\$domain-le-ssl.access.log combined
</VirtualHost>
"

if [ ! -f "\$configFile" ]; then
    #Create file if not exist
    echo -e "\$configContent" | sudo tee "\$configFile" > /dev/null
fi

echo "Configuration for \$domain-le has been created."
EOF
sudo chmod +x /opt/killbot/apache80_letsencrypt_test.sh      



sudo tee /opt/killbot/apache443.sh > /dev/null <<EOF
#!/bin/bash

if [ \$# -ne 5 ]; then
  echo "Usage: \$0 <domain> <main_domain> <secondary_domain> <backend_ip> <folder>"
  exit 1
fi

domain=\$1
main_domain=\$2
secondary_domain=\$3
backend_ip=\$4
folder=\$5


configFile="/etc/apache2/sites-available/\$domain.conf"

configContent="<VirtualHost *:443>
    ServerName \$secondary_domain

    ***www_ssl_on***
    SSLCertificateFile ***SSLCertificateFile***
    SSLCertificateKeyFile ***SSLCertificateKeyFile***

    Redirect permanent / https://\$main_domain/
</VirtualHost>

<VirtualHost *:80>
    ServerName \$main_domain
    ServerAlias \$secondary_domain    
    ServerAlias www.\$domain
    ***SubdomainAlias***
   
    RewriteEngine On        
    RewriteCond %{HTTP_HOST} ^(\$main_domain|\$secondary_domain)\$ [NC]
    RewriteRule ^(.*)\$ https://\$main_domain%{REQUEST_URI} [R=301,L]
        
    RewriteCond %{HTTP_HOST} ^(.+)\.\$domain\$ [NC]
    RewriteRule ^(.*)\$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>

<VirtualHost *:443>
    ServerName \$main_domain
    ServerAlias \$secondary_domain
    ServerAlias www.\$domain
    ***SubdomainAlias***

    ErrorLog \\\${APACHE_LOG_DIR}/error.log
    CustomLog \\\${APACHE_LOG_DIR}/access.log combined

    SSLEngine on
    SSLCertificateFile ***SSLCertificateFile***
    SSLCertificateKeyFile ***SSLCertificateKeyFile***

    RewriteEngine on

    SetEnvIf X-Forwarded-For \"^([0-9\.]+)\" REAL_REMOTE_ADDR=$1

    RewriteCond %{ENV:REAL_REMOTE_ADDR} ^$
    RewriteRule .* - [E=REAL_REMOTE_ADDR:%{REMOTE_ADDR}]

    Alias /.well-known /var/www/html/.well-known
    <Directory "/var/www/html/.well-known">
        Options None
        AllowOverride None
        Require all granted
    </Directory>

    #Define PROXY_ENABLE

    <IfDefine PROXY_ENABLE>
        ProxyPreserveHost On
        SSLProxyEngine On 
        SSLProxyCheckPeerCN Off
        SSLProxyCheckPeerName Off
        SSLProxyCheckPeerExpire Off

        ProxyPass /.well-known !
        ProxyPass /var/www/html/.well-known !
       
        # set X-Real-IP if not exist
        RequestHeader setIfEmpty X-Real-IP "%{REAL_REMOTE_ADDR}e"

        # Set X-Forwarded-For
        #RewriteRule .* - [E=SERVER_REMOTE_ADDR:%{REMOTE_ADDR}]
        #RequestHeader append X-Forwarded-For "%{SERVER_REMOTE_ADDR}e"

        Header unset X-Frame-Options

        ProxyPass / https://\$backend_ip/
        ProxyPassReverse / https://\$backend_ip/
    </IfDefine>

    #DocumentRoot \$folder
    #<Directory \$folder>
    #    Options Indexes FollowSymLinks MultiViews
    #    AllowOverride All
    #    Require all granted
    #</Directory>
</VirtualHost>"


#create or rewrite
echo -e "\$configContent" | sudo tee "\$configFile" > /dev/null

echo "Configuration for \$domain has been created."
EOF

sudo chmod +x /opt/killbot/apache443.sh

sudo sudo tee /etc/init.d/kb > /dev/null <<EOF
#!/bin/bash
#
# Script for managing killbot
#

# Path to Apache configurations directory
APACHE_CONF_DIR="/etc/apache2/sites-available"
# Path to killbot installation script
KILLBOT_INSTALL_SCRIPT="/opt/killbot/install.sh"
# Path to killbot cert delete script
KILLBOT_CERT_DELETE_SCRIPT="/opt/killbot/cert_delete.sh"

# Check for root privileges
if [ "\$(id -u)" != "0" ]; then
   echo "This script must be run as root." 1>&2
   exit 1
fi


# Function to check Apache configuration
check_apache_config() {
    # Checking Apache configuration for errors
    apache2ctl configtest > /dev/null 2>&1
    if [ \$? -ne 0 ]; then
        echo "Apache configuration test failed."
        exit 1
    fi    
}

# Function to delete killbot certificate
cert_del() {
    local domain=\$1

    if [ -z "\$domain" ]; then
        echo "Usage: \$0 cert_del domain"
        exit 1
    fi

    if [ ! -x "\$KILLBOT_CERT_DELETE_SCRIPT" ]; then
        echo "Cert delete script not found or not executable: \$KILLBOT_CERT_DELETE_SCRIPT"
        exit 1
    fi

    "\$KILLBOT_CERT_DELETE_SCRIPT" "\$domain"
    echo "Certificate deleted for domain \$domain."
}

# Function to disable apache sites for domain and reload apache
# kb a2dissite {domain.ru}
a2dissite_domain() {
    local domain=\$1
    local standard_conf="\$domain.conf"
    local killbot_conf="\$domain-killbot.conf"

    # check syntax first
    check_apache_config

    # Disable both configs (ignore output)
    a2dissite "\$standard_conf" > /dev/null 2>&1
    a2dissite "\$killbot_conf" > /dev/null 2>&1

    # Reload Apache
    service apache2 reload
    echo "Apache sites disabled for domain \$domain (both \$standard_conf and \$killbot_conf). Apache reloaded."
}

# Function to enable killbot screen configuration
ensite() {
    local domain=\$1
    local opt=\$2
    local killbot_conf="\$domain-killbot.conf"
    local standard_conf="\$domain.conf"    

    if [ ! -f "\$APACHE_CONF_DIR/\$killbot_conf" ]; then
        printf  "Configuration \$killbot_conf not found.\nInstall killbot configuration first.\nUsage:\n -reverce proxy case: kb install -d {domain} -e {email} -ip {domain_backend_ip}\n"
        exit 1
    fi

    # Disable the killbot verification page configuration
    a2dissite "\$killbot_conf" > /dev/null 2>&1
    # Disable the standard configuration
    a2dissite "\$standard_conf" > /dev/null 2>&1

    # Enable the killbot screen configuration
    echo "Killbot verification page for domain \$domain has been enabled."
    a2ensite "\$killbot_conf" > /dev/null 2>&1
    
    check_apache_config

    # Restart Apache to apply changes
    service apache2 reload
    
}

# Function to disable killbot screen configuration
dissite() {
    local domain=\$1
    local killbot_conf="\$domain-killbot.conf"
    local standard_conf="\$domain.conf"
    
    if [ ! -f "\$APACHE_CONF_DIR/\$standard_conf" ]; then        
        printf  "Configuration \$standard_conf not found.\nInstall killbot configuration first.\nUsage:\n -if website in /var/www/html/domain folder): kb install domain email\n -proxy case (IP - website backend ip): kb install domain email ip\n"
        exit 1
    fi

    # Disable the killbot verification page configuration
    a2dissite "\$killbot_conf" > /dev/null 2>&1    

    # Enable the standard configuration
    a2ensite "\$standard_conf" > /dev/null 2>&1

    check_apache_config

    # Restart Apache to apply changes
    service apache2 reload
    echo "Killbot screen for domain \$domain has been disabled."
}

# Function to reload apache2
reload() {
    
    check_apache_config

    # Restart Apache to apply changes
    service apache2 reload
    echo "Apache2 reloaded."
}

# Function to install killbot screen configuration
install() {    

    if [ ! -x "\$KILLBOT_INSTALL_SCRIPT" ]; then
        echo "Killbot installation script not found or not executable."
        exit 1
    fi

    # Run the installation script
    "\$KILLBOT_INSTALL_SCRIPT" "\$1" "\$2" "\$3" "\$4" "\$5" "\$6" "\$7" "\$8" "\$9" "\${10}" "\${11}" "\${12}" "\${13}" "\${14}" "\${15}" "\${16}" "\${17}" "\${18}" "\${19}" "\${20}" "\${21}" "\${22}" "\${23}" "\${24}" "\${25}" "\${26}" "\${27}" "\${28}" "\${29}" "\${30}"
    #echo "Killbot configuration with verification page for domain \$domain has been installed."
}

# Command handling
case "\$1" in
    reload)
        reload
        ;;
    ensite)
        if [ -z "\$2" ]; then
            echo "Usage: \$0 ensite domain"
            exit 1
        fi
        
        ensite "\$2" "\$3"
        ;;
    dissite)
        if [ -z "\$2" ]; then
            echo "Usage: \$0 dissite domain"
            exit 1
        fi
        dissite "\$2"
        ;;
    cert_del)
        if [ -z "\$2" ]; then
            echo "Usage: \$0 cert_del domain"
            exit 1
        fi
        cert_del "\$2"
        ;;
    a2dissite)
        if [ -z "\$2" ]; then
            echo "Usage: \$0 a2dissite domain"
            exit 1
        fi
        a2dissite_domain "\$2"
        ;;
    install)
        
        install "\$2" "\$3" "\$4" "\$5" "\$6" "\$7" "\$8" "\$9" "\${10}" "\${11}" "\${12}" "\${13}" "\${14}" "\${15}" "\${16}" "\${17}" "\${18}" "\${19}" "\${20}" "\${21}" "\${22}" "\${23}" "\${24}" "\${25}" "\${26}" "\${27}" "\${28}" "\${29}" "\${30}"
        ;;
    *)
        echo "Usage: kb {ensite|dissite|a2dissite|cert_del|install|reload} domain"
        exit 1
        ;;
esac

exit 0
EOF

sudo chmod +x /etc/init.d/kb

if [ ! -L "/usr/local/bin/kb" ]; then
    sudo ln -s /etc/init.d/kb /usr/local/bin/kb
fi

sudo tee /opt/killbot/install.sh > /dev/null <<EOF
#!/bin/bash

declare email=""
declare token=""
declare backend_ip=""
declare folder=""
declare domain=""
declare www=-1
declare le="1"
declare wlip=\$(grep -vE '^\$' /opt/killbot/wl-ip | paste -sd ",")
declare wlua=\$(grep -vE '^\$' /opt/killbot/wl-ua | paste -sd ",")
declare wlpath=\$(grep -vE '^\$' /opt/killbot/wl-path | paste -sd ",")
declare SSLCertificateFile=""
declare SSLCertificateKeyFile=""

DNS_SERVERS=("77.88.8.8" "8.8.8.8")  # yandex, Google
RANDOM_INDEX=\$(( \${#DNS_SERVERS[@]} > 0 ? RANDOM % \${#DNS_SERVERS[@]} : 0 ))
DNS_LE_SERVER="\${DNS_SERVERS[\$RANDOM_INDEX]}"
echo "DNS server: \$DNS_LE_SERVER"

declare DNSServer="\$DNS_LE_SERVER"

# DNS API configuration for wildcard SSL certificates
declare use_sub_domains="0"
declare api_env_content=""
declare dns_provider=""

while [[ "\$#" -gt 0 ]]; do
    if [[ -z "\$1" ]]; then
        break
    fi
    case "\$1" in
        -e)
            email="\$2"; shift 2;;
        -t)
            token="\$2"; shift 2;;
        -ip)
            backend_ip="\$2"; shift 2;;
        -f)
            folder="\$2"; shift 2;;
        -d)
            domain="\$2"; shift 2;;
        -wlip)
            wlip="\$2"; shift 2;;
        -wlua)
            wlua="\$2"; shift 2;;
        -ah)
            ah="\$2"; shift 2;;
        -wlpath)
            wlpath="\$2"; shift 2;;
        -le)
            le="\$2"; shift 2;;
        -www)
            www="\$2"; shift 2;;
        # DNS API configuration
        -use_sub_domains)
            use_sub_domains="\$2"; shift 2;;
        -api_env_content)
            api_env_content="\$2"; shift 2;;
        -dns_provider)
            dns_provider="\$2"; shift 2;;
        *)
            trimmed="\$(echo -n "\$1" | xargs)"
            [[ -n "\$trimmed" ]] && { echo "Unknown arg: '\$1'"; exit 1; } || shift 1
            ;;
    esac
done

if [[ -z "\$email" && -z "\$token" ]]; then
    echo "Error: argument email (-e) or token (-t) is required" >&2
    exit 1
fi

if [[ -z "\$backend_ip" && -z "\$folder" ]]; then
    echo "Error: argument ip (-ip) or folder (-f) is required" >&2
    exit 1
fi

if [[ -z "\$domain" ]]; then
    echo "Error: argument domain (-d) is required" >&2
    exit 1
fi

if [[ "\$domain" =~ ^https?:// ]]; then
  echo "Error: The domain should not contain http:// or https://. Enter only the website domain (without http(s))"
fi

#check if www not set
if [ "\$www" -eq -1 ]; then
    if [[ \$domain == www.* ]]; then
        www=1    
    else
        www=0        
    fi
fi

SERVER_IP=\$(curl -s http://checkip.amazonaws.com)

#check if port 443 is opened
# Running curl and analyzing the output
output=\$(curl -v --connect-timeout 5 --max-time 10 --insecure https://\$backend_ip:443 2>&1)

if echo "\$output" | grep -q "Connected to"; then
    echo "Port 443 on the \$backend_ip server is opened"
else
    echo "ERROR: Port 443 is closed for \$backend_ip. The KillBot server has no access to the website server. Please open port 443 on your website server (\$backend_ip) for the KillBot server (\$SERVER_IP)."
    exit 1
fi

domain_without_www=\${domain#www.}
domain_with_www="www.\$domain_without_www"

if [ -z "\$folder" ]; then
    folder="/var/www/html/\$domain_without_www"
fi


sudo mkdir -p /var/log/apache2/
sudo chown -R www-data:www-data /var/log/apache2/
sudo chmod -R 755 /var/log/apache2/

ip_without_www=\$(dig @"\$DNSServer" +short "\$domain_without_www" | head -n 1)
ip_with_www=\$(dig @"\$DNSServer" +short "\$domain_with_www" | head -n 1)

resolved_ip=\$(dig @"\$DNSServer" +short "\$domain" | head -n 1)

#echo "Public server IP: \$SERVER_IP"

if [[ "\$le" -ne 0 ]] && [[ "\$resolved_ip" != "\$SERVER_IP" ]]  && [[ "\$ip_without_www" != "\$SERVER_IP" ]] && [[ "\$ip_with_www" != "\$SERVER_IP" ]]; then
    echo "Error: Wait until the A record of the domain \$domain will points to \$SERVER_IP Now domain \$domain points to \$resolved_ip instead of \$SERVER_IP"
    exit 1
fi

certPath="/etc/letsencrypt/live/\$domain_without_www/fullchain.pem"

SSLCertificateFile="/etc/letsencrypt/live/\$domain_without_www/fullchain.pem"
SSLCertificateKeyFile="/etc/letsencrypt/live/\$domain_without_www/privkey.pem"

if [[ ! -f "\$certPath" && "\$le" -ne 0 ]]; then

   echo "Obtaining letsencrypt certificate...."

    if [ -z "\$email" ]; then
        echo "Error: Add -e [email] parametr to receive letsencript cert."
        exit 1
    fi
    
    output=\$(/opt/killbot/apache80_letsencrypt_test.sh "\$domain_without_www" "\$backend_ip")

    if echo "\$output" | grep -q "created"; then
        :
    else
        echo "Error: There is no confirmation of file creation in the script output:"
        echo "\$output"
        exit 1
    fi
    
    apache_check=\$(sudo apachectl configtest 2>&1)

    if echo "\$apache_check" | grep -q "Syntax OK"; then
        :
    else
        echo "Apache configuration error for \$domain: \$apache_check"

        sudo a2dissite "\$domain_without_www-le"
        sudo rm -f "/etc/apache2/sites-available/\$domain_without_www-le.conf"

        exit 1
    fi
    
    sudo a2ensite "\$domain_without_www-le"
    sudo a2dissite "\$domain_without_www"
    sudo a2dissite "\$domain_without_www-killbot"
    sudo systemctl reload apache2

    echo "The site \$domain_without_www-le has been successfully enabled and Apache has been restarted."
    
    sudo rm -rf /etc/letsencrypt/live/"\$domain_without_www"\*
    sudo rm -rf /etc/letsencrypt/archive/"\$domain_without_www"\*
    sudo rm -rf /etc/letsencrypt/renewal/"\$domain_without_www"\*.conf

    if [[ "\$le" -eq 2 ]]; then
        echo "Error: le=2 not supported!"
        exit 1;

        output=\$(dig @"\$DNSServer" +short AAAA "\$domain_without_www")
            if echo "\$output" | grep -q .; then
                echo "ERROR: remove AAAA dns record for \$domain_without_www"        
                exit 1;
            fi

        output=\$(sudo certbot certonly --manual --preferred-challenges=dns \
          --cert-name "\$domain_without_www" \
          -d "\$domain_without_www" \
          -d "*.\$domain_without_www" \
          --email "\$email" \
          --agree-tos \          
          --manual-public-ip-logging-ok \
          --expand \
          2>&1)

        # Check result and show DNS instructions if needed
        if [[ \$? -ne 0 ]]; then
            echo "Error obtaining SSL certificate:"
            echo "\$output"

            # Try to extract DNS record information
            if grep -q "Please deploy a DNS TXT record" <<< "\$output"; then
                echo -e "\n\033[1;31mATTENTION: You need to manually add a DNS record:\033[0m"
                # Extract record name and value
                dns_record=\$(grep -oP "acme-challenge\.[^\s]+" <<< "\$output" | head -1)
                dns_value=\$(grep -oP 'TXT record \K[^\s]+' <<< "\$output" | head -1)

                echo -e "Add this TXT record to your DNS zone:"
                echo -e "Name: \033[1;32m_\$dns_record\033[0m"
                echo -e "Value: \033[1;32m\$dns_value\033[0m"
                echo -e "TTL: 300 (or default value)"
                echo -e "\nAfter adding, wait 2-5 minutes for DNS propagation and try again."

                echo -e "\nYou can verify DNS propagation with:"
                echo -e "dig -t TXT _acme-challenge.\$domain_without_www +short"
            fi
            exit 1
        else
            echo -e "\033[1;32mSuccess! Wildcard certificate obtained for:\033[0m"
            echo "- Primary domain: \$domain"
            echo "- All subdomains: *.\$domain_without_www"

            echo -e "\nCertificate details:"
            sudo certbot certificates --cert-name "\$domain_without_www"
        fi

    else
        if [[ "\$ip_without_www" == "\$ip_with_www" && -n "\$ip_without_www" ]]; then

            output=\$(dig @"\$DNSServer" +short AAAA "\$domain_without_www")
            if echo "\$output" | grep -q .; then
                echo "ERROR: remove AAAA dns record for \$domain_without_www"        
                exit 1;
            fi

            output=\$(dig @"\$DNSServer" +short AAAA "\$domain_with_www")
            if echo "\$output" | grep -q .; then
                echo "ERROR: remove AAAA dns record for \$domain_with_www"        
                exit 1;
            fi

            output=\$(sudo certbot certonly --webroot --cert-name "\$domain_without_www" -w /var/www/html -d "\$domain_without_www" -d "\$domain_with_www" --email "\$email" --agree-tos --non-interactive 2>&1)
        else

            output=\$(dig @"\$DNSServer" +short AAAA "\$domain_without_www")
            if echo "\$output" | grep -q .; then
                echo "ERROR: remove AAAA dns record for \$domain_without_www"        
                exit 1;
            fi

            output=\$(sudo certbot certonly --webroot --cert-name "\$domain_without_www" -w /var/www/html -d "\$domain" --email "\$email" --agree-tos --non-interactive 2>&1)
        fi
    fi

    if echo "\$output" | grep -q -E "Congratulations|Successfully";  then
        
        SSLCertificateFile="/etc/letsencrypt/live/\$domain_without_www/fullchain.pem"
        SSLCertificateKeyFile="/etc/letsencrypt/live/\$domain_without_www/privkey.pem"

        echo "The certificate has been successfully obtained."

        sudo a2dissite "\$domain_without_www-le"
        sudo rm -f "/etc/apache2/sites-available/\$domain_without_www-le.conf"

    else
        echo "Error obtaining the certificate: \$output"
        exit 1
    fi   

fi

if [[ "\$le" -eq 0 ]]; then
    sudo apt install openssl -y

    sudo mkdir /etc/apache2/ssl
    cd /etc/apache2/ssl

    certPath="/etc/apache2/ssl/\$domain-selfsigned.crt"

    if [[ ! -f "\$certPath" ]]; then
        sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
            -keyout "\$domain-selfsigned.key" \
            -out "\$domain-selfsigned.crt" \
            -subj "/C=RU/ST=Moscow/L=Moscow/O=KillBot/OU=Killbot/CN=\$domain/emailAddress=\$email"
    fi

    SSLCertificateFile="/etc/apache2/ssl/\$domain-selfsigned.crt"
    SSLCertificateKeyFile="/etc/apache2/ssl/\$domain-selfsigned.key"
fi

# Check is sert is on: (enabled != 0)
enabled_file="/opt/killbot/ssl/\$domain_without_www/enabled"
enabled_value="1"
if [[ -f "\$enabled_file" ]]; then
    enabled_value=\$(cat "\$enabled_file" 2>/dev/null || echo "1")
fi
if [[ "\$enabled_value" != "0" ]]; then
    if [[ -f "/opt/killbot/ssl/\$domain_without_www/privkey.pem" ]]; then
      SSLCertificateFile="/opt/killbot/ssl/\$domain_without_www/fullchain.pem"
      SSLCertificateKeyFile="/opt/killbot/ssl/\$domain_without_www/privkey.pem"
      echo "Custom SSL certificate is used!"
    fi
fi


# Create DNS API configuration for wildcard SSL certificates
if [[ "\$use_sub_domains" == "1" && -n "\$api_env_content" ]]; then
    echo "Creating DNS API configuration for wildcard SSL certificates..."
    
    # Create directory for domain certificates
    sudo mkdir -p "/opt/killbot/certs/\$domain_without_www"
    sudo chown -R www-data:www-data "/opt/killbot/certs/\$domain_without_www"
    sudo chmod -R 755 "/opt/killbot/certs/\$domain_without_www"
    
    # Create api.env file with provided content
    api_env_file="/opt/killbot/certs/\$domain_without_www/api.env"
    enabled_file="/opt/killbot/certs/\$domain_without_www/enabled"
    
    # Decode base64 content and write to file
    echo "\$api_env_content" | base64 -d > "\$api_env_file"
    
    # Set proper permissions for api.env file
    sudo chown www-data:www-data "\$api_env_file"
    sudo chmod 600 "\$api_env_file"
    
    # Remove enabled file when api.env is created/updated (new credentials available)
    if [[ -f "\$enabled_file" ]]; then
        rm -f "\$enabled_file"
        log "Removed enabled file for \$domain_without_www - new credentials available"
    fi
    
    # Create provider file with DNS provider name
    if [[ -n "\$dns_provider" ]]; then
        provider_file="/opt/killbot/certs/\$domain_without_www/provider"
        echo "\$dns_provider" > "\$provider_file"
        
        # Set proper permissions for provider file
        sudo chown www-data:www-data "\$provider_file"
        sudo chmod 644 "\$provider_file"
        
        echo "Created provider file: \$provider_file with content: \$dns_provider"
    fi
    
    set -euo pipefail

    echo "Running DNS API check for \$api_env_file ..."
    /opt/killbot/acme_check_api.sh "\$api_env_file"

    if [[ \$? -eq 0 ]]; then
      echo "✅ DNS API check passed, continuing..."
    else
      echo "❌ DNS API check failed for \$API_ENV"
      exit 1
    fi

    echo "DNS API configuration created at: \$api_env_file"
fi


#sudo systemctl reload apache2

lang="ru"
metrika=""
instanceID=""


token_killbot=$KILLBOT_ACCOUNT_TOKEN  # partner API key
tokens_file="/opt/killbot/tokens"
#Read token from file if exist
if [[ -n "\$email" && -z "\$token" ]]; then
    token=\$(grep "^\$email:" "\$tokens_file" | cut -d':' -f2)
fi

if [[ -z "\$token" ]]; then
    
    kb_url="https://killbot.ru/api/login?create=1&d=\$domain"

    echo "Creating account on KillBot for email = \$email"
    response=\$(curl -s -H "X-Token: \$token_killbot" -H "X-Email: \$email" "\$kb_url")

    #echo "response = \$response"

    code=\$(echo "\$response" | jq -r '.code')
    message=\$(echo "\$response" | jq -r '.message')

    #error check
    if [[ "\$code" -ne 200 ]]; then
        echo "Error: Account for \$email already exist. To continue take your API key: https://killbot.ru/api-key ( or https://killbot.ru/api-key ) and run command with your API token like this: "
        echo "kb install -d \$domain -t YOUR_API_TOKEN -ip \$backend_ip"
        echo "Original error message: \$message"
        exit 1
    fi
    
    token=\$(echo "\$response" | jq -r '.data')
    echo "\$email:\$token" >> "\$tokens_file"
    echo "Token saved to file: \$tokens_file"
fi

echo "Creating the KillBot script"
kb_url="https://killbot.ru/api/create_script?integration_type=2&instance_id=\$instanceID&ip=\$backend_ip&url=https://\$domain"
response=\$(curl -s -H "X-Email: \$email" -H "X-Token: \$token_killbot" -H "X-Tokenauth: \$token" "\$kb_url")
#echo "\$response"

# Check if JSON is correct
code=\$(echo "\$response" | jq -r '.code' 2>/dev/null)
message=\$(echo "\$response" | jq -r '.message' 2>/dev/null)

# IF parse error
if [ \$? -ne 0 ] || ! [[ "\$code" =~ ^[0-9]+\$ ]]; then
    echo "Error: Failed to parse JSON response"
    echo "URL: \$kb_url"
    echo "Response: \$response"
    exit 1
fi

code=\$(echo "\$response" | jq -r '.code')
message=\$(echo "\$response" | jq -r '.message')

if [ "\$code" != "200" ]; then
    echo "Error: \$message"
    exit 1
fi

json_data=\$(echo "\$response" | jq -r '.data' | jq -r '.')
cv_json=\$(echo "\$json_data" | jq -r '.cv' | jq -r '.')
metrika=\$(echo "\$json_data" | jq -r '.metrika' | jq -r '.')

php_script=\$(echo "\$cv_json" | jq -r '.php')
php_script_escaped=\$(echo "\$php_script" | sed 's/\\\$/\\\\&/g')
apache_script=\$(echo "\$cv_json" | jq -r '.apache')
lua_script=\$(echo "\$cv_json" | jq -r '.lua')
lua_script2=\$(echo "\$cv_json" | jq -r '.lua2')

#echo "PHP Script: \$php_script"
#echo "Apache Config: \$apache_script"
#echo "LUA Config: \$lua_script"


#Updating kb.lus
#sed "s|kb_lua_script|\$lua_script|g" /opt/killbot/kb.lua > /opt/killbot/lua/\$domain_without_www.lua


make_lua_array() {
    local varname="\$1"
    local values="\$2"
    local result="local \$varname = {"
    IFS=',' read -ra arr <<< "\$values"
    for val in "\${arr[@]}"; do
        val="\${val//\\"/\\\\\"}"  
        result+="    \"\$val\","
    done
    result+="}"
    echo -e "\$result"
}

is_wildcard_cert() {
  local certfile="\$1"  
  if [[ ! -f "\$certfile" ]]; then return 1; fi

  #get domain from certpath like "SERTDIR/{domain}/fullchain.pem"
  local domain=\$(echo "\$certfile" | rev | cut -d'/' -f2 | rev)

  mapfile -t dns_entries < <(openssl x509 -in "\$certfile" -noout -text 2>/dev/null | grep -oP 'DNS:[^,]+' | sed 's/^DNS://')
  for n in "\${dns_entries[@]}"; do
    if [[ "\$n" == "*.\$domain" ]]; then
      return 0
    fi
  done
  return 1
}

wlpath="\$wlpath,/.well-known/"

lua_agents=\$(make_lua_array "allowed_agents" "\$wlua")
lua_paths=\$(make_lua_array "allowed_paths" "\$wlpath")
lua_ips=\$(make_lua_array "allowed_ips" "\$wlip")
lua_ah=\$(make_lua_array "allowed_ah" "\$ah")

subdomain_alias=""
if is_wildcard_cert "\$SSLCertificateFile"; then
    subdomain_alias="ServerAlias *.\$domain_without_www"
    echo "Wildcard certificate detected: \$SSLCertificateFile. Configuring Apache for all subdomains"
fi

#Updating kb.lus
sed -e "s|kb_lua_script|\$lua_script|g" -e "s|kb2_lua_script|\$lua_script2|g" -e "s|kb_lua_agents|\$lua_agents|g" -e "s|kb_lua_paths|\$lua_paths|g" -e "s|kb_lua_ips|\$lua_ips|g" -e "s|kb_lua_ah|\$lua_ah|g"  /opt/killbot/kb.lua > /opt/killbot/lua/\$domain_without_www.lua

#sudo chown -R www-data:www-data /opt/killbot/php/\$domain_without_www.php
#chmod 755 /opt/killbot/php/\$domain_without_www.php

#Updating apache443-killbot.sh
sed -e "s|\*\*\*SubdomainAlias\*\*\*|\$subdomain_alias|g" -e "s|\*\*\*server_ip\*\*\*|\$SERVER_IP|g" -e "s|\*\*\*apache_script\*\*\*|\$apache_script|g"  -e "s|\*\*\*SSLCertificateFile\*\*\*|\$SSLCertificateFile|g" -e "s|\*\*\*SSLCertificateKeyFile\*\*\*|\$SSLCertificateKeyFile|g"  /opt/killbot/apache443-killbot.sh > /opt/killbot/sh/\$domain_without_www-killbot.sh
sed -e "s|\*\*\*SubdomainAlias\*\*\*|\$subdomain_alias|g" -e "s|\*\*\*server_ip\*\*\*|\$SERVER_IP|g" -e "s|\*\*\*SSLCertificateFile\*\*\*|\$SSLCertificateFile|g" -e "s|\*\*\*SSLCertificateKeyFile\*\*\*|\$SSLCertificateKeyFile|g"  /opt/killbot/apache443.sh > /opt/killbot/sh/\$domain_without_www.sh

#Disable SSL if the domain does not have "www"
if [[ "\$ip_without_www" == "\$ip_with_www" && -n "\$ip_without_www" ]]; then
    sed -i "s|\*\*\*www_ssl_on\*\*\*|SSLEngine on|g" /opt/killbot/sh/\$domain_without_www-killbot.sh    
else
    sed -i "s|\*\*\*www_ssl_on\*\*\*||g" /opt/killbot/sh/\$domain_without_www-killbot.sh    
fi

sudo chmod +x /opt/killbot/sh/\$domain_without_www-killbot.sh /opt/killbot/sh/\$domain_without_www.sh

#Determine the primary mirror based on the www variable
if [ "\$www" -eq 0 ]; then
    main_domain="\$domain_without_www"
    secondary_domain="www.\$domain_without_www"
else
    main_domain="www.\$domain_without_www"
    secondary_domain="\$domain_without_www"
fi

# Creating an Apache configuration file with KillBot support so that the site opens through the KillBot verification screen.
output=\$(/opt/killbot/sh/\$domain_without_www-killbot.sh "\$domain_without_www" "\$main_domain" "\$secondary_domain" "\$backend_ip" "\$wlua" "\$wlpath" "\$wlip" "\$folder")

if echo "\$output" | grep -q "created"; then
    echo "The Apache file with the KillBot screen on port 443 has been created."
else
    echo "Error: There is no confirmation of file creation in the script output."
    echo "Script output: \$output"
    exit 1
fi

# Creating an Apache configuration file without KillBot support - simple proxying.
#output=\$(/opt/killbot/apache443.sh "\$domain_without_www" "\$backend_ip" "\$folder")
output=\$(/opt/killbot/sh/\$domain_without_www.sh "\$domain_without_www" "\$main_domain" "\$secondary_domain" "\$backend_ip" "\$folder")


if echo "\$output" | grep -q "created"; then
    echo "The Apache file without KillBot on port 443 has been created."
else
    echo "Error: There is no confirmation of file creation in the script output."
    echo "Script output: \$output"
    exit 1
fi

# Disable SSL if the domain does not have www
if [[ "\$ip_without_www" == "\$ip_with_www" && -n "\$ip_without_www" ]]; then
    sed -i "s|\*\*\*www_ssl_on\*\*\*|SSLEngine on|g" /etc/apache2/sites-available/\$domain_without_www.conf    
else
    sed -i "s|\*\*\*www_ssl_on\*\*\*||g" /etc/apache2/sites-available/\$domain_without_www.conf
fi

if [ "\$backend_ip" != "localhost" ]; then
    echo "The Apache server for the site \$domain_without_www is configured as a reverse proxy to IP=\$backend_ip"
    sed -i "s|#Define PROXY_ENABLE|Define PROXY_ENABLE|g" /etc/apache2/sites-available/\$domain_without_www-killbot.conf
    sed -i "s|#Define PROXY_ENABLE|Define PROXY_ENABLE|g" /etc/apache2/sites-available/\$domain_without_www.conf
else
    echo "The Apache server for the site \$domain_without_www is configured to the localhost directory \$folder"
fi

apache_check=\$(sudo apachectl configtest 2>&1)

if echo "\$apache_check" | grep -q "Syntax OK"; then
    echo "Apache configuration for \$domain_without_www is correct."
else
    echo "Apache configuration error for \$domain_without_www: \$apache_check"

    #sudo a2dissite "\$domain_without_www"
    #sudo rm -f "/etc/apache2/sites-available/\$domain_without_www.conf"

    exit 1
fi

sudo a2dissite "\$domain_without_www"
sudo a2ensite "\$domain_without_www-killbot"

apache_check=\$(sudo apachectl configtest 2>&1)

if echo "\$apache_check" | grep -q "Syntax OK"; then
    echo "Apache configuration for \$domain_without_www is correct."
else
    echo "Apache configuration error for \$domain_without_www: \$apache_check"

    #sudo a2dissite "\$domain_without_www"
    #sudo rm -f "/etc/apache2/sites-available/\$domain_without_www.conf"

    exit 1
fi

sudo systemctl reload apache2
sudo systemctl start apache2

if [ "\$backend_ip" != "localhost" ]; then
    echo "Success: Killbot configuration with verification page for domain \$domain_without_www is configured as a reverse proxy to IP=\$backend_ip"
else
    echo "Success: Killbot configuration with verification page for domain \$domain_without_www  is configured to the localhost directory \$folder"
fi

EOF

sudo chmod +x /opt/killbot/install.sh


# Allow configure KillBot via php
RULE="www-data ALL=(ALL) NOPASSWD: /etc/init.d/kb"
SUDOERS_FILE="/etc/sudoers"
if sudo grep -Fxq "$RULE" "$SUDOERS_FILE"; then
    :
else    
    echo "$RULE" | sudo tee -a "$SUDOERS_FILE" > /dev/null    
fi
RULE="www-data ALL=(ALL) NOPASSWD: /opt/killbot/install.sh"
SUDOERS_FILE="/etc/sudoers"
if sudo grep -Fxq "$RULE" "$SUDOERS_FILE"; then
    :
else    
    echo "$RULE" | sudo tee -a "$SUDOERS_FILE" > /dev/null    
fi



sudo sudo tee /opt/killbot/update.sh > /dev/null <<EOF
#!/bin/bash
FILE="/opt/killbot/html/verification.php"
  
    curl -o "\$FILE" "https://data.killbot.ru/verification.html"
    
    if [ \$? -eq 0 ]; then
        echo "The verification page (verification.html) has been successfully loaded."
    else
        echo "Error loading the verification page."
        exit 1
    fi
    #sudo test -f /var/www/html/.htaccess || sudo tee /var/www/html/.htaccess > /dev/null <<EOF
    #<FilesMatch "\.(html|htm)$">
    #    Header set Cache-Control "no-cache, no-store, must-revalidate"
    #    Header set Pragma "no-cache"
    #    Header set Expires 0
    #</FilesMatch>


FILE="/opt/killbot/html/FakeBot.php"

    curl -o "\$FILE" "https://data.killbot.ru/FakeBot.html"

    if [ \$? -eq 0 ]; then
        echo "The FakeBot page (FakeBot.php) has been successfully loaded."
    else
        echo "Error loading the FakeBot page."
        exit 1
    fi

FILE="/opt/killbot/html/Expired.html"

    curl -o "\$FILE" "https://data.killbot.ru/Expired.html"

    if [ \$? -eq 0 ]; then
        echo "The Expired page (Expired.html) has been successfully loaded."
    else
        echo "Error loading the Expired page."
        exit 1
    fi

sudo chown www-data:www-data /opt/killbot/html/FakeBot.php /opt/killbot/html/verification.php

FILE="/opt/killbot/cert_wildcard_new.sh"

    curl -o "\$FILE" "https://data.killbot.ru/killbot_dns/cert_wildcard_new.sh"

    if [ \$? -eq 0 ]; then
        echo "The cert_wildcard_new.sh has been successfully loaded."
    else
        echo "Error loading the cert_wildcard_new.sh."
        exit 1
    fi

FILE="/opt/killbot/off_killbot_protection.sh"

    curl -o "\$FILE" "https://data.killbot.ru/killbot_dns/off_killbot_protection.sh"

    if [ \$? -eq 0 ]; then
        echo "The off_killbot_protection.sh has been successfully loaded."
    else
        echo "Error loading the off_killbot_protection.sh."
        exit 1
    fi

FILE="/opt/killbot/on_killbot_protection.sh"

    curl -o "\$FILE" "https://data.killbot.ru/killbot_dns/on_killbot_protection.sh"

    if [ \$? -eq 0 ]; then
        echo "The on_killbot_protection.sh has been successfully loaded."
    else
        echo "Error loading the on_killbot_protection.sh."
        exit 1
    fi

FILE="/opt/killbot/clean_up_unused_certs.sh"

    curl -o "\$FILE" "https://data.killbot.ru/killbot_dns/clean_up_unused_certs.sh"

    if [ \$? -eq 0 ]; then
        echo "The clean_up_unused_certs.sh has been successfully loaded."
    else
        echo "Error loading the clean_up_unused_certs.sh"
        exit 1
    fi

FILE="/opt/killbot/UpdateAll.sh"

    curl -o "\$FILE" "https://data.killbot.ru/killbot_dns/UpdateAll.sh"

    if [ \$? -eq 0 ]; then
        echo "The UpdateAll.sh has been successfully loaded."
    else
        echo "Error loading the UpdateAll.sh"
        exit 1
    fi

FILE="/opt/killbot/renew_wildcard.sh"
    curl -o "\$FILE" "https://data.killbot.ru/killbot_dns/renew_wildcard.sh"
    
    if [ \$? -eq 0 ]; then
        echo "The renew_wildcard.sh file has been successfully loaded."
    else
        echo "Error loading the renew_wildcard.shUpdateAll.sh file."
        exit 1
    fi

FILE="/opt/killbot/acme_check_api.sh"
    curl -o "\$FILE" "https://data.killbot.ru/killbot_dns/acme_check_api.sh"
    
    if [ \$? -eq 0 ]; then
        echo "The acme_check_api.sh file has been successfully loaded."
    else
        echo "Error loading the acme_check_api.sh file."
        exit 1
    fi

FILE="/opt/killbot/cert_delete.sh"
    curl -o "\$FILE" "https://data.killbot.ru/killbot_dns/cert_delete.sh"
    
    if [ \$? -eq 0 ]; then
        echo "The cert_delete.sh file has been successfully loaded."
    else
        echo "Error loading the cert_delete.sh file."
        exit 1
    fi

FILE="/root/.acme.sh/dnsapi/dns_nicru.sh"
    curl -o "\$FILE" "https://data.killbot.ru/killbot_dns/dnsapi/dns_nicru.sh"
    
    if [ \$? -eq 0 ]; then
        echo "The dns_nicru.sh file has been successfully loaded."
    else
        echo "Error loading the dns_nicru.sh file."
        exit 1
    fi

FILE="/root/.acme.sh/dnsapi/dns_selectel.sh"
    curl -o "\$FILE" "https://data.killbot.ru/killbot_dns/dnsapi/dns_selectel.sh"
    
    if [ \$? -eq 0 ]; then
        echo "The dns_selectel.sh file has been successfully loaded."
    else
        echo "Error loading the dns_selectel.sh file."
        exit 1
    fi


FILE="/opt/killbot/f2b/subnet-monitor.sh"
    curl -o "\$FILE" "https://data.killbot.ru/killbot_dns/subnet-monitor.sh"
    
    if [ \$? -eq 0 ]; then
        echo "The subnet-monitor.sh file has been successfully loaded."
    else
        echo "Error loading the subnet-monitor.sh file."
        exit 1
    fi



sudo chmod +x /root/.acme.sh/dnsapi/dns_selectel.sh /root/.acme.sh/dnsapi/dns_nicru.sh  /opt/killbot/f2b/subnet-monitor.sh  /opt/killbot/renew_wildcard.sh /opt/killbot/cert_delete.sh /opt/killbot/acme_check_api.sh /opt/killbot/on_killbot_protection.sh /opt/killbot/off_killbot_protection.sh /opt/killbot/cert_wildcard_new.sh /opt/killbot/clean_up_unused_certs.sh /opt/killbot/UpdateAll.sh


EOF

sudo chmod +x /opt/killbot/update.sh


# Copying configuration to make the default SSL certificate be the default one
cp "/etc/apache2/sites-available/default-ssl.conf" "/etc/apache2/sites-available/000-default-ssl.conf"
echo "Created copy: $TARGET_CONF"

#add default page empty_en.html and empty_ru.html
FILE="/etc/apache2/sites-available/000-default-ssl.conf"
MARKER="empty.php"
INSERT_AFTER="DocumentRoot /var/www/html"

BLOCK_RULES_SSL=$'\n    RewriteEngine On\n\n    RewriteCond %{REQUEST_URI} !^/kb\.php$\n    RewriteCond %{REQUEST_URI} !^/empty\.php$\n    RewriteRule ^ /empty.php [L]\n\n'
BLOCK_RULES_HTTP=$'\n    RewriteEngine On\n\n    RewriteCond %{REQUEST_METHOD} ^OPTIONS\n\n    RewriteRule .* - [R=403,L]\n\n    RewriteCond %{REQUEST_URI} !^/kb\.php$\n    RewriteCond %{REQUEST_URI} !^/empty\.php$\n    RewriteRule ^ /empty.php [L]\n\n'

if [ -f "$FILE" ]; then
    if grep -q "$MARKER" "$FILE"; then
        echo "Rules already exist in $FILE"
    else
        # Вставляем после строки DocumentRoot /var/www/html/
        sudo awk -v insert="$BLOCK_RULES_SSL" -v after="$INSERT_AFTER" '
        {
            print
            if ($0 ~ after) {
                print insert
            }
        }' "$FILE" > /tmp/tmp_conf && sudo mv /tmp/tmp_conf "$FILE"

        echo "Rules added to $FILE"
    fi
else
    echo "File $FILE not found, skipping..."
    exit 1
fi

FILE="/etc/apache2/sites-available/000-default.conf"
if [ -f "$FILE" ]; then
    if grep -q "$MARKER" "$FILE"; then
        echo "Rules already exist in $FILE"
    else
        # Вставляем после строки DocumentRoot /var/www/html/
        sudo awk -v insert="$BLOCK_RULES_HTTP" -v after="$INSERT_AFTER" '
        {
            print
            if ($0 ~ after) {
                print insert
            }
        }' "$FILE" > /tmp/tmp_conf && sudo mv /tmp/tmp_conf "$FILE"

        echo "Rules added to $FILE"
    fi
else
    echo "File $FILE not found, skipping..."
    exit 1
fi

# Enabling configuration
a2ensite 000-default-ssl.conf
echo "Configuration 000-default-ssl.conf enabled"


SERVER_IP=$(curl -s http://checkip.amazonaws.com)
#echo "Public server IP: $SERVER_IP"

# Adding blocking rules to prevent the site from being accessed by IP address
#BLOCK_RULES_80="\n<VirtualHost *:80>\n    ServerName $SERVER_IP\n    <Location '/kb.php'>\n        Require all granted\n    </Location>\n    <Location '/'>\n        Require all denied\n        ErrorDocument 403 'Forbidden'\n    </Location>\n</VirtualHost>\n"
#BLOCK_RULES_443="\n<VirtualHost *:443>\n    ServerName $SERVER_IP\n    <Location '/kb.php'>\n        Require all granted\n    </Location>\n    <Location '/'>\n        Require all denied\n        ErrorDocument 403 'Forbidden'\n    </Location>\n</VirtualHost>\n"

BLOCK_RULES_443="\n<VirtualHost *:443>\n    ServerName $SERVER_IP\n    DocumentRoot /var/www/html\n\n    <Directory \"/var/www/html\">\n        Require all denied\n        <Files \"kb.php\">\n            Require all granted\n        </Files>\n    </Directory>\n\n</VirtualHost>\n"
BLOCK_RULES_80="\n<VirtualHost *:80>\n    ServerName $SERVER_IP\n    DocumentRoot /var/www/html\n\n      RewriteEngine On\n\n    RewriteCond %{REQUEST_METHOD} ^OPTIONS\n\n    RewriteRule .* - [R=403,L]\n\n  <Directory \"/var/www/html\">\n        Require all denied\n        <Files \"kb.php\">\n            Require all granted\n        </Files>\n    </Directory>\n\n</VirtualHost>\n"

FILE="/etc/apache2/sites-available/000-default.conf"
if [ -f "$FILE" ]; then
    if ! grep -q "ServerName $SERVER_IP" "$FILE"; then
        echo -e "$BLOCK_RULES_80" | sudo tee -a "$FILE" > /dev/null
        echo "Rules added to $FILE"
    else
        echo "Rules already exist in $FILE"
    fi
else
    echo "File $FILE not found, skipping..."
fi

FILE="/etc/apache2/sites-available/000-default-ssl.conf"
if [ -f "$FILE" ]; then
    if ! grep -q "ServerName $SERVER_IP" "$FILE"; then
        echo -e "$BLOCK_RULES_443" | sudo tee -a "$FILE" > /dev/null
        echo "Rules added to $FILE"
    else
        echo "Rules already exist in $FILE"
    fi
else
    echo "File $FILE not found, skipping..."
fi




# Stopping Apache before making changes
sudo systemctl stop apache2

# Changing the number of concurrent connections. Modifying KeepAliveTimeout configuration and
CONFIG_FILE="/etc/apache2/apache2.conf"
MPM_PREFORK_FILE="/etc/apache2/mods-available/mpm_prefork.conf"
MPM_EVENT_FILE="/etc/apache2/mods-available/mpm_event.conf"
MPM_WORKER_FILE="/etc/apache2/mods-available/mpm_worker.conf"

# Set KeepAliveTimeout to 1 second
sudo sed -i 's/^KeepAliveTimeout.*/KeepAliveTimeout 1/' "$CONFIG_FILE"

# Set maximum number of concurrent connections in Apache
sudo sed -i "s/^MaxRequestWorkers.*/MaxRequestWorkers $MAX_CONNECTIONS_WORKERS/" "$CONFIG_FILE"

# Configure MPM settings (prefork, event, worker)
for MPM_FILE in "$MPM_PREFORK_FILE" "$MPM_EVENT_FILE" "$MPM_WORKER_FILE"; do
    if [ -f "$MPM_FILE" ]; then
        sudo cp "$MPM_FILE" "$MPM_FILE.bak"
        sudo sed -i "s/^\s*MaxRequestWorkers.*/    MaxRequestWorkers $MAX_CONNECTIONS_WORKERS/" "$MPM_FILE"
        sudo sed -i "s/^\s*MaxConnectionsPerChild.*/    MaxConnectionsPerChild 1000/" "$MPM_FILE"

        # Проверяем, есть ли ServerLimit
        if grep -q "^\s*ServerLimit" "$MPM_FILE"; then
            # Если есть, обновляем
            sudo sed -i "s/^\s*ServerLimit.*/    ServerLimit $MAX_CONNECTIONS/" "$MPM_FILE"
        else
            # Если нет, добавляем сразу после MaxRequestWorkers
            sudo sed -i "/^\s*MaxRequestWorkers.*/a\    ServerLimit $MAX_CONNECTIONS" "$MPM_FILE"
        fi

    fi
done


# Set SSLSessionCache to 2MB if not already set
SSL_CONF="/etc/apache2/mods-available/ssl.conf"
echo "Checking and updating SSLSessionCache..."

if [ -f "$SSL_CONF" ]; then
    if grep -q "^SSLSessionCache.*2097152" "$SSL_CONF"; then
        echo "SSLSessionCache is already set to 2097152 — no changes made."
    elif grep -q "^SSLSessionCache" "$SSL_CONF"; then
        # Replace the existing SSLSessionCache line with the desired value
        sudo sed -i 's|^SSLSessionCache.*|SSLSessionCache shmcb:/var/cache/apache2/ssl_scache(33554432)|' "$SSL_CONF"
        echo "SSLSessionCache updated to 2097152."
    else
        # If SSLSessionCache is not defined, append the correct value
        echo "SSLSessionCache shmcb:/var/cache/apache2/ssl_scache(2097152)" | sudo tee -a "$SSL_CONF" > /dev/null
        echo "SSLSessionCache set to 2097152."
    fi
else
    echo "File $SSL_CONF not found! Exiting."
    exit 1
fi


SYSCTL_CONF="/etc/sysctl.conf"

# Lines to be added
CONFIG_LINES=(
"net.ipv6.conf.all.disable_ipv6 = 1"
"net.ipv6.conf.default.disable_ipv6 = 1"
"net.ipv6.conf.lo.disable_ipv6 = 1"
)

echo "Checking and adding IPv6 disable settings to $SYSCTL_CONF..."

for line in "${CONFIG_LINES[@]}"; do
    # Escape dots for grep
    escaped_line=$(echo "$line" | sed 's/\./\\./g')
    if grep -q "^$escaped_line" "$SYSCTL_CONF"; then
        echo "Already present: $line"
    else
        echo "$line" | sudo tee -a "$SYSCTL_CONF" > /dev/null
        echo "Added: $line"
    fi
done

# Apply changes immediately
echo "Applying sysctl settings..."
sudo sysctl -p

echo "IPv6 disable settings are applied and persisted."


CONF_FILE="/etc/apache2/apache2.conf"
MUTEX_LINE="#Mutex posixsem rewrite-map"

#disable mutex
if grep -Fxq "$MUTEX_LINE" "$CONF_FILE"; then
    echo "mutex already exist in $CONF_FILE"
else
    echo "$MUTEX_LINE" | sudo tee -a "$CONF_FILE" > /dev/null
    echo "mutex added to $CONF_FILE"
fi

# Path to configuration file
MODSEC_DIR="/etc/modsecurity"
MODSEC_FILE="${MODSEC_DIR}/killbot-bots.conf"

# Create /etc/modsecurity directory if it doesn't exist
sudo mkdir -p "$MODSEC_DIR"

# Create configuration file to prevent large number of bot visits /etc/modsecurity/killbot.conf
sudo tee "$MODSEC_FILE" > /dev/null <<EOL
# Enable request processing
SecRuleEngine On

SecAction "id:1001,phase:1,pass,nolog,setvar:tx.kbRes_counter=0"

SecRule REQUEST_COOKIES "kbRes=true" \
    "id:1002,phase:2,pass,nolog,setvar:tx.kbRes_counter=+1"

# Check if counter exceeds limit
SecRule TX:kbRes_counter "@gt $MAX_CONNECTIONS_BOTS" \
    "id:1003,phase:2,deny,status:302,redirect:/BlockBot.html,msg:'Bot connection limit exceeded'"
EOL


MODSEC_FILE="${MODSEC_DIR}/killbot-slow.conf"
# Create configuration file to prevent slow connections /etc/modsecurity/killbot-slow.conf
sudo tee "$MODSEC_FILE" > /dev/null <<EOL
# Enable request processing
SecRuleEngine On

# Record the request processing start time
SecRule REQUEST_URI "@streq /opt/killbot/verification.php" \
    "id:2001,phase:1,pass,nolog,setvar:tx.start_time=%{TIME}"

# Check if processing time exceeds 5 seconds
SecRule TX:START_TIME "@lt %{TIME}-5" \
    "id:2002,phase:4,deny,status:408,msg:'Slow request detected',log,chain"
SecRule REQUEST_URI "@streq /opt/killbot/verification.php"
EOL

MODSEC_FILE="${MODSEC_DIR}/killbot-ip.conf"
# Create configuration file for multiple requests to verification.php /etc/modsecurity/killbot-ip.conf
sudo tee "$MODSEC_FILE" > /dev/null <<EOL
# Включаем обработку запросов
SecRuleEngine On

# Initialize counter only for /opt/killbot/verification.php
SecRule REQUEST_URI "@streq /opt/killbot/verification.php" \
    "id:3001,phase:1,pass,nolog,initcol:ip=%{REMOTE_ADDR}"

# Increment request counter for current IP
SecRule REQUEST_URI "@streq /opt/killbot/verification.php" \
    "id:3002,phase:2,pass,nolog,setvar:ip.requests=+1"

# Check if request count exceeds limit (MAX_CONNECTIONS_IP_VP)
SecRule IP:REQUESTS "@gt $MAX_CONNECTIONS_IP_VP" \
    "id:3003,phase:2,deny,status:429,msg:'Too many requests from this IP',log"
EOL


CONFIG_FILE="/etc/apache2/mods-available/security2.conf"
# Check if the line is already commented
if grep -q '^\s*#\s*IncludeOptional /usr/share/modsecurity-crs/\*\.load' "$CONFIG_FILE"; then
  echo "Line is already commented. Doing nothing."
fi
# If line is not commented, comment it out
sed -i '/^\s*IncludeOptional \/usr\/share\/modsecurity-crs\/\*\.load/s/^/# /' "$CONFIG_FILE"

# Path to Apache2 configuration file in systemd
CONFIG_FILE="/etc/systemd/system/apache2.service.d/autorestart.conf"

# Create configuration directory if it doesn't exist
mkdir -p /etc/systemd/system/apache2.service.d

# Create or modify configuration file
echo "[Service]" > "$CONFIG_FILE"
echo "Restart=always" >> "$CONFIG_FILE"
echo "RestartSec=10" >> "$CONFIG_FILE"

# Define variables for easy configuration
APACHE_USER="www-data"
SERVICE_NAME="apache2"

# Check if running as root
if [ "$EUID" -ne 0 ]; then
    echo "Please run as root"
    exit 1
fi

# 1. Configure system-wide file descriptor limit
echo "Configuring system-wide file descriptors..."
# Remove existing entry if present and append new value
sed -i "/fs.file-max/d" /etc/sysctl.conf
echo "fs.file-max = $MAX_OPEN_FILES_SYS" >> /etc/sysctl.conf
sysctl -p

# 2. Configure user limits in limits.conf
echo "Configuring user limits..."
# Function to update or add limit
update_limit() {
    local user=$1
    local type=$2
    local limit=$3
    local value=$4

    # Escape special characters in user pattern
    local user_pattern=$(sed 's/[][\.*^$]/\\&/g' <<< "$user")

    # Update existing entry or append new one
    sed -i "/^$user_pattern[[:space:]]\+$type[[:space:]]\+$limit/d" /etc/security/limits.conf
    echo "$user        $type    $limit      $value" >> /etc/security/limits.conf
}

# Update limits for different users
update_limit "$APACHE_USER" "soft" "nofile" "$MAX_OPEN_FILES"
update_limit "$APACHE_USER" "hard" "nofile" "$MAX_OPEN_FILES"
update_limit "*" "soft" "nofile" "$MAX_OPEN_FILES"
update_limit "*" "hard" "nofile" "$MAX_OPEN_FILES"
update_limit "root" "soft" "nofile" "$MAX_OPEN_FILES"
update_limit "root" "hard" "nofile" "$MAX_OPEN_FILES"

# 3. Configure systemd global limits
echo "Configuring systemd global limits..."
sed -i "/^DefaultLimitNOFILE=/d" /etc/systemd/system.conf
echo "DefaultLimitNOFILE=$MAX_OPEN_FILES" >> /etc/systemd/system.conf

# 4. Configure Apache service limits
echo "Configuring Apache service limits..."
mkdir -p /etc/systemd/system/${SERVICE_NAME}.service.d/
cat << EOF > /etc/systemd/system/${SERVICE_NAME}.service.d/limit_nofile.conf
[Service]
Nice=-10
LimitNOFILE=$MAX_OPEN_FILES
LimitNPROC=$MAX_PROCESSES
EOF

# 5. Configure PAM modules
echo "Configuring PAM..."
# Remove existing entry if present and append new value
sed -i "/pam_limits\.so/d" /etc/pam.d/common-session
echo "session required pam_limits.so" >> /etc/pam.d/common-session

PAM_LINE="session required pam_limits.so"
PAM_FILE="/etc/pam.d/sudo"

# Check if the line already exists (exact match)
if ! grep -Fxq "$PAM_LINE" "$PAM_FILE"; then
    echo "$PAM_LINE" >> "$PAM_FILE"
fi

# Configuration file for Apache log rotation
ROTATE_CONF="/etc/logrotate.d/apache2"

# Check if the configuration file exists
if [ ! -f "$ROTATE_CONF" ]; then
    echo "Creating new Apache log rotation configuration"
    cat <<EOF | sudo tee "$ROTATE_CONF"
/var/log/apache2/*.log {
    daily                      # Rotate logs daily
    missingok                 # Don't fail if log is missing
    rotate 3                  # Keep only 3 days of logs
    compress                  # Compress rotated logs
    delaycompress             # Compress on next rotation cycle
    notifempty                # Don't rotate empty logs
    create 640 root adm       # Set proper permissions
    sharedscripts             # Run scripts only once for all logs
    postrotate                # Command to run after rotation
        /usr/lib/apache2/apache2ctl graceful  # Graceful Apache restart
    endscript
}
EOF
else
    echo "Updating existing log rotation configuration"
    
    # Update rotate parameter if it exists
    if grep -q "rotate" "$ROTATE_CONF"; then
        sudo sed -i 's/^\(\s*rotate\s*\)[0-9]\+/\13/' "$ROTATE_CONF"
    else
        # Add rotate parameter after daily if missing
        sudo sed -i '/daily/a \    rotate 3' "$ROTATE_CONF"
    fi
    
    # Ensure compression is enabled
    if ! grep -q "compress" "$ROTATE_CONF"; then
        sudo sed -i '/rotate/a \    compress' "$ROTATE_CONF"
    fi
fi

# Display the final configuration
echo "Current log rotation configuration:"
echo "----------------------------------"
cat "$ROTATE_CONF"
echo "----------------------------------"
echo "Apache log rotation is now configured to keep 3 days of logs"


# Reload systemd configuration
sudo systemctl daemon-reexec
sudo systemctl daemon-reload

# Restart Apache to apply changes
sudo systemctl stop apache2
sudo systemctl start apache2
echo "Apache restarted, changes applied!"


# Check if cron is installed
#if ! command -v crontab &> /dev/null; then
#    echo "Cron is not installed. Please install it first (e.g., 'apt-get install cron')." >&2
#    exit 1
#fi

# Define the cron job (restart Apache daily at 3:00 AM)
#CRON_JOB="0 3 * * * /usr/bin/systemctl stop apache2 && sleep 2 && /usr/bin/systemctl start apache2 >> /var/log/apache_restart.log 2>&1"

# Check if the cron job already exists to avoid duplicates
#if crontab -l | grep -qF "$CRON_JOB"; then
#    echo "Cron job already exists. Skipping addition."
#else
    # Add the cron job to the crontab
#    echo "Adding cron job..."
#   (crontab -l 2>/dev/null; echo "$CRON_JOB") | crontab -
    # Verify the job was added successfully
#    if crontab -l | grep -qF "$CRON_JOB"; then
#        echo "Cron job added successfully."
#    else
#        echo "Error: Failed to add cron job!" >&2
        #exit 1
#    fi
#fi


# Verification
echo -e "\nVerification:"
echo "0. User file limit: $(sudo -u www-data bash -c 'ulimit -n')"
echo "1. System-wide file-max: $(cat /proc/sys/fs/file-max)"
result=$(cat /proc/$(pgrep -u root -f 'apache2' | head -n1)/limits | grep 'open files')
echo "2. Apache single process open files limit: $result"
echo "3. MPM: $(apache2ctl -M 2>/dev/null | grep mpm_)"

# Check Apache2 status
systemctl status apache2 --no-pager

echo "Configuration complete. Apache2 will automatically restart on failure."

# cron filename
CRON_FILE="/etc/cron.d/killbot-cleanup"
SCRIPT_PATH="/opt/killbot/clean_up_unused_certs.sh"

# Создаем конфигурацию для cron
echo "# Clean unuser certs for KillBot
0 0 * * 0 root $SCRIPT_PATH
* * * * * root /opt/killbot/f2b/subnet-monitor.sh run >> /var/log/killbot/subnet-monitor-cron.log
" | sudo tee "$CRON_FILE" > /dev/null

echo "KillBot cron file: $CRON_FILE"

#Останавливаем и отключаем fail2ban
#sudo systemctl stop fail2ban
#sudo systemctl disable fail2ban 
#sudo fail2ban-client status

#allow ports
#sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
#sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
#sudo netfilter-persistent save
#sudo ufw allow 80/tcp
#sudo ufw allow 443/tcp
#sudo ufw reload
#sudo ufw status

# Create cron job to run every 20 minutes
sudo tee /etc/cron.d/killbot-wildcard-renewal > /dev/null <<EOF
# KillBot Wildcard SSL Certificate Renewal
# Run every 30 minutes
*/30 * * * * root /opt/killbot/renew_wildcard.sh >> /var/log/killbot/wildcard.log 2>&1
EOF

# Set proper permissions for cron file
sudo chmod 644 /etc/cron.d/killbot-wildcard-renewal

echo "Wildcard SSL certificate renewal system installed successfully!"
echo "Cron job created to run every 20 minutes"
echo "Log file location: /var/log/killbot/wildcard_renewal.log"

#close mail service
sudo systemctl stop postfix
sudo systemctl disable postfix
