Files

525 lines
20 KiB
Bash
Executable File

#!/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 <<EOF > /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 <<EOF > /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 "$@"