#!/bin/bash # Derek's Debian initialization script, only support Debian 11-12 # curl -LO https://repo.sxl.net/nix/debinit12.sh ; chmod +x debinit12.sh ## log everything to debinit.log # exec &> >(tee -a "debinit.log") ### my functions die() { printf '\n%s\nScript Aborted!\n' "ERROR: $1" >&2 ; exit 1; } ### die ^echo message and then die require() { for n in "$@" ; do [[ $(command -v "$n" 2>&1) ]] || die "required command $n not found"; done; } help() { echo "syntax: debinit.sh "; } config_ssh() { echo "## allow root ssh" tasksel install ssh-server apt install openssh-server openssh-client echo 'PermitRootLogin yes' > /etc/ssh/sshd_config.d/PermitRootLogin_yes echo 'HashKnownHosts no' > /etc/ssh/ssh_config.d/HashKnownHosts_no systemctl restart sshd } config_apt() { echo "## update debian source.list" apt-get -yq install lsb-release url="http://deb.debian.org/debian" out="/etc/apt/sources.list" ver="$(lsb_release -sc)" repo="main contrib non-free non-free-firmware" mv -bf "$out" "${out}.orig" touch "$out" { echo "deb ${url} ${ver} ${repo}" echo "deb ${url}-security ${ver}-security ${repo}" echo "deb ${url} ${ver}-updates ${repo}" echo "#deb ${url} ${ver}-backports ${repo}" echo "#deb-src ${url} ${ver} ${repo}" echo "#deb-src ${url}-security ${ver}-security ${repo}" echo "#deb-src ${url} ${ver}-updates ${repo}" echo "#deb-src ${url} ${ver}-backports ${repo}" } >> "$out" cat /etc/apt/sources.list apt-get -yq update apt-get -yq dist-upgrade } config_locale() { echo "## set locale" apt-get -yq install locales sed -i '/^en_US/d' /etc/locale.gen # delete previous entries echo 'en_US ISO-8859-1' >> /etc/locale.gen echo 'en_US.UTF_8 UTF-8' >> /etc/locale.gen locale-gen update-locale LANG=en_US.UTF-8 update-locale LANGUAGE=en_US:en update-locale LC_CTYPE="en_US.UTF-8" update-locale LC_NUMERIC="en_US.UTF-8" update-locale LC_TIME="en_US.UTF-8" update-locale LC_COLLATE="en_US.UTF-8" update-locale LC_MONETARY="en_US.UTF-8" update-locale LC_MESSAGES="en_US.UTF-8" update-locale LC_PAPER="en_US.UTF-8" update-locale LC_NAME="en_US.UTF-8" update-locale LC_ADDRESS="en_US.UTF-8" update-locale LC_TELEPHONE="en_US.UTF-8" update-locale LC_MEASUREMENT="en_US.UTF-8" update-locale LC_IDENTIFICATION="en_US.UTF-8" update-locale LC_ALL } inst_pkg() { echo "## install essential packages" apt-get -yq update apt-get -yq dist-upgrade apt-get install -yq openssh-server sudo wget curl aria2 man gnupg gnupg2 apt-get install -yq vim-nox htop iotop dialog net-tools tmux fail2ban ufw apt-get install -yq lsb-release dnsutils apt-get -yq autoclean apt-get -yq autoremove # fix fail2ban bug in debian12 echo -e "[sshd]\nbackend=systemd\nenabled=true" | sudo tee /etc/fail2ban/jail.local systemctl restart fail2ban } config_mail() { # put hostname in postfix main.cf DEBIAN_FRONTEND=noninteractive apt-get install -yq postfix mailutils sed -i '/^myhostname/d' /etc/postfix/main.cf # delete previous entries echo "myhostname=$(hostname -f)" > /etc/mailname systemctl restart postfix # forward root email to systems mailbox echo "systems@sxl.net" > /root/.forward echo "Testing message" | mail -s "Testing sent from server: $(hostname -f)" root } config_upgrade() { echo "## enable unattended upgrade" apt-get -y install unattended-upgrades echo 'Unattended-Upgrade::Mail "root";' > /etc/apt/apt.conf.d/50unattended-upgrades-mailtoroot systemctl start unattended-upgrades systemctl enable unattended-upgrades } disable_ipv6() { echo "## disable IPv6" echo 'net.ipv6.conf.all.disable_ipv6 = 1' >> /etc/sysctl.conf sysctl -p } make_swap() { echo "## make swapfile if necessary" makeswap=Y [[ $(swapon --show) ]] && makeswap=N ## already has swap [[ $(systemd-detect-virt -c) = "none" ]] || makeswap=N ## running in a container echo $makeswap if [[ $makeswap == Y ]]; then echo "## create swap file" ram_kb=$(grep MemTotal /proc/meminfo | awk '{print $2}') ram_b=$((ram_kb*1024/2)) # half of ram size fallocate -l $ram_b /swapfile || exit chmod 600 /swapfile || exit mkswap /swapfile || exit swapon /swapfile || exit echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab #sysctl vm.swappiness=10 #sysctl vm.vfs_cache_pressure=50 echo 'vm.swappiness=10' >> /etc/sysctl.conf echo 'vm.vfs_cache_pressure=50' >> /etc/sysctl.conf sysctl -p fi } inst_vmtools() { echo "## install various machine specific tools" case $(systemd-detect-virt) in none) echo "Running in physical machine" apt-get install -y haveged ;; vmware) echo "Running in VMWARE" apt-get install -y haveged open-vm-tools ;; kvm) echo "Running in KVM" apt-get install -y haveged qemu-guest-agent ;; oracle) echo "Running in Virtualbox, please install guest additions manually" apt-get install -y haveged ;; esac } config_pref() { echo "installing Derek's preferences and scripts" update-alternatives --set editor /usr/bin/vim.nox cd ~ || exit curl -o ~/.bashrc https://repo.sxl.net/nix/bashrc.txt curl -o ~/.vimrc https://repo.sxl.net/nix/vimrc.txt curl -o ~/backup-etc.sh https://repo.sxl.net/nix/backup-etc.sh mkdir ~/.ssh && touch ~/.ssh/authorized_keys curl -o ~/.ssh/authorized_keys https://repo.sxl.net/.h/proj/cert/id_ed25519.pub # shellcheck disable=SC1090 source ~/.bashrc chmod +x backup-etc.sh } inst_cockpit() { #apt-get install -yq cockpit-system cockpit-ws ## cockpit cd ~ || exit apt-get install cockpit mv /etc/motd /etc/motd.orig && touch /etc/motd # empty mtod out="/etc/cockpit/ws-certs.d" repo="https://repo.sxl.net/.h/proj/cert" curl -o "$out/server.key" "$repo/star.sxl.net-wan.pem.key" curl -o "$out/server.crt" "$repo/star.sxl.net-wan.pem.crt" systemctl restart cockpit echo "You may open Cockpit at https://$(hostname -f):9090" } ############################################################ ### MAIN program # exit if not running as root [[ $EUID -ne 0 ]] && echo "ERROR: This script must be run as root" && exit 1 # check requirements require lsb_release OSDIST=$(lsb_release -si) OSVER=$(lsb_release -sr) OSARCH="$(uname -m)" [[ "$OSDIST" != "Debian" ]] && die "Unsupported OS: $OSDIST" [[ "$OSVER" -lt 12 ]] && die "Unsupported version: $OSVER" [[ "$OSARCH" != "x86_64" ]] && die "Unsupported architecture: $OSVER" # validate parameters if [ "$#" -ne 1 ]; then { help; die "require 1 parameter"; }; fi fqdn="$1" #ip="$2" re="^([a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]\.)+[a-zA-Z]{2,}$" # valid fqdn if [[ "$fqdn" =~ $re ]]; then { echo "$1 is FQDN"; } else { help; die "ERROR: $1 is not FQDN"; } fi # re="^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$" # if [[ "$ip" =~ $re ]]; # then { echo "$2 is IPv4";} # else { help; die "ERROR: $2 is not valid IPv4"; } # fi hostname=${fqdn%%.*} # before first dot #domainname=${fqdn#*.} # ask for confirmation echo "\ debinit started at $(date) IMPORTANT !!! 1. Did you changed default password? 2. Are these settings correct? hostname : $(hostname) FQDN : $(hostname -f) IP address : $(hostname -I) Distro/Ver : ${OSDIST} ${OSVER} Arch : ${OSARCH}" read -r -p "Do you want to continue? [y/N] " response [[ ! "$response" =~ [Yy] ]] && exit 0 # set /etc/hostname echo "$hostname" > /etc/hostname # /etc/hosts #hostline="$ip $fqdn $hostname" #sed -i "/^127\..*debian$/c\\$hostline" /etc/hosts sed -i '/^127\..*debian$/d' /etc/hosts cat /etc/hosts # do config config_ssh config_apt config_locale inst_pkg config_mail config_upgrade config_pref #inst_cockpit if [[ ! $(systemd-detect-virt -c) == "none" ]]; then { make_swap disable_ipv6 inst_vmtools } fi