946 lines
28 KiB
Bash
946 lines
28 KiB
Bash
#!/bin/bash
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
|
|
### CONFIGURATION ###
|
|
BUILD=20240727
|
|
PASS=$(openssl rand -base64 32 | sha256sum | base64 | head -c 32 | tr '[:upper:]' '[:lower:]')
|
|
DBPASS=$(openssl rand -base64 24 | sha256sum | base64 | head -c 32 | tr '[:upper:]' '[:lower:]')
|
|
SERVERID=$(openssl rand -base64 12 | sha256sum | base64 | head -c 32 | tr '[:upper:]' '[:lower:]')
|
|
REPO=yolanmees/Spikster
|
|
BRANCH=master
|
|
ADMIN_EMAIL="your_admin_email@example.com"
|
|
USE_LOCAL_IP=false
|
|
|
|
# CLI tool coloring
|
|
reset=$(tput sgr0)
|
|
bold=$(tput bold)
|
|
underline=$(tput smul)
|
|
black=$(tput setaf 0)
|
|
white=$(tput setaf 7)
|
|
red=$(tput setaf 1)
|
|
green=$(tput setaf 2)
|
|
yellow=$(tput setaf 3)
|
|
blue=$(tput setaf 4)
|
|
purple=$(tput setaf 5)
|
|
bgblack=$(tput setab 0)
|
|
bgwhite=$(tput setab 7)
|
|
bgred=$(tput setab 1)
|
|
bggreen=$(tput setab 2)
|
|
bgyellow=$(tput setab 4)
|
|
bgblue=$(tput setab 4)
|
|
bgpurple=$(tput setab 5)
|
|
|
|
# Function to check disk space
|
|
check_disk_space() {
|
|
required_space=2048 #
|
|
available_space=$(df / | tail -1 | awk '{print $4}')
|
|
if ((available_space < required_space)); then
|
|
echo "${bgred}${white}${bold}Error: Not enough disk space.
|
|
Required: ${required_space}MB, Available: $(($available_space / 1024))MB.${reset}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Call to the disk space check function
|
|
clear
|
|
check_disk_space
|
|
|
|
# LOGO
|
|
clear
|
|
echo "${green}${bold}"
|
|
echo ""
|
|
echo "███████╗██████╗ ██╗██╗ ██╗███████╗████████╗███████╗██████╗ "
|
|
echo "██╔════╝██╔══██╗██║██║ ██╔╝██╔════╝╚══██╔══╝██╔════╝██╔══██╗"
|
|
echo "███████╗██████╔╝██║█████╔╝ ███████╗ ██║ █████╗ ██████╔╝"
|
|
echo "╚════██║██╔═══╝ ██║██╔═██╗ ╚════██║ ██║ ██╔══╝ ██╔══██╗"
|
|
echo "███████║██║ ██║██║ ██╗███████║ ██║ ███████╗██║ ██║"
|
|
echo "╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝"
|
|
echo ""
|
|
echo "Installation has been started... Hold on!"
|
|
echo "${reset}"
|
|
sleep 3s
|
|
|
|
help() {
|
|
echo "Usage: $0 [OPTIONS]
|
|
-n, --nginx Install Nginx [yes|no] default: yes
|
|
-p, --phpfpm Install PHP-FPM [yes|no] default: yes
|
|
-m, --mysql Install MySQL [yes|no] default: yes
|
|
-b, --branch Set branch for admin panel default: master
|
|
-f, --force Force installation
|
|
-l, --local Use local IP instead of external IP
|
|
-h, --help Print this help
|
|
|
|
Example: bash $0 -n no -p yes -m yes"
|
|
exit 1
|
|
}
|
|
|
|
# Parse short and long arguments
|
|
nginx='yes'
|
|
phpfpm='yes'
|
|
mysql='yes'
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case $1 in
|
|
-n | --nginx)
|
|
nginx="$2"
|
|
shift 2
|
|
;;
|
|
-p | --phpfpm)
|
|
phpfpm="$2"
|
|
shift 2
|
|
;;
|
|
-m | --mysql)
|
|
mysql="$2"
|
|
shift 2
|
|
;;
|
|
-b | --branch)
|
|
BRANCH="$2"
|
|
shift 2
|
|
;;
|
|
-f | --force)
|
|
force='yes'
|
|
shift
|
|
;;
|
|
-l | --local)
|
|
USE_LOCAL_IP=true
|
|
shift
|
|
;;
|
|
-h | --help)
|
|
help
|
|
;;
|
|
*)
|
|
echo "Unknown option: $1"
|
|
help
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Ensure valid input values
|
|
validate_choice() {
|
|
if [ "$1" != "yes" ] && [ "$1" != "no" ]; then
|
|
echo "${bgred}${white}${bold}Invalid option for $2. Expected [yes|no].${reset}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
validate_choice "$nginx" "Nginx"
|
|
validate_choice "$phpfpm" "PHP-FPM"
|
|
validate_choice "$mysql" "MySQL"
|
|
|
|
# Function to log messages
|
|
log_message() {
|
|
echo "$(date +'%Y-%m-%d %H:%M:%S') - $1" >>/var/log/spikster_install.log
|
|
}
|
|
|
|
# Function to handle errors gracefully
|
|
handle_error() {
|
|
echo "${bgred}${white}${bold}Error occurred during $1. Check logs for details. Exiting.${reset}"
|
|
log_message "Error occurred during $1. Exiting."
|
|
exit 1
|
|
}
|
|
|
|
# Check for existing software versions
|
|
log_message "Checking current versions of installed software"
|
|
nginx_version=$(nginx -v 2>&1)
|
|
php_version=$(php -v 2>&1)
|
|
mysql_version=$(mysql --version 2>&1)
|
|
versions=""
|
|
if dpkg -l | grep -qw nginx; then
|
|
versions+="Nginx: $nginx_version\n"
|
|
else
|
|
versions+="Nginx: Not installed\n"
|
|
fi
|
|
if dpkg -l | grep -qw php; then
|
|
versions+="PHP: $php_version\n"
|
|
else
|
|
versions+="PHP: Not installed\n"
|
|
fi
|
|
if dpkg -l | grep -qw mysql-server; then
|
|
versions+="MySQL: $mysql_version\n"
|
|
else
|
|
versions+="MySQL: Not installed\n"
|
|
fi
|
|
echo -e "$versions" >>/var/log/spikster_install.log
|
|
|
|
# OS Check
|
|
clear
|
|
log_message "OS check..."
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "OS check..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
ID=$(grep -oP '(?<=^ID=).+' /etc/os-release | tr -d '"')
|
|
VERSION=$(grep -oP '(?<=^VERSION_ID=).+' /etc/os-release | tr -d '"')
|
|
if [ "$ID" = "ubuntu" ]; then
|
|
case $VERSION in
|
|
20.04 | 22.04 | 23.04 | 24.04) ;;
|
|
*)
|
|
echo "${bgred}${white}${bold}"
|
|
echo "Spikster requires a minimum of Linux Ubuntu 20.04 LTS"
|
|
echo "${reset}"
|
|
log_message "Unsupported Ubuntu version: $VERSION"
|
|
exit 1
|
|
;;
|
|
esac
|
|
else
|
|
echo "${bgred}${white}${bold}"
|
|
echo "Spikster requires a minimum of Linux Ubuntu 20.04 LTS"
|
|
echo "${reset}"
|
|
log_message "Unsupported OS: $ID"
|
|
exit 1
|
|
fi
|
|
|
|
# Root check
|
|
clear
|
|
log_message "Permission check..."
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Permission check..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
if [ "$(id -u)" != "0" ]; then
|
|
echo "${bgred}${white}${bold}"
|
|
echo "You have to run Spikster as root. (In AWS use 'sudo -s')"
|
|
echo "${reset}"
|
|
log_message "Script must be run as root"
|
|
exit 1
|
|
fi
|
|
|
|
# Backup existing configurations
|
|
backup_configuration() {
|
|
backup_dir="/root/spikster_backup_$(date +%s)"
|
|
mkdir -p $backup_dir
|
|
|
|
config_files=(
|
|
"/etc/nginx"
|
|
"/etc/mysql"
|
|
"/etc/php"
|
|
"/etc/supervisor/conf.d"
|
|
)
|
|
|
|
for file in "${config_files[@]}"; do
|
|
if [ -d $file ]; then
|
|
cp -r $file $backup_dir
|
|
fi
|
|
done
|
|
|
|
log_message "Configuration files backed up to $backup_dir"
|
|
echo "Backup completed and stored to $backup_dir"
|
|
}
|
|
|
|
get_local_ip() {
|
|
local_ip=$(hostname -I | awk '{print $1}')
|
|
echo $local_ip
|
|
}
|
|
|
|
# Perform backup
|
|
backup_configuration
|
|
|
|
# Basic setup
|
|
clear
|
|
log_message "Basic setup..."
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Base setup..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
apt-get update || handle_error "apt-get update"
|
|
apt-get -y install software-properties-common curl wget nano vim sed zip unzip openssl expect \
|
|
dirmngr apt-transport-https lsb-release ca-certificates dnsutils dos2unix zsh htop ffmpeg || handle_error "installing basic packages"
|
|
|
|
# GET IP
|
|
clear
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Getting IP..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
if $USE_LOCAL_IP; then
|
|
IP=$(get_local_ip)
|
|
else
|
|
IP=$(curl -s https://checkip.amazonaws.com)
|
|
fi
|
|
log_message "Server IP obtained: $IP"
|
|
|
|
# MOTD WELCOME MESSAGE
|
|
clear
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Motd settings..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
WELCOME=/etc/motd
|
|
touch $WELCOME
|
|
cat >"$WELCOME" <<EOF
|
|
███████╗██████╗ ██╗██╗ ██╗███████╗████████╗███████╗██████╗
|
|
██╔════╝██╔══██╗██║██║ ██╔╝██╔════╝╚══██╔══╝██╔════╝██╔══██╗
|
|
███████╗██████╔╝██║█████╔╝ ███████╗ ██║ █████╗ ██████╔╝
|
|
╚════██║██╔═══╝ ██║██╔═██╗ ╚════██║ ██║ ██╔══╝ ██╔══██╗
|
|
███████║██║ ██║██║ ██╗███████║ ██║ ███████╗██║ ██║
|
|
╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝
|
|
|
|
With great power comes great responsibility...
|
|
EOF
|
|
log_message "MOTD message set"
|
|
|
|
# SWAP FILE CREATION
|
|
clear
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Memory SWAP..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
# Check if swap is already enabled
|
|
if swapon --show | grep -q "swapfile"; then
|
|
echo "${bgyellow}${black}${bold}Swapfile already exists.${reset}"
|
|
log_message "Swapfile already exists. Skipping creation."
|
|
else
|
|
fallocate -l 1G /swapfile || handle_error "creating swap file"
|
|
chmod 600 /swapfile || handle_error "setting swap file permissions"
|
|
mkswap /swapfile || handle_error "setting up swap space"
|
|
swapon /swapfile || handle_error "enabling swap"
|
|
echo "/swapfile none swap sw 0 0" >>/etc/fstab
|
|
log_message "1GB swapfile created and enabled"
|
|
fi
|
|
|
|
# ALIAS
|
|
clear
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Custom CLI configuration..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
shopt -s expand_aliases
|
|
alias ll='ls -alF'
|
|
log_message "CLI aliases set"
|
|
|
|
# Spikster DIRS
|
|
clear
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Spikster directories..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
mkdir /etc/spikster/ && chmod o-r /etc/spikster
|
|
mkdir /var/spikster/ && chmod o-r /var/spikster
|
|
log_message "Spikster directories created"
|
|
|
|
# USER
|
|
clear
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Spikster root user..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
# Check if user already exists
|
|
if id "spikster" &>/dev/null; then
|
|
echo "${bgyellow}${black}${bold}User 'spikster' already exists. Deleting user...${reset}"
|
|
userdel -r spikster || handle_error "deleting existing spikster user"
|
|
log_message "'spikster' user already existed and was deleted"
|
|
fi
|
|
|
|
pam-auth-update --package || handle_error "updating PAM authentication"
|
|
useradd -m -s /bin/bash spikster || handle_error "creating spikster user"
|
|
echo "spikster:$PASS" | chpasswd || handle_error "setting spikster user password"
|
|
usermod -aG sudo spikster || handle_error "modifying spikster user groups"
|
|
log_message "Spikster user account created"
|
|
|
|
if [ "$phpfpm" = "yes" ]; then
|
|
clear
|
|
log_message "PHP-FPM setup..."
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "PHP setup..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
add-apt-repository -y ppa:ondrej/php || handle_error "adding PPA for PHP"
|
|
apt-get update || handle_error "apt-get update after adding PPA"
|
|
apt-get -y install php8.3-fpm php8.3-common php8.3-curl php8.3-bcmath \
|
|
php8.3-mbstring php8.3-mysql php8.3-sqlite3 php8.3-pgsql php8.3-redis \
|
|
php8.3-memcached php8.3-zip php8.3-xml php8.3-soap php8.3-gd \
|
|
php8.3-imagick php8.3-imap php8.3-cli || handle_error "installing PHP packages"
|
|
|
|
if ! command -v php >/dev/null 2>&1; then
|
|
echo "${bgred}${white}${bold}PHP installation failed${reset}"
|
|
log_message "PHP installation failed"
|
|
exit 1
|
|
else
|
|
log_message "PHP installed successfully"
|
|
fi
|
|
|
|
PHPINI=/etc/php/8.3/fpm/conf.d/spikster.ini
|
|
touch $PHPINI
|
|
cat >"$PHPINI" <<EOF
|
|
memory_limit = 256M
|
|
upload_max_filesize = 256M
|
|
post_max_size = 256M
|
|
max_execution_time = 180
|
|
max_input_time = 180
|
|
EOF
|
|
service php8.3-fpm restart || handle_error "restarting PHP-FPM"
|
|
log_message "PHP-FPM installed"
|
|
|
|
update-alternatives --set php /usr/bin/php8.3 || handle_error "setting PHP CLI version"
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "PHP CLI configuration..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
log_message "PHP CLI configured"
|
|
fi
|
|
|
|
# Install Composer
|
|
if [ "$phpfpm" = "yes" ]; then
|
|
clear
|
|
log_message "Composer setup..."
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Composer setup..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
|
|
EXPECTED_SIGNATURE=$(wget -q -O - https://composer.github.io/installer.sig)
|
|
ACTUAL_SIGNATURE=$(php -r "echo hash_file('SHA384', 'composer-setup.php');")
|
|
if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]; then
|
|
echo >&2 'ERROR: Invalid installer signature'
|
|
rm -f composer-setup.php
|
|
exit 1
|
|
fi
|
|
php composer-setup.php --quiet --install-dir=/usr/local/bin --filename=composer
|
|
RESULT=$?
|
|
rm -f composer-setup.php
|
|
if [ $RESULT -ne 0 ]; then
|
|
log_message "Composer installation failed"
|
|
exit $RESULT
|
|
fi
|
|
composer --version
|
|
log_message "Composer installed"
|
|
fi
|
|
|
|
# GIT
|
|
clear
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "GIT setup..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
apt-get -y install git
|
|
ssh-keygen -t rsa -C "git@github.com" -f /etc/spikster/github -q -P ""
|
|
log_message "GIT installed"
|
|
|
|
# SUPERVISOR
|
|
clear
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Supervisor setup..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
apt-get -y install supervisor
|
|
service supervisor restart
|
|
log_message "Supervisor installed"
|
|
|
|
# Install Nginx
|
|
if [ "$nginx" = "yes" ]; then
|
|
start_nginx() {
|
|
log_message "Checking Nginx configuration..."
|
|
nginx -t || handle_error "Nginx configuration check"
|
|
log_message "Nginx configuration is valid."
|
|
|
|
log_message "Starting Nginx service..."
|
|
systemctl start nginx.service || handle_error "starting Nginx"
|
|
systemctl enable nginx.service || handle_error "enabling Nginx"
|
|
log_message "Nginx started and enabled to start on boot."
|
|
}
|
|
|
|
clear
|
|
log_message "Nginx setup..."
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Nginx setup..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
apt-get -y install nginx-core || handle_error "installing Nginx"
|
|
start_nginx
|
|
sed -i -e 's|http {|&\n limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;\n fastcgi_read_timeout 300;|g' /etc/nginx/nginx.conf || handle_error "configuring Nginx" systemctl enable nginx.service || handle_error "enabling Nginx"
|
|
log_message "Nginx installed"
|
|
|
|
# DEFAULT VHOST
|
|
clear
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Default vhost..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
NGINX=/etc/nginx/sites-available/default
|
|
if test -f "$NGINX"; then
|
|
unlink NGINX
|
|
fi
|
|
touch $NGINX
|
|
cat >"$NGINX" <<EOF
|
|
server {
|
|
listen 80 default_server;
|
|
listen [::]:80 default_server;
|
|
root /var/www/html/public;
|
|
add_header X-Frame-Options "SAMEORIGIN";
|
|
add_header X-XSS-Protection "1; mode=block";
|
|
add_header X-Content-Type-Options "nosniff";
|
|
client_body_timeout 10s;
|
|
client_header_timeout 10s;
|
|
client_max_body_size 256M;
|
|
index index.html index.php;
|
|
charset utf-8;
|
|
server_tokens off;
|
|
location / {
|
|
try_files \$uri \$uri/ /index.php?\$query_string;
|
|
}
|
|
location = /favicon.ico { access_log off; log_not_found off; }
|
|
location = /robots.txt { access_log off; log_not_found off; }
|
|
error_page 404 /index.php;
|
|
location ~ \.php$ {
|
|
include snippets/fastcgi-php.conf;
|
|
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
|
|
}
|
|
location ~ /\.(?!well-known).* {
|
|
deny all;
|
|
}
|
|
}
|
|
EOF
|
|
mkdir /etc/nginx/spikster/
|
|
systemctl restart nginx.service
|
|
|
|
fi
|
|
|
|
# Install MySQL
|
|
if [ "$mysql" = "yes" ]; then
|
|
clear
|
|
log_message "MySQL setup..."
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "MySQL setup..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
apt-get -y install mysql-server || handle_error "installing MySQL"
|
|
SECURE_MYSQL=$(expect -c "
|
|
set timeout 10
|
|
spawn mysql_secure_installation
|
|
expect \"Press y|Y for Yes, any other key for No:\"
|
|
send \"n\r\"
|
|
expect \"New password:\"
|
|
send \"$DBPASS\r\"
|
|
expect \"Re-enter new password:\"
|
|
send \"$DBPASS\r\"
|
|
expect \"Remove anonymous users? (Press y|Y for Yes, any other key for No)\"
|
|
send \"y\r\"
|
|
expect \"Disallow root login remotely? (Press y|Y for Yes, any other key for No)\"
|
|
send \"n\r\"
|
|
expect \"Remove test database and access to it? (Press y|Y for Yes, any other key for No)\"
|
|
send \"y\r\"
|
|
expect \"Reload privilege tables now? (Press y|Y for Yes, any other key for No) \"
|
|
send \"y\r\"
|
|
expect eof
|
|
")
|
|
echo "$SECURE_MYSQL"
|
|
/usr/bin/mysql -u root -p$DBPASS <<EOF
|
|
use mysql;
|
|
CREATE USER 'spikster'@'%' IDENTIFIED WITH mysql_native_password BY '$DBPASS';
|
|
GRANT ALL PRIVILEGES ON *.* TO 'spikster'@'%' WITH GRANT OPTION;
|
|
FLUSH PRIVILEGES;
|
|
EOF
|
|
log_message "MySQL installed"
|
|
fi
|
|
|
|
# REDIS
|
|
clear
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Redis setup..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
apt install -y redis-server
|
|
rpl -i -w "supervised no" "supervised systemd" /etc/redis/redis.conf
|
|
systemctl restart redis.service
|
|
|
|
# LET'S ENCRYPT
|
|
clear
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Let's Encrypt setup..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
apt-get install -y certbot
|
|
apt-get install -y python3-certbot-nginx
|
|
apt-get install -y pyenv
|
|
|
|
# NODE
|
|
clear
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Node/npm setup..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
curl -s https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add -
|
|
curl -sL https://deb.nodesource.com/setup_16.x | -E bash -
|
|
NODE=/etc/apt/sources.list.d/nodesource.list
|
|
unlink NODE
|
|
touch $NODE
|
|
cat >"$NODE" <<EOF
|
|
deb https://deb.nodesource.com/node_16.x focal main
|
|
deb-src https://deb.nodesource.com/node_16.x focal main
|
|
EOF
|
|
apt-get update
|
|
apt -y install nodejs
|
|
apt -y install npm
|
|
|
|
# Exim installation and configuration
|
|
clear
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Exim setup..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
apt-get -y install exim4 || handle_error "installing Exim"
|
|
dpkg-reconfigure exim4-config
|
|
update-exim4.conf
|
|
|
|
# Dovecot installation and configuration
|
|
clear
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Dovecot setup..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
apt-get -y install dovecot-core dovecot-imapd dovecot-pop3d || handle_error "installing Dovecot"
|
|
|
|
# Configure Dovecot
|
|
cat >/etc/dovecot/dovecot.conf <<EOF
|
|
disable_plaintext_auth = yes
|
|
mail_privileged_group = mail
|
|
mail_location = maildir:~/Maildir
|
|
|
|
protocols = imap pop3
|
|
|
|
service imap-login {
|
|
inet_listener imap {
|
|
port = 0
|
|
}
|
|
inet_listener imaps {
|
|
port = 993
|
|
ssl = yes
|
|
}
|
|
}
|
|
|
|
service pop3-login {
|
|
inet_listener pop3 {
|
|
port = 0
|
|
}
|
|
inet_listener pop3s {
|
|
port = 995
|
|
ssl = yes
|
|
}
|
|
}
|
|
|
|
ssl = required
|
|
ssl_cert = </etc/ssl/certs/ssl-cert-snakeoil.pem
|
|
ssl_key = </etc/ssl/private/ssl-cert-snakeoil.key
|
|
EOF
|
|
|
|
systemctl restart dovecot || handle_error "restarting Dovecot"
|
|
|
|
# SpamAssassin installation and configuration
|
|
clear
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "SpamAssassin setup..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
apt-get -y install spamassassin spamc || handle_error "installing SpamAssassin"
|
|
systemctl enable spamassassin
|
|
systemctl start spamassassin
|
|
|
|
# ClamAV installation and configuration
|
|
clear
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "ClamAV setup..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
apt-get -y install clamav clamav-daemon || handle_error "installing ClamAV"
|
|
systemctl stop clamav-freshclam
|
|
freshclam
|
|
systemctl start clamav-freshclam
|
|
|
|
# Roundcube installation and configuration
|
|
clear
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Roundcube setup..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
apt-get -y install roundcube roundcube-plugins roundcube-core || handle_error "installing Roundcube"
|
|
|
|
# Link Roundcube to web server
|
|
ln -s /usr/share/roundcube /var/www/html/roundcube
|
|
|
|
# Update Roundcube configuration
|
|
sed -i "s|^\(\$config\['default_host'\] = \).*|\1'localhost';|" /etc/roundcube/config.inc.php
|
|
sed -i "s|^\(\$config\['smtp_server'\] = \).*|\1'localhost';|" /etc/roundcube/config.inc.php
|
|
sed -i "s|^\(\$config\['imap_auth_type'\] = \).*|\1'PLAIN';|" /etc/roundcube/config.inc.php
|
|
sed -i "s|^\(\$config\['smtp_auth_type'\] = \).*|\1'PLAIN';|" /etc/roundcube/config.inc.php
|
|
|
|
systemctl restart nginx.service || handle_error "restarting Nginx"
|
|
|
|
# Fail2ban setup
|
|
clear
|
|
log_message "Fail2ban setup..."
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Fail2ban setup..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
apt-get -y install fail2ban || handle_error "installing Fail2Ban"
|
|
JAIL=/etc/fail2ban/jail.local
|
|
touch $JAIL
|
|
cat >"$JAIL" <<EOF
|
|
[DEFAULT]
|
|
bantime = 3600
|
|
banaction = iptables-multiport
|
|
[sshd]
|
|
enabled = true
|
|
logpath = /var/log/auth.log
|
|
EOF
|
|
systemctl restart fail2ban || handle_error "restarting Fail2Ban"
|
|
log_message "Fail2ban configured"
|
|
|
|
# Firewall setup
|
|
ufw --force enable || handle_error "enabling UFW"
|
|
ufw allow ssh || handle_error "allowing SSH through UFW"
|
|
ufw allow http || handle_error "allowing HTTP through UFW"
|
|
ufw allow https || handle_error "allowing HTTPS through UFW"
|
|
if [ "$nginx" = "yes" ]; then
|
|
ufw allow "Nginx Full" || handle_error "allowing Nginx through UFW"
|
|
fi
|
|
log_message "Firewall configured"
|
|
|
|
# Panel Installation
|
|
if [ "$nginx" = "yes" ]; then
|
|
clear
|
|
log_message "Panel installation..."
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Panel installation..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
# Create MySQL Database if MySQL is set to install
|
|
if [ "$mysql" = "yes" ]; then
|
|
/usr/bin/mysql -u root -p$DBPASS <<EOF
|
|
CREATE DATABASE IF NOT EXISTS spikster;
|
|
EOF
|
|
log_message "MySQL database 'spikster' created"
|
|
fi
|
|
|
|
clear
|
|
rm -rf /var/www/html
|
|
|
|
# Clone the repository and log errors if any
|
|
cd /var/www && git clone https://github.com/yolanmees/Spikster.git html || {
|
|
log_message "Failed to clone the repository"
|
|
exit 1
|
|
}
|
|
|
|
cd /var/www/html && git checkout $BRANCH || {
|
|
log_message "Failed to checkout branch $BRANCH"
|
|
exit 1
|
|
}
|
|
|
|
cd /var/www/html && composer update --no-interaction || {
|
|
log_message "Composer update failed"
|
|
exit 1
|
|
}
|
|
|
|
if [ -f .env ]; then
|
|
rm .env
|
|
fi
|
|
cp .env.example .env
|
|
php artisan key:generate || handle_error "artisan key:generate"
|
|
|
|
# Replace database and application configurations using sed
|
|
sed -i "s/DB_USERNAME=dbuser/DB_USERNAME=spikster/g" /var/www/html/.env
|
|
sed -i "s/DB_PASSWORD=dbpass/DB_PASSWORD=$DBPASS/g" /var/www/html/.env
|
|
sed -i "s/DB_DATABASE=dbname/DB_DATABASE=spikster/g" /var/www/html/.env
|
|
sed -i "s|APP_URL=http://localhost|APP_URL=http://$IP|g" /var/www/html/.env
|
|
sed -i "s/APP_ENV=local/APP_ENV=production/g" /var/www/html/.env
|
|
|
|
# Replace additional placeholders in the seeder file
|
|
sed -i "s|CIPISERVERID|$SERVERID|g" /var/www/html/database/seeders/DatabaseSeeder.php
|
|
sed -i "s|CIPIIP|$IP|g" /var/www/html/database/seeders/DatabaseSeeder.php
|
|
sed -i "s|CIPIPASS|$PASS|g" /var/www/html/database/seeders/DatabaseSeeder.php
|
|
sed -i "s|CIPIDB|$DBPASS|g" /var/www/html/database/seeders/DatabaseSeeder.php
|
|
|
|
chmod -R o+w /var/www/html/storage
|
|
chmod -R 777 /var/www/html/storage
|
|
chmod -R o+w /var/www/html/bootstrap/cache
|
|
chmod -R 777 /var/www/html/bootstrap/cache
|
|
|
|
# Run composer update and handle errors
|
|
cd /var/www/html && composer update --no-interaction || {
|
|
log_message "Composer update failed"
|
|
exit 1
|
|
}
|
|
|
|
php artisan key:generate || handle_error "artisan key:generate"
|
|
php artisan cache:clear || handle_error "artisan cache:clear"
|
|
php artisan storage:link || handle_error "artisan storage:link"
|
|
php artisan view:cache || handle_error "artisan view:cache"
|
|
php artisan migrate --seed --force || handle_error "artisan migrate --seed --force"
|
|
php artisan config:cache || handle_error "artisan config:cache"
|
|
chmod -R o+w /var/www/html/storage
|
|
chmod -R 775 /var/www/html/storage
|
|
chmod -R o+w /var/www/html/bootstrap/cache
|
|
chmod -R 775 /var/www/html/bootstrap/cache
|
|
chown -R www-data:spikster /var/www/html
|
|
|
|
log_message "Panel installed"
|
|
fi
|
|
|
|
# Last Steps
|
|
clear
|
|
log_message "Last steps..."
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Last steps..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
chown www-data:spikster -R /var/www/html
|
|
chmod -R 750 /var/www/html
|
|
echo 'DefaultStartLimitIntervalSec=1s' >>/usr/lib/systemd/system/user@.service
|
|
echo 'DefaultStartLimitBurst=50' >>/usr/lib/systemd/system/user@.service
|
|
echo 'StartLimitBurst=0' >>/usr/lib/systemd/system/user@.service
|
|
systemctl daemon-reload || handle_error "daemon-reload"
|
|
|
|
# Set up the cron jobs
|
|
TASK=/etc/cron.d/spikster.crontab
|
|
touch $TASK
|
|
cat >"$TASK" <<EOF
|
|
10 4 * * 7 certbot renew --nginx --non-interactive --post-hook "systemctl restart nginx.service"
|
|
20 4 * * 7 apt-get -y update
|
|
40 4 * * 7 DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical apt-get -q -y -o "Dpkg::Options::=--force-confdef" -o "Dpkg::Options::=--force-confold" dist-upgrade
|
|
20 5 * * 7 apt-get clean && apt-get autoclean
|
|
50 5 * * * echo 3 > /proc/sys/vm/drop_caches && swapoff -a && swapon -a
|
|
* * * * * cd /var/www/html && php artisan schedule:run >> /dev/null 2>&1
|
|
5 2 * * * cd /var/www/html/utility/spikster-update && sh run.sh >> /dev/null 2>&1
|
|
EOF
|
|
crontab $TASK || handle_error "setting up crontab"
|
|
systemctl restart nginx.service || handle_error "restarting nginx"
|
|
log_message "Cron jobs and Nginx restart configured"
|
|
|
|
# Strengthen SSH configuration
|
|
rpl -i -w "#PasswordAuthentication" "PasswordAuthentication" /etc/ssh/sshd_config
|
|
rpl -i -w "# PasswordAuthentication" "PasswordAuthentication" /etc/ssh/sshd_config
|
|
rpl -i -w "PasswordAuthentication no" "PasswordAuthentication yes" /etc/ssh/sshd_config
|
|
rpl -i -w "PermitRootLogin yes" "PermitRootLogin no" /etc/ssh/sshd_config
|
|
service sshd restart || handle_error "restarting SSH service"
|
|
log_message "SSH configuration strengthened"
|
|
|
|
# Supervisor setup for worker processes
|
|
clear
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Supervisor setup..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
# Install Supervisor
|
|
apt-get install -y supervisor || handle_error "installing Supervisor"
|
|
service supervisor start || handle_error "starting Supervisor"
|
|
|
|
# Create the directory if it doesn't exist
|
|
mkdir -p /etc/supervisor/conf.d
|
|
|
|
TASK=/etc/supervisor/conf.d/spikster-worker.conf
|
|
touch $TASK
|
|
cat >"$TASK" <<EOF
|
|
[program:spikster-worker]
|
|
process_name=%(program_name)s_%(process_num)02d
|
|
command=php /var/www/html/artisan queue:work --sleep=3 --tries=3 --max-time=3600
|
|
autostart=true
|
|
autorestart=true
|
|
stopasgroup=true
|
|
killasgroup=true
|
|
user=spikster
|
|
numprocs=8
|
|
redirect_stderr=true
|
|
stdout_logfile=/var/www/worker.log
|
|
stopwaitsecs=3600
|
|
EOF
|
|
|
|
# Ensure supervisorctl exists in the path
|
|
if ! command -v supervisorctl &>/dev/null; then
|
|
echo "${bgred}${white}${bold}supervisorctl is missing. Exiting.${reset}"
|
|
log_message "supervisorctl is missing. Exiting."
|
|
exit 1
|
|
fi
|
|
|
|
supervisorctl reread || handle_error "supervisor reread"
|
|
supervisorctl update || handle_error "supervisor update"
|
|
supervisorctl start all || handle_error "supervisor start all"
|
|
service supervisor restart || handle_error "restarting supervisor"
|
|
log_message "Supervisor configured"
|
|
|
|
# Additional installations
|
|
apt install -y bind9 bind9utils bind9-doc || handle_error "installing bind9"
|
|
apt install -y python3-pip || handle_error "installing Python3 pip"
|
|
|
|
pip install glances bottle fastapi uvicorn || handle_error "installing Python packages"
|
|
log_message "Additional packages installed: bind9, glances, bottle, fastapi"
|
|
|
|
# Complete
|
|
clear
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Spikster installation has been completed..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
# Send notification email upon successful completion
|
|
email_notification() {
|
|
local subject="$1"
|
|
local body="$2"
|
|
mail -s "$subject" $ADMIN_EMAIL <<EOF
|
|
$body
|
|
|
|
-- Spikster Team
|
|
EOF
|
|
}
|
|
email_notification "Spikster Installation Completed" "The installation of Spikster on host $(hostname) was successful. Server Details:\n- SSH user: spikster\n- SSH pass: $PASS\n- MySQL user: spikster\n- MySQL pass: $DBPASS\n\nYou can manage your server by visiting: http://$IP and clicking on the 'dashboard' button.\nDefault credentials are: administrator@localhost / password"
|
|
log_message "Installation completion notification sent"
|
|
|
|
log_message "Spikster installation completed"
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Spikster installation has been completed..."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
# Start glances in the background and ensure it keeps running after the script ends
|
|
nohup glances -w --disable-webui >/var/log/glances.log 2>&1 &
|
|
|
|
echo "Glances has been started in the background."
|
|
|
|
# Confirm script completion
|
|
log_message "Script completed successfully."
|
|
echo "${bggreen}${black}${bold}"
|
|
echo "Script completed successfully."
|
|
echo "${reset}"
|
|
sleep 1s
|
|
|
|
echo "***********************************************************"
|
|
echo " SETUP COMPLETE"
|
|
echo "***********************************************************"
|
|
echo ""
|
|
echo " SSH root user: spikster"
|
|
echo " SSH root pass: $PASS"
|
|
echo " MySQL root user: spikster"
|
|
echo " MySQL root pass: $DBPASS"
|
|
echo ""
|
|
echo " To manage your server visit: http://$IP"
|
|
echo " and click on 'dashboard' button."
|
|
echo " Default credentials are: administrator@localhost / password"
|
|
echo ""
|
|
echo "***********************************************************"
|
|
echo " DO NOT LOSE AND KEEP SAFE THIS DATA"
|
|
echo "***********************************************************"
|
|
|
|
# Exit script
|
|
exit 0
|