#!/bin/bash # Exit immediately if a command exits with a non-zero status. set -euo pipefail # helper to rewrite configure_from_template() { local file="$1" local placeholder="$2" local value="$3" local escaped_value escaped_value=$(sed 's/[&|\\]/\\&/g' <<<"$value") sed -i "s|$placeholder|$escaped_value|g" "$file" } exit_with_error() { local message="$1" echo "ERROR: ${message}" >&2 echo -e "\e[0m" exit 1 } ################################################################################ # SCRIPT LOGIC FUNCTIONS ################################################################################ # Checks OS version, root privileges, and configuration sanity. check_prerequisites() { echo "--- 1. Checking Prerequisites ---" # --- OS Check --- source /etc/os-release local expected_dist="debian" local expected_release="bookworm" if [[ "$ID" != "$expected_dist" || "$VERSION_CODENAME" != "$expected_release" ]]; then exit_with_error "ERROR: This script is only for a fresh install on $expected_dist $expected_release." fi echo " -> OS check passed (Debian 12 Bookworm)." # --- Root User Check --- if [ "$(id -u)" -ne 0 ]; then exit_with_error "ERROR: This script must be run as root." fi echo " -> Root privileges check passed." # --- Config Sanity Checks --- if [ ${#MASTERONION} -lt 62 ]; then exit_with_error "ERROR: MASTERONION in endgame.config must be at least 62 characters (including .onion)." fi if [ "$KEY" = "encryption_key" ]; then exit_with_error "ERROR: Change the default 'encryption_key' in endgame.config." fi if [ ${#SALT} -ne 8 ]; then exit_with_error "ERROR: The 'SALT' variable in endgame.config must be exactly 8 characters long." fi if [ -z "$TORAUTHPASSWORD" ]; then exit_with_error "ERROR: The 'TORAUTHPASSWORD' variable in endgame.config cannot be empty." fi echo " -> endgame.config sanity checks passed." } generate_master_key() { echo "--- 2. Generating Master Key ---" local salt_hex salt_hex=$(echo -n "$SALT" | od -A n -t x1 | sed 's/ *//g') MASTER_KEY=$(openssl enc -aes-256-cbc -pbkdf2 -pass pass:"$KEY" -S "$salt_hex" -iter 2000000 -md sha256 -P | grep "key" | sed 's/key=//g') echo " -> Master key generated successfully." } # Generates the master key from the user's config values. generate_ssl_certificate() { # Check if hostname argument is provided if [[ -z "$1" ]]; then echo "Error: Hostname argument is required." >&2 return 1 fi local onion_hostname="$1" local ssl_path="${2:-/etc/nginx/ssl}" echo " -> Hostname: ${onion_hostname}" echo " -> Path: ${ssl_path}" mkdir -p "${ssl_path}" local key_path="${ssl_path}/${onion_hostname}.key" local cert_path="${ssl_path}/${onion_hostname}.crt" # We are using ECC not RSA for speed here. Clients should handle it fine. openssl req -x509 -nodes -days 3650 \ -newkey ec:<(openssl ecparam -name secp384r1) \ -keyout "${key_path}" \ -out "${cert_path}" \ -subj "/CN=${onion_hostname}" \ -addext "subjectAltName = DNS:${onion_hostname}" > /dev/null 2>&1 chown root:root "${key_path}" "${cert_path}" chmod 600 "${key_path}" chmod 644 "${cert_path}" echo " -> SSL certificate and key generated successfully." } # Replaces all placeholders in application files with values from the endgame.config. configure_files() { echo "--- 4. Configuring Application Files ---" # --- Nginx/Lua Configuration --- configure_from_template "lua/cap.lua" "encryption_key" "$KEY" configure_from_template "lua/cap.lua" "salt1234" "$SALT" configure_from_template "lua/cap.lua" "masterkeymasterkeymasterkey" "$MASTER_KEY" configure_from_template "lua/cap.lua" "sessionconfigvalue" "$SESSION_LENGTH" configure_from_template "site.conf" "sessionconfigvalue" "$SESSION_LENGTH" configure_from_template "site.conf" "requestratelimitvalue" "$REQUESTRATELIMIT" configure_from_template "site.conf" "streamratelimitvalue" "$STREAMRATELIMIT" configure_from_template "torrc" "streamratelimitvalue" "$STREAMRATELIMIT" # --- Styling Configuration --- configure_from_template "resty/cap_d.css" "HEXCOLORDARK" "$HEXCOLORDARK" configure_from_template "resty/cap_d.css" "HEXCOLOR" "$HEXCOLOR" configure_from_template "resty/cap_d.css" "SQUARELOGO" "$SQUARELOGO" configure_from_template "resty/cap_d.css" "NETWORKLOGO" "$NETWORKLOGO" configure_from_template "resty/queue.html" "HEXCOLORDARK" "$HEXCOLORDARK" configure_from_template "resty/queue.html" "HEXCOLOR" "$HEXCOLOR" configure_from_template "resty/queue.html" "SITENAME" "$SITENAME" configure_from_template "resty/queue.html" "FAVICON" "$FAVICON" configure_from_template "resty/queue.html" "SQUARELOGO" "$SQUARELOGO" configure_from_template "resty/caphtml.lua" "SITENAME" "$SITENAME" configure_from_template "resty/caphtml.lua" "SITETAGLINE" "$SITETAGLINE" configure_from_template "resty/caphtml.lua" "SITESINCE" "$SITESINCE" configure_from_template "resty/caphtml.lua" "FAVICON" "$FAVICON" echo " -> Configured application and styles." # --- Proxy/Backend Configuration --- if $LOCALPROXY; then echo " -> Configuring for local proxy pass." configure_from_template "site.conf" "backendurl" "$PROXYPASSURL" else echo " -> Configuring for Tor backend onions." configure_from_template "startup.sh" "HOSTNAME1" "$BACKENDONION1" configure_from_template "startup.sh" "HOSTNAME2" "$BACKENDONION2" sed -i 's/#t/t/' startup.sh > /dev/null 2>&1 sed -i 's/#n/n/' startup.sh > /dev/null 2>&1 configure_from_template "site.conf" "backendurl" "tor" fi # --- Tor Configuration --- echo " -> Configuring for Tor OnionBalance setup." configure_from_template "site.conf" "masterbalanceonion" "$MASTERONION" configure_from_template "site.conf" "torauthpassword" "$TORAUTHPASSWORD" } # Sets up APT repositories for Nginx, Tor, and optionally the unstable Kernel. setup_repositories() { echo "--- 5. Setting up APT Repositories ---" apt update > /dev/null 2>&1 apt install -y -q apt-transport-https lsb-release ca-certificates gpg > /dev/null 2>&1 # --- Nginx Repository --- echo "deb [signed-by=/etc/apt/trusted.gpg.d/nginx.gpg] https://nginx.org/packages/$ID/ $VERSION_CODENAME nginx" > /etc/apt/sources.list.d/nginx.list mv "repokeys/nginx.gpg" "/etc/apt/trusted.gpg.d/nginx.gpg" echo " -> Nginx repository configured." # --- Tor Repository --- echo "deb [signed-by=/usr/share/keyrings/deb.torproject.org-keyring.gpg] https://deb.torproject.org/torproject.org bookworm main" > /etc/apt/sources.list.d/tor.list mv "repokeys/deb.torproject.org-keyring.gpg" "/usr/share/keyrings/deb.torproject.org-keyring.gpg" echo " -> Tor Project repository configured." # --- Unstable Kernel Repository --- if $LATESTKERNEL; then echo " -> Configuring repository for latest unstable kernel." echo "deb https://deb.debian.org/debian unstable main contrib non-free" > /etc/apt/sources.list.d/kernel.list mv aptpreferences /etc/apt/preferences fi echo " -> Updating package lists..." apt update > /dev/null 2>&1 } # Installs all required packages and performs a system upgrade. install_dependencies() { echo "--- 6. Installing Dependencies and Upgrading System ---" # Define common silent apt options local APT_SILENT_OPTS="-y -qq -o Dpkg::Options::=--force-confdef" echo " -> Installing Core Dependencies..." # --- Core Dependencies --- DEBIAN_FRONTEND=noninteractive apt install $APT_SILENT_OPTS nginx build-essential zlib1g-dev libpcre3-dev uuid-dev gcc git wget curl libpcre2-dev > /dev/null 2>&1 # --- Tor Dependencies --- echo " -> Installing Tor Dependencies..." DEBIAN_FRONTEND=noninteractive apt install $APT_SILENT_OPTS tor nyx socat deb.torproject.org-keyring > /dev/null 2>&1 # --- System Hardening Tools --- echo " -> Installing Hardening Tools..." DEBIAN_FRONTEND=noninteractive apt install $APT_SILENT_OPTS apt-listbugs needrestart debsecan debsums fail2ban libpam-tmpdir rkhunter chkrootkit rng-tools > /dev/null 2>&1 # --- System Upgrade --- echo " -> Performing full system upgrade (this may take a while)..." DEBIAN_FRONTEND=noninteractive apt $APT_SILENT_OPTS full-upgrade > /dev/null 2>&1 # --- Latest Kernel Install --- if $LATESTKERNEL; then echo " -> Installing latest kernel from unstable..." DEBIAN_FRONTEND=noninteractive apt install $APT_SILENT_OPTS -t unstable linux-image-amd64 > /dev/null 2>&1 fi } # Builds and installs custom LuaJIT and OpenResty modules. build_and_install_modules() { echo "--- 7. Building and Installing Custom Lua Modules ---" export LD_LIBRARY_PATH=/usr/local/lib export LUAJIT_LIB=/usr/local/lib export LUAJIT_INC=/usr/local/include/luajit-2.1 # Persist environment variables for system-wide access echo "LD_LIBRARY_PATH=/usr/local/lib" > /etc/environment echo "LUAJIT_LIB=/usr/local/lib" >> /etc/environment echo "LUAJIT_INC=/usr/local/include/luajit-2.1" >> /etc/environment mkdir -p building cp -R dependencies/* building/ cd building echo " -> Building LuaJIT..." (cd luajit2 && make -j"$(nproc)" && make install) > /dev/null 2>&1 echo " -> Installing resty-string..." (cd lua-resty-string && make install) > /dev/null 2>&1 echo " -> Installing resty-cookie..." (cd lua-resty-cookie && make install) > /dev/null 2>&1 echo " -> Installing resty-session..." mkdir -p /usr/local/share/lua/5.1/resty/ cp -a lua-resty-session/lib/resty/* /usr/local/share/lua/5.1/resty/ cd .. echo " -> Custom modules installed." } # Configures system services, hardening, and file placements. configure_system() { echo "--- 8. Performing System Configuration and Hardening ---" # --- Build and Place Nginx/Lua files --- tar zxf resty.tgz -C /usr/local/share/lua/5.1/resty ./nginx-update.sh > /dev/null 2>&1 mv nginx.conf /etc/nginx/nginx.conf mv naxsi_core.rules /etc/nginx/naxsi_core.rules mv naxsi_whitelist.rules /etc/nginx/naxsi_whitelist.rules if [ $CAPTCHA == false ]; then configure_from_template "resty/nocaphtml.lua" "sessionconfigvalue" "$SESSION_LENGTH" configure_from_template "resty/nocaphtml.lua" "SITENAME" "$SITENAME" configure_from_template "lua/cap.lua" "caphtml" "nocaphtml" fi rm -rf /etc/nginx/lua mv lua /etc/nginx/ mkdir -p /etc/nginx/resty/ mv resty/* /etc/nginx/resty/ mkdir -p /etc/nginx/sites-enabled/ mv site.conf /etc/nginx/sites-enabled/site.conf # --- Create Cache Dirs and Set Permissions --- mkdir -p /etc/nginx/cache/ chown -R www-data:www-data /etc/nginx/ chown -R www-data:www-data /usr/local/lib/lua /usr/local/share/lua/ # --- Fail2ban --- mv jail.local /etc/fail2ban/jail.local systemctl restart fail2ban > /dev/null 2>&1 systemctl enable fail2ban > /dev/null 2>&1 echo " -> Fail2ban configured and enabled." # --- Set TimeZone to UTC --- timedatectl set-timezone UTC # --- Custom Startup Service --- chmod 500 startup.sh chown debian-tor:debian-tor startup.sh mv startup.sh /startup.sh cat < /etc/systemd/system/endgame.service [Unit] Description=Endgame Startup Script Service [Service] Type=forking ExecStart=/startup.sh [Install] WantedBy=multi-user.target EOF chown root:root /etc/systemd/system/endgame.service chmod 600 /etc/systemd/system/endgame.service echo " -> Endgame startup service created." # --- Harden Nginx Service --- cat < /lib/systemd/system/nginx.service [Unit] Description=nginx - high performance web server Documentation=https://nginx.org/en/docs/ After=network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=/var/run/nginx.pid ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf ExecReload=/bin/kill -s HUP $(cat /var/run/nginx.pid) ExecStop=/bin/kill -s TERM $(cat /var/run/nginx.pid) Environment="LD_LIBRARY_PATH=/usr/local/lib" ProtectHome=true NoNewPrivileges=true ProtectKernelTunables=true ProtectKernelLogs=true ProtectControlGroups=true ProtectKernelModules=yes KeyringMode=private ProtectClock=true ProtectHostname=true [Install] WantedBy=multi-user.target EOF echo " -> Nginx systemd service hardened." # --- System Limits and Kernel Parameters --- mv sysctl.conf /etc/sysctl.conf mv limits.conf /etc/security/limits.conf echo " -> System limits and sysctl parameters applied." # --- Cron Jobs --- echo "*/5 * * * * root cd /etc/nginx/resty/ && ./captcha && nginx -s reload" > /etc/cron.d/endgame echo "0 0 * * * root /usr/sbin/logrotate -f /etc/logrotate.conf" > /etc/cron.d/logrotate echo " -> Cron jobs for captcha generation and log rotation created." # --- Logrotate Config --- rm -f /etc/logrotate.d/nginx cat << EOF > /etc/logrotate.d/nginx /var/log/nginx/*.log { daily rotate 7 missingok notifempty compress sharedscripts postrotate if [ -f /var/run/nginx.pid ]; then kill -USR1 \`cat /var/run/nginx.pid\` fi endscript } EOF rm -rf /var/log/nginx/ mkdir /var/log/nginx/ chown www-data:www-data /var/log/nginx echo " -> Nginx log rotation configured." systemctl daemon-reload > /dev/null 2>&1 systemctl enable endgame.service > /dev/null 2>&1 systemctl enable nginx.service > /dev/null 2>&1 } # Configures and launches the Tor front's instance. configure_and_start_tor() { echo "--- 9. Configuring Tor OnionBalance Instance ---" if $TORMINWORK; then (cd tor-patch && ./tor-build.sh) > /dev/null 2>&1 fi mv torrc /etc/tor/torrc mv torrc2 /etc/tor/torrc2 mv torrc3 /etc/tor/torrc3 chown -R debian-tor:debian-tor /etc/tor/ local torhash torhash=$(tor --hash-password "$TORAUTHPASSWORD" | tail -c 62) configure_from_template "/etc/tor/torrc" "hashedpassword" "$torhash" echo " -> Starting Tor to generate hidden service files..." tor >/dev/null 2>&1 sleep 10 if [ -d hidden_service ]; then rm -rf /etc/tor/hidden_service cp -r hidden_service /etc/tor/ chown -R debian-tor:debian-tor /etc/tor/hidden_service chmod -R 700 /etc/tor/hidden_service fi TORHOSTNAME=$(cat /etc/tor/hidden_service/hostname) echo " -> Generating Self-Signed SSL Certificate for instance onion..." generate_ssl_certificate "$TORHOSTNAME" mv ssl/* /etc/nginx/ssl/ echo " -> Generating Strong Diffie-Hellman with safe prime (can take a long time)..." openssl dhparam -dsaparam -out /etc/nginx/ssl/dhparams.pem 4096 chown -R www-data:www-data /etc/nginx/ configure_from_template "/etc/nginx/sites-enabled/site.conf" "mainonion" "$TORHOSTNAME" echo "MasterOnionAddress $MASTERONION" > /etc/tor/hidden_service/ob_config echo " -> Applying final OnionBalance configuration..." sed -i "s/#HiddenServiceOnionBalanceInstance/HiddenServiceOnionBalanceInstance/g" /etc/tor/torrc > /dev/null 2>&1 if $TORINTRODEFENSE; then sed -i "s/#HiddenServiceEnableIntroDoS/HiddenServiceEnableIntroDoS/g" /etc/tor/torrc > /dev/null 2>&1 fi if $TORPOWDEFENSE; then sed -i "s/#HiddenServicePoWDefensesEnabled/HiddenServicePoWDefensesEnabled/g" /etc/tor/torrc > /dev/null 2>&1 fi if $TORMINWORK; then sed -i "s/#HiddenServicePoWEffort/HiddenServicePoWEffort/g" /etc/tor/torrc > /dev/null 2>&1 fi echo " -> Restarting Tor with final configuration..." pkill tor sleep 3 tor >/dev/null 2>&1 echo " -> Tor setup complete." } # Finalizes the setup by starting services. finalize_setup() { echo "--- 10. Finalizing Setup ---" echo " -> Generating initial captcha set..." (cd /etc/nginx/resty/ && ./captcha) > /dev/null 2>&1 echo " -> Starting services..." systemctl start nginx.service > /dev/null 2>&1 systemctl start endgame.service > /dev/null 2>&1 #remove the tor service autostart so the endgame script can run it systemctl disable tor echo "================================================" echo "EndGame Setup Script Finished!" echo "================================================" echo "Tor Onion Service Hostname: $TORHOSTNAME" if $TORPOWDEFENSE; then echo "POW DEFENSES ENABLED. YOU CAN'T USE THIS WITH GOBALANCE AS IT DOESN'T SUPPORT POW! Just provide the URL to your users." else echo "Add this address to your gobalance config.yaml file!" fi if $REBOOT; then echo -e "--- The system will now reboot in 10 seconds as requested! ---" sleep 10 reboot fi echo -e "\e[0m" #exit purple color } ################################################################################ # MAIN EXECUTION ################################################################################ main() { echo -e "\e[1;35m" #purple color ART="███████╗███╗ ██╗██████╗ ██████╗ █████╗ ███╗ ███╗███████╗ ██╗ ██╗██████╗ ███████╗\n" ART+="██╔════╝████╗ ██║██╔══██╗██╔════╝ ██╔══██╗████╗ ████║██╔════╝ ██║ ██║╚════██╗ ██╔════╝\n" ART+="█████╗ ██╔██╗ ██║██║ ██║██║ ███╗███████║██╔████╔██║█████╗ ██║ ██║ █████╔╝ ███████╗\n" ART+="██╔══╝ ██║╚██╗██║██║ ██║██║ ██║██╔══██║██║╚██╔╝██║██╔══╝ ╚██╗ ██╔╝ ╚═══██╗ ╚════██║\n" ART+="███████╗██║ ╚████║██████╔╝╚██████╔╝██║ ██║██║ ╚═╝ ██║███████╗ ╚████╔╝ ██████╔╝██╗███████║\n" ART+="╚══════╝╚═╝ ╚═══╝╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═══╝ ╚═════╝ ╚═╝╚══════╝\n" export ENDGAME_ART="$ART" echo -e "$ENDGAME_ART" echo "Welcome To The EndGame DDOS Prevention Setup..." sleep 1 echo "This anti-ddos script was created with help from multiple individuals including:" echo "/u/Paris (admin of dread)" echo "/u/MrWhite (admin of WHM)" echo "/u/Drughub (admin of Drughub)" echo "/u/InfinityProject" echo "/u/francium87" sleep 1 if ! source endgame.config; then echo "FATAL: endgame.config not found or contains errors. Exiting." >&2 exit 1 fi echo "Welcome To The EndGame DDOS Prevention Setup..." if $REBOOT; then echo "--- The system will reboot after finishing setup! ---" fi sleep 1 check_prerequisites generate_master_key if [ -d "ssl" ]; then echo "--- 3. Using Configured SSL Certificate ---" else echo "--- 3. Generating Self-Signed SSL Certificate ---" generate_ssl_certificate "$MASTERONION" "ssl"; fi configure_files setup_repositories install_dependencies build_and_install_modules configure_system configure_and_start_tor finalize_setup exit 0 } main "$@"