Files
bash/debian.sh
2025-10-30 23:52:17 +09:00

888 lines
25 KiB
Bash

#!/usr/bin/env bash
#########################################################
# Function :Initial Server Setup for Debian Server #
# Platform :Debian 11, 12 or 13 #
# Version :2.1 #
# Date :26-08-2025 #
# Author :Xiufeng Guo #
# Contact :i@m.ac #
# Company :Show Corporation #
# Usage :curl -sSL ba.sh/debian | bash #
#########################################################
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export PATH
set -euo pipefail
IFS=$'\n\t'
# Global variables with environment variable override support
SSH_KEYS_URL="${SSH_KEYS_URL:-https://git.m.ac/showfom/bash/raw/branch/main/authorized_keys}"
SSH_KEYS_RETRY_COUNT="${SSH_KEYS_RETRY_COUNT:-3}"
SSH_KEYS_RETRY_DELAY="${SSH_KEYS_RETRY_DELAY:-5}"
APT_MIRROR_URL="${APT_MIRROR_URL:-https://mirror-cdn.xtom.com}"
# Global codename variable (will be set by check_debian_version)
CODENAME=""
#current_dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
# Check system requirements, if it's not Debian 11, 12 or 13, exit
function check_debian_version() {
if [[ -f /etc/os-release ]]; then
source /etc/os-release
if [[ "$ID" == "debian" && ( "$VERSION_CODENAME" == "bullseye" || "$VERSION_CODENAME" == "bookworm" || "$VERSION_CODENAME" == "trixie" ) ]]; then
echo "Running on supported Debian version: $PRETTY_NAME"
# Set global codename variable
CODENAME="$VERSION_CODENAME"
else
echo "Unsupported Debian version: $PRETTY_NAME"
exit 1
fi
else
echo "/etc/os-release file not found. Cannot determine OS version."
exit 1
fi
}
check_debian_version
# Check if user is root, if not, exit
function check_root() {
if [ "$(id -u)" != "0" ]; then
printf "\E[0;31;40m"
echo "### This script must be run as root. Exiting... ###"
printf "\E[0m"
exit 1
fi
}
check_root
function change_apt_sources() {
printf "\E[0;35;40m"
echo '### Remove all apt sources files ###'
printf "\E[0m"
# If /etc/apt/sources.list exists, then backup it
if [ -f /etc/apt/sources.list ]; then
cp /etc/apt/sources.list /etc/apt/sources.list.$(date +"%Y%m%d_%H%M%S").bak
fi
# If /etc/apt/sources.list.d exists, then backup it
if [ -d /etc/apt/sources.list.d ] && [ "$(ls -A /etc/apt/sources.list.d 2>/dev/null)" ]; then
cp -r /etc/apt/sources.list.d /etc/apt/sources.list.d.$(date +"%Y%m%d_%H%M%S").bak
fi
printf "\E[0;35;40m"
echo '### Update system, install apt-transport-https and ca-certificates ###'
printf "\E[0m"
apt update
apt install apt-transport-https ca-certificates lsb-release -y
printf "\E[0;35;40m"
echo '### Replace the default sources.list with the new one ###'
printf "\E[0m"
case "$CODENAME" in
"bullseye")
cat > /etc/apt/sources.list << EOF
deb $APT_MIRROR_URL/debian $CODENAME main contrib non-free
deb $APT_MIRROR_URL/debian-security $CODENAME-security main contrib non-free
deb $APT_MIRROR_URL/debian $CODENAME-updates main contrib non-free
EOF
# Delete all sources.list.d files for bullseye
rm -rf /etc/apt/sources.list.d/*
;;
"bookworm"|"trixie")
# Clear existing sources.list
if [ -f /etc/apt/sources.list ]; then
cat /dev/null > /etc/apt/sources.list
fi
# Create new sources files
rm -rf /etc/apt/sources.list.d/*
cat > /etc/apt/sources.list.d/debian.sources << EOF
Types: deb
URIs: $APT_MIRROR_URL/debian
Suites: $CODENAME $CODENAME-updates $CODENAME-backports
Components: main contrib non-free non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.pgp
Types: deb
URIs: $APT_MIRROR_URL/debian-security
Suites: $CODENAME-security
Components: main contrib non-free non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.pgp
EOF
;;
*)
printf "\E[0;31;40m"
echo "### This script is only for Debian 11 (bullseye), 12 (bookworm) or 13 (trixie). Current: $CODENAME ###"
printf "\E[0m"
exit 1
;;
esac
printf "\E[0;35;40m"
echo '### Updating system... ###'
printf "\E[0m"
apt update
printf "\E[0;33;40m"
echo "### apt sources replaced ###"
printf "\E[0m"
}
function install_packages() {
printf "\E[0;35;40m"
echo '### Install the necessary packages ###'
printf "\E[0m"
apt install -y \
vim nano cron sudo \
net-tools dnsutils mtr-tiny traceroute \
wget curl host \
unzip rsync \
bash-completion git whois rsyslog \
fail2ban iptables haveged gnupg vnstat lrzsz jq \
unattended-upgrades apt-listchanges \
htop iftop p7zip-full zstd systemd-timesyncd \
bat python3-systemd byobu screen extrepo \
netcat-openbsd telnet rclone libpam-systemd
printf "\E[0;35;40m"
echo '### Updating system... ###'
printf "\E[0m"
apt update
apt upgrade -y
apt full-upgrade -y
apt autoclean
apt autoremove -y
printf "\E[0;33;40m"
echo "### System upgraded ###"
printf "\E[0m"
}
function change_timezone() {
printf "\E[0;35;40m"
echo '### Change timezone to UTC and environment variables to en_US.UTF-8 ###'
printf "\E[0m"
rm -rf /etc/localtime
ln -s /usr/share/zoneinfo/UTC /etc/localtime
cat > /etc/locale.conf << EOF
LANG=en_US.UTF-8
LC_TIME=en_US.UTF-8
LANGUAGE=en_US.UTF-8
EOF
cat > /etc/default/locale << EOF
LANG=en_US.UTF-8
LC_TIME=en_US.UTF-8
LANGUAGE=en_US.UTF-8
EOF
locale-gen en_US.UTF-8
update-locale LANG=en_US.UTF-8 LC_TIME=en_US.UTF-8 LANGUAGE=en_US.UTF-8
printf "\E[0;33;40m"
echo "### Timezone changed to UTC ###"
printf "\E[0m"
}
function add_ssh_keys(){
printf "\E[0;35;40m"
echo '### Add SSH keys... ###'
printf "\E[0m"
# Create .ssh directory
mkdir -p ~/.ssh
# Backup existing authorized_keys file (if exists)
if [ -f /root/.ssh/authorized_keys ]; then
cp /root/.ssh/authorized_keys "/root/.ssh/authorized_keys.$(date +%Y%m%d_%H%M%S).bak"
printf "\E[0;33;40m"
echo "### Backed up existing authorized_keys ###"
printf "\E[0m"
fi
# Download SSH keys with retry mechanism
local retry_count=0
local download_success=false
while [ $retry_count -lt $SSH_KEYS_RETRY_COUNT ]; do
printf "\E[0;35;40m"
echo "### Downloading SSH keys from $SSH_KEYS_URL (attempt $((retry_count + 1))/$SSH_KEYS_RETRY_COUNT)... ###"
printf "\E[0m"
if curl -sSL "$SSH_KEYS_URL" -o /root/.ssh/authorized_keys.tmp; then
# Verify downloaded file is not empty
if [ -s /root/.ssh/authorized_keys.tmp ]; then
# Verify file contains valid SSH key format
if grep -qE "^(ssh-rsa|ssh-ed25519|ecdsa-sha2-nistp256|ecdsa-sha2-nistp384|ecdsa-sha2-nistp521|ssh-dss)" /root/.ssh/authorized_keys.tmp; then
mv /root/.ssh/authorized_keys.tmp /root/.ssh/authorized_keys
download_success=true
break
else
printf "\E[0;31;40m"
echo "### Downloaded file doesn't contain valid SSH keys ###"
printf "\E[0m"
fi
else
printf "\E[0;31;40m"
echo "### Downloaded file is empty ###"
printf "\E[0m"
fi
else
printf "\E[0;31;40m"
echo "### Failed to download SSH keys ###"
printf "\E[0m"
fi
# Clean up temporary file
rm -f /root/.ssh/authorized_keys.tmp
retry_count=$((retry_count + 1))
if [ $retry_count -lt $SSH_KEYS_RETRY_COUNT ]; then
printf "\E[0;33;40m"
echo "### Retrying in $SSH_KEYS_RETRY_DELAY seconds... ###"
printf "\E[0m"
sleep $SSH_KEYS_RETRY_DELAY
fi
done
if [ "$download_success" = true ]; then
# Set correct permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
# Verify final authorized_keys file
if [ -f /root/.ssh/authorized_keys ] && [ -s /root/.ssh/authorized_keys ]; then
local key_count=$(grep -cE "^(ssh-rsa|ssh-ed25519|ecdsa-sha2-nistp256|ecdsa-sha2-nistp384|ecdsa-sha2-nistp521|ssh-dss)" /root/.ssh/authorized_keys || true)
printf "\E[0;32;40m"
echo "### SSH keys added successfully ($key_count keys found) ###"
printf "\E[0m"
return 0
else
printf "\E[0;31;40m"
echo "### ERROR: authorized_keys file is invalid ###"
printf "\E[0m"
return 1
fi
else
printf "\E[0;31;40m"
echo "### ERROR: Failed to download SSH keys after $SSH_KEYS_RETRY_COUNT attempts ###"
echo "### No SSH keys were added. You may need to manually add SSH keys later. ###"
printf "\E[0m"
# If backup files exist, remind user they can restore
if [ -f /root/.ssh/authorized_keys.*.bak ]; then
printf "\E[0;33;40m"
echo "### Note: Backup files exist in /root/.ssh/ ###"
printf "\E[0m"
fi
return 1
fi
}
function disable_ssh_password() {
printf "\E[0;35;40m"
echo '### Disable SSH password ###'
printf "\E[0m"
cat > /etc/ssh/sshd_config.d/disable_password.conf << EOF
PermitRootLogin prohibit-password
PasswordAuthentication no
EOF
cat > /etc/ssh/sshd_config.d/hide_debian_banner.conf << EOF
DebianBanner no
EOF
cat > /etc/ssh/sshd_config.d/enable_rsa_keys.conf << EOF
HostKeyAlgorithms +ssh-rsa
PubkeyAcceptedKeyTypes +ssh-rsa
EOF
printf "\E[0;33;40m"
echo "### SSH password disabled ###"
printf "\E[0m"
}
function custom_fail2ban() {
printf "\E[0;35;40m"
echo '### Custom Fail2ban ###'
printf "\E[0m"
cat > /etc/fail2ban/jail.d/bantime.conf << EOF
[DEFAULT]
bantime = 1h
EOF
# If you still needs iptables
# cat > /etc/fail2ban/jail.d/sshd.conf << EOF
#[sshd]
#banaction = iptables-multiport
#banaction_allports = iptables-allports
#EOF
printf "\E[0;33;40m"
echo "### Custom Fail2ban configuration added ###"
printf "\E[0m"
}
function custom_bashrc() {
printf "\E[0;35;40m"
echo '### Custom .bashrc ###'
printf "\E[0m"
cp -r /root/.bashrc /root/.bashrc.$(date +"%Y_%m_%d_%I_%M_%p").bak
cat > ~/.bashrc << EOF
if [ -z "\$PS1" ]; then
return
fi
# Custom alias
alias ls='ls --color=auto'
alias ll='ls --color=auto -alFh'
alias l='ls -A'
alias mtr='mtr --aslookup --show-ips'
PS1='\[\033[01;31m\]\u\[\033[01;33m\]@\[\033[01;36m\]\h \[\033[01;33m\]\w \[\033[01;35m\]\\$ \[\033[00m\]'
# If this is an xterm set the title to user@host:dir
case "\$TERM" in
xterm*|rxvt*)
PS1="\[\e]0;\${debian_chroot:+(\$debian_chroot)}\u@\h: \w\a\]\$PS1"
;;
*)
;;
esac
EOF
printf "\E[0;33;40m"
echo "### Custom .bashrc added ###"
printf "\E[0m"
}
function custom_vimrc() {
printf "\E[0;35;40m"
echo '### Custom .vimrc ###'
printf "\E[0m"
cat > ~/.vimrc << EOF
set nopaste
syntax on
set nu
set tabstop=4
set shiftwidth=4
set softtabstop=4
set expandtab
EOF
printf "\E[0;33;40m"
echo "### Custom .vimrc added ###"
printf "\E[0m"
}
function custom_rc() {
printf "\E[0;35;40m"
echo '### Custom .inputrc ###'
printf "\E[0m"
cat > ~/.inputrc << EOF
set enable-bracketed-paste off
EOF
printf "\E[0;33;40m"
echo "### Custom .inputrc added ###"
printf "\E[0m"
# echo '### Custom .curlrc ###'
# printf "\E[0m"
# cat > ~/.curlrc << EOF
#ipv4
#EOF
# printf "\E[0;33;40m"
# echo "### Custom .curlrc added ###"
# printf "\E[0m"
}
function custom_sysctl() {
printf "\E[0;35;40m"
echo '### Custom sysctl.conf ###'
printf "\E[0m"
# Check if /etc/sysctl.d exists
if [ ! -d /etc/sysctl.d ]; then
printf "\E[0;33;40m"
echo "### WARNING: /etc/sysctl.d does not exist ###"
echo "### Skipping sysctl configuration... ###"
printf "\E[0m"
return 0
fi
# Modern system - use /etc/sysctl.d/
cat > /etc/sysctl.d/local.conf << EOF
net.ipv4.ip_forward = 1
net.ipv4.conf.all.proxy_arp = 0
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.all.autoconf = 0
net.ipv6.conf.default.autoconf = 0
net.ipv6.conf.all.accept_ra = 0
net.ipv6.conf.default.accept_ra = 0
net.ipv6.conf.default.accept_dad = 0
net.ipv6.conf.all.accept_dad = 0
net.core.rmem_default = 1212992
net.ipv4.neigh.default.gc_interval = 3600
net.ipv4.neigh.default.gc_stale_time = 3600
net.ipv4.neigh.default.gc_thresh1 = 2048
net.ipv4.neigh.default.gc_thresh2 = 4096
net.ipv4.neigh.default.gc_thresh3 = 8192
net.ipv6.neigh.default.base_reachable_time_ms = 3600
net.core.wmem_max = 134217728
net.core.rmem_max = 134217728
net.ipv4.tcp_rmem = 10240 87380 134217728
net.ipv4.tcp_wmem = 10240 87380 134217728
net.ipv4.tcp_slow_start_after_idle = 0
fs.inotify.max_user_watches = 819200
net.ipv4.tcp_max_syn_backlog = 32768
net.core.somaxconn = 2048
net.core.netdev_max_backlog = 32768
vm.vfs_cache_pressure = 100
vm.dirty_background_bytes = 52428800
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
net.ipv6.route.max_size = 1048576
fs.file-max = 1000000
vm.swappiness = 10
vm.dirty_ratio = 60
vm.dirty_background_ratio = 2
net.ipv6.ip6frag_high_thresh = 4194304
net.ipv6.ip6frag_low_thresh = 3145728
net.ipv4.ipfrag_high_thresh = 4194304
net.ipv4.ipfrag_low_thresh = 3145728
net.ipv4.ping_group_range = 0 2147483647
EOF
# Apply sysctl settings
sysctl -p /etc/sysctl.d/local.conf
# If /etc/sysctl.conf exists, backup and replace with guide comment
if [ -f /etc/sysctl.conf ]; then
cp /etc/sysctl.conf /etc/sysctl.conf.$(date +"%Y%m%d_%H%M%S").bak
cat > /etc/sysctl.conf << EOF
#
# /etc/sysctl.conf - Configuration file for setting system variables
#
# NOTE: This file has been deprecated in favor of /etc/sysctl.d/
# Please add or modify system settings in /etc/sysctl.d/local.conf
#
# Custom configurations are now located at: /etc/sysctl.d/local.conf
#
EOF
fi
# Verify if the settings were applied successfully
local file_max=$(sysctl -n fs.file-max)
if [ "$file_max" = "1000000" ]; then
printf "\E[0;32;40m"
echo "### Custom sysctl settings added successfully (fs.file-max=$file_max) ###"
printf "\E[0m"
else
printf "\E[0;31;40m"
echo "### ERROR: Failed to apply sysctl settings (fs.file-max=$file_max, expected 1000000) ###"
printf "\E[0m"
return 1
fi
echo "### Adjust system file limits ###"
cat > /etc/security/limits.d/nofile.conf << EOF
root soft nofile 65536
root hard nofile 1048576
* soft nofile 65536
* hard nofile 1048576
EOF
mkdir -p /etc/systemd/system.conf.d
cat > /etc/systemd/system.conf.d/limits.conf << EOF
[Manager]
DefaultLimitNOFILE=65536
EOF
systemctl daemon-reexec
echo "### Adjust system file limits done ###"
}
# Helper function to add repository sources
function add_repo_source() {
local repo_name="$1"
local key_url="$2"
local key_file="$3"
local repo_url="$4"
local components="$5"
local suite="${6:-$CODENAME}"
# Download GPG key - try direct download first, then dearmor if needed
printf "\E[0;35;40m"
echo "### Downloading GPG key for $repo_name... ###"
printf "\E[0m"
# Download to temporary file first
local temp_key_file="/tmp/$(basename "$key_file").tmp.$$"
if curl -sSL "$key_url" -o "$temp_key_file"; then
# Check if file starts with ASCII armored header
if head -n 1 "$temp_key_file" | grep -q "^-----BEGIN PGP"; then
# ASCII armored format, need to dearmor
if gpg --dearmor < "$temp_key_file" > "$key_file" 2>/dev/null; then
rm "$temp_key_file"
else
printf "\E[0;31;40m"
echo "### ERROR: Failed to dearmor GPG key for $repo_name ###"
printf "\E[0m"
rm -f "$temp_key_file"
return 1
fi
else
# Binary format, use directly
mv "$temp_key_file" "$key_file"
fi
else
printf "\E[0;31;40m"
echo "### ERROR: Failed to download GPG key for $repo_name ###"
printf "\E[0m"
rm -f "$temp_key_file"
return 1
fi
# Create repository source based on Debian version
if [ "$CODENAME" = "bookworm" ] || [ "$CODENAME" = "trixie" ]; then
# Use new DEB822 format for Debian 12 and 13
cat > "/etc/apt/sources.list.d/${repo_name}.sources" << EOF
Types: deb
URIs: $repo_url
Suites: $suite
Components: $components
Signed-By: $key_file
EOF
else
# Use traditional format for Debian 11
echo "deb [arch=$(dpkg --print-architecture) signed-by=$key_file] $repo_url $suite $components" > "/etc/apt/sources.list.d/${repo_name}.list"
fi
}
function add_nginx_repo() {
printf "\E[0;35;40m"
echo '### Add n.wtf Nginx repo ###'
printf "\E[0m"
add_repo_source "n.wtf" \
"https://n.wtf/public.key" \
"/usr/share/keyrings/n.wtf.gpg" \
"https://mirror-cdn.xtom.com/sb/nginx" \
"main"
printf "\E[0;33;40m"
echo "### n.wtf Nginx repo added ###"
printf "\E[0m"
}
function add_caddy_repo() {
printf "\E[0;35;40m"
echo '### Add Caddy repo ###'
printf "\E[0m"
add_repo_source "caddy" \
"https://dl.cloudsmith.io/public/caddy/stable/gpg.key" \
"/usr/share/keyrings/caddy.gpg" \
"https://dl.cloudsmith.io/public/caddy/stable/deb/debian" \
"main" \
"any-version"
add_repo_source "xcaddy" \
"https://dl.cloudsmith.io/public/caddy/xcaddy/gpg.key" \
"/usr/share/keyrings/xcaddy.gpg" \
"https://dl.cloudsmith.io/public/caddy/xcaddy/deb/debian" \
"main" \
"any-version"
printf "\E[0;33;40m"
echo "### Caddy repo added ###"
printf "\E[0m"
}
function add_docker_repo() {
printf "\E[0;35;40m"
echo '### Add Docker CE repo ###'
printf "\E[0m"
add_repo_source "docker" \
"https://download.docker.com/linux/debian/gpg" \
"/usr/share/keyrings/docker-ce.gpg" \
"https://download.docker.com/linux/debian" \
"stable"
printf "\E[0;33;40m"
echo "### Docker CE repo added ###"
printf "\E[0m"
}
function add_php_repo() {
printf "\E[0;35;40m"
echo '### Add Sury PHP repo ###'
printf "\E[0m"
add_repo_source "php" \
"https://packages.sury.org/php/apt.gpg" \
"/usr/share/keyrings/deb.sury.org-php.gpg" \
"https://mirror-cdn.xtom.com/sury/php" \
"main"
printf "\E[0;33;40m"
echo "### Sury PHP repo added ###"
printf "\E[0m"
}
function add_mariadb_repo() {
printf "\E[0;35;40m"
echo '### Add MariaDB repo ###'
printf "\E[0m"
add_repo_source "mariadb" \
"https://supplychain.mariadb.com/MariaDB-Server-GPG-KEY" \
"/usr/share/keyrings/mariadb.gpg" \
"https://mirror-cdn.xtom.com/mariadb/repo/11.8/debian" \
"main"
printf "\E[0;33;40m"
echo "### MariaDB repo added ###"
printf "\E[0m"
}
function add_postgresql_repo() {
printf "\E[0;35;40m"
echo '### Add PostgreSQL repo ###'
printf "\E[0m"
add_repo_source "postgresql" \
"https://www.postgresql.org/media/keys/ACCC4CF8.asc" \
"/usr/share/keyrings/postgresql.gpg" \
"http://apt.postgresql.org/pub/repos/apt" \
"main" \
"${CODENAME}-pgdg"
printf "\E[0;33;40m"
echo "### PostgreSQL repo added ###"
printf "\E[0m"
}
function add_tor_repo() {
printf "\E[0;35;40m"
echo '### Add Tor repo ###'
printf "\E[0m"
add_repo_source "tor" \
"https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc" \
"/usr/share/keyrings/tor.gpg" \
"https://deb.torproject.org/torproject.org" \
"main"
printf "\E[0;33;40m"
echo "### Tor repo added ###"
printf "\E[0m"
}
function add_redis_repo() {
printf "\E[0;35;40m"
echo '### Add Redis repo ###'
printf "\E[0m"
add_repo_source "redis" \
"https://packages.redis.io/gpg" \
"/usr/share/keyrings/redis.gpg" \
"https://packages.redis.io/deb" \
"main"
printf "\E[0;33;40m"
echo "### Redis repo added ###"
printf "\E[0m"
}
function add_unattended_upgrades() {
printf "\E[0;35;40m"
echo '### Enable Unattended Upgrades ###'
printf "\E[0m"
cp -r /etc/apt/apt.conf.d/50unattended-upgrades /etc/apt/apt.conf.d/50unattended-upgrades.$(date +"%Y_%m_%d_%I_%M_%p").bak
cat > /etc/apt/apt.conf.d/50unattended-upgrades << EOF
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::Verbose "1";
APT::Periodic::AutocleanInterval "7";
Unattended-Upgrade::Mail "root";
Unattended-Upgrade::Origins-Pattern {
"origin=Debian,codename=\${distro_codename},label=Debian-Security";
"origin=Debian,codename=\${distro_codename}-security,label=Debian-Security";
};
Unattended-Upgrade::Package-Blacklist {
};
Unattended-Upgrade::Automatic-Reboot "false";
EOF
printf "\E[0;33;40m"
echo "### Unattended Upgrades enabled ###"
printf "\E[0m"
}
function add_acme_sh() {
printf "\E[0;35;40m"
echo '### Install acme.sh ###'
printf "\E[0m"
curl -sSL https://get.acme.sh | bash
/root/.acme.sh/acme.sh --upgrade --auto-upgrade
/root/.acme.sh/acme.sh --set-default-ca --server letsencrypt
printf "\E[0;33;40m"
echo "### acme.sh installation done ###"
printf "\E[0m"
}
function add_anubis() {
printf "\E[0;35;40m"
echo '### Install Anubis ###'
printf "\E[0m"
VERSION=$(curl -s https://api.github.com/repos/TecharoHQ/anubis/releases/latest | grep tag_name | cut -d '"' -f 4 | sed 's/^v//') && echo "Latest Anubis version is v${VERSION}"
wget -O /tmp/anubis.deb https://github.com/TecharoHQ/anubis/releases/download/v${VERSION}/anubis_${VERSION}_$(dpkg --print-architecture).deb
dpkg -i /tmp/anubis.deb
rm /tmp/anubis.deb
printf "\E[0;33;40m"
echo "### Anubis installation done ###"
printf "\E[0m"
}
function add_update_sh() {
printf "\E[0;35;40m"
echo '### Add update.sh ###'
printf "\E[0m"
cat > /root/update.sh << EOF
#!/usr/bin/env bash
apt update
apt upgrade -y
apt full-upgrade -y
apt autoclean
apt autoremove -y
EOF
chmod +x /root/update.sh
/root/update.sh
printf "\E[0;33;40m"
echo "### update.sh added ###"
printf "\E[0m"
}
# Check if dialog is installed, if not, install it
function check_dialog() {
if ! command -v dialog &> /dev/null; then
echo "dialog is not installed. Installing it now..."
apt update && apt install dialog -y
fi
}
check_dialog
# Dialog box begins here
cmd=(dialog --title "Debian Server Initial Setup" --separate-output --checklist "Select options:" 22 76 16)
options=(1 "Install Packages" on # any option can be set to default to "on"
2 "Change APT Sources" on
3 "Change Timezone" on
4 "Add SSH Keys" on
5 "Disable SSH Password" on
6 "Custom Fail2ban" on
7 "Custom .bashrc" on
8 "Custom .vimrc" on
9 "Custom run commands" on
10 "Custom sysctl and system file limitation" on
11 "Enable Unattended Upgrades" on
12 "Add n.wtf Nginx Repo" on
13 "Add Caddy Repo" off
14 "Add Docker CE Repo" off
15 "Add Sury PHP Repo" off
16 "Add MariaDB Repo" off
17 "Add PostgreSQL Repo" off
18 "Add Tor Project Repo" off
19 "Add Redis Repo" off
20 "Install Anubis" off
97 "Install acme.sh" off
99 "Add update.sh" on)
choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
clear
for choice in $choices
do
case $choice in
1)
install_packages
;;
2)
change_apt_sources
;;
3)
change_timezone
;;
4)
add_ssh_keys
;;
5)
disable_ssh_password
;;
6)
custom_fail2ban
;;
7)
custom_bashrc
;;
8)
custom_vimrc
;;
9)
custom_rc
;;
10)
custom_sysctl
;;
11)
add_unattended_upgrades
;;
12)
add_nginx_repo
;;
13)
add_caddy_repo
;;
14)
add_docker_repo
;;
15)
add_php_repo
;;
16)
add_mariadb_repo
;;
17)
add_postgresql_repo
;;
18)
add_tor_repo
;;
19)
add_redis_repo
;;
20)
add_anubis
;;
97)
add_acme_sh
;;
99)
add_update_sh
;;
esac
done
printf "\E[0;36;40m"
echo '### Server Initial Setup Completed. ###'
echo 'Have a nice day.'
echo 'You may need to reboot your system to take affect.'
printf "\E[0m"