# Server Setup Debian 12 minimal installation, ensure the SSH server and standard system tools are included. ## Base Configuration Internal hostname, replace "myhostname": ``` hostnamectl set-hostname myhostname ``` **/etc/hosts** ``` 127.0.0.1 localhost 127.0.1.1 myhostname ``` Install packages: ``` apt-get update echo "iptables-persistent iptables-persistent/autosave_v4 boolean true" | debconf-set-selections echo "iptables-persistent iptables-persistent/autosave_v6 boolean true" | debconf-set-selections echo "unattended-upgrades unattended-upgrades/enable_auto_updates boolean true" | debconf-set-selections apt-get install curl sysstat unattended-upgrades iptables-persistent \ man less vim rsync bc net-tools git git-lfs sqlite3 strace sudo \ apparmor-utils rsyslog ``` Install packages without `recommends`: ``` apt-get install --no-install-recommends smem \ nginx nginx-core libnginx-mod-stream \ certbot python3-certbot-nginx ``` Set up services: ``` systemctl disable remote-fs.target rsync.service systemctl enable sysstat unattended-upgrades netfilter-persistent ``` As needed: ``` apt-get update apt-get full-upgrade reboot ``` ## User Setup Add a login user: ``` export MYUSER="frankthetank" useradd -m -d /home/${MYUSER} -s /bin/bash -g users -G sudo ${MYUSER} passwd ${MYUSER} mkdir -p /var/xyzzy/bin chown -R ${MYUSER}: /var/xyzzy ``` If `ssh-copy-id` can't be used: ``` mkdir /home/${MYUSER}/.ssh cp /root/.ssh/authorized_keys /home/${MYUSER}/.ssh/ chmod 0700 /home/${MYUSER}/.ssh chmod 0600 /home/${MYUSER}/.ssh/authorized_keys chown -R ${MYUSER}:users /home/${MYUSER}/.ssh ``` Disable root login: ``` _SCFG="/etc/ssh/sshd_config" if $(grep -iEq '^PermitRootLogin[[:space:]]+yes' "${_SCFG}"); then sed -i.bak -e 's/^PermitRootLogin.*/PermitRootLogin no/gi' "${_SCFG}" else sed -i.bak -e 's/^#PermitRootLogin.*/PermitRootLogin no/gi' "${_SCFG}" fi ``` After confirming the change is correct: ``` systemctl restart sshd ``` Test logging in again as the user and sudo to root in another term. ## Server Configuration Get rid of mouse in `vim`: ``` echo 'set mouse=' >> ~/.vimrc ``` Get rid of bracketed paste: ``` echo 'set enable-bracketed-paste Off' >> ~/.inputrc ``` Enable `sysstat`: ``` sed -i.bak -e 's|^ENABLED=".*"|ENABLED="true"|g' /etc/default/sysstat ``` Configure `unattended-upgrades`: ``` cp 02periodic /etc/apt/apt.conf.d/ ``` Configure `iptables` and `ip6tables`: ``` cp rules.* /etc/iptables/ ``` Configure tweaks: ``` mkdir /etc/systemd/journald.conf.d mkdir /etc/systemd/system/nginx.service.d cp sysctl.d/local.conf /etc/sysctl.d/ cp systemd/journald.conf.d/local.conf \ /etc/systemd/journald.conf.d/ cp systemd/system/nginx.service.d/override.conf \ /etc/systemd/system/nginx.service.d/ systemctl daemon-reload ``` ## Fail2ban Setup SSH jail: ``` apt-get install fail2ban cp jail.local /etc/fail2ban/ systemctl enable --now fail2ban ``` Maintenance tasks: ``` cp dbpurge.sql /etc/fail2ban/ cp f2b-cleanup /etc/cron.weekly/ chown root:root /etc/cron.weekly/f2b-cleanup chmod 0755 /etc/cron.weekly/f2b-cleanup cp bin/jailstat.sh /var/xyzzy/bin/ ``` ## Nginx Setup Gitea first-time setup is easier with nginx + SSL already working. #### Basic Prep ``` cd /etc/nginx/modules-enabled rm \ 50-mod-http-geoip.conf \ 50-mod-http-image-filter.conf \ 50-mod-http-xslt-filter.conf \ 50-mod-mail.conf \ 70-mod-stream-geoip.conf cp security.conf /etc/nginx/conf.d/ ``` #### Site Prep ``` mkdir /var/xyzzy/html cp html* /var/xyzzy/html/ cp xyzzy.ee.conf.bootstrap /etc/nginx/sites-available/xyzzy.ee.conf cp xyzzy.fi.conf.bootstrap /etc/nginx/sites-available/xyzzy.fi.conf cp git.xyzzy.ee.conf.bootstrap /etc/nginx/sites-available/git.xyzzy.ee.conf cd /etc/nginx/sites-enabled rm default ln -s /etc/nginx/sites-available/xyzzy.ee.conf 00xyzzy.ee.conf ln -s /etc/nginx/sites-available/xyzzy.fi.conf 01xyzzy.fi.conf ln -s /etc/nginx/sites-available/git.xyzzy.ee.conf 02git.xyzzy.ee.conf nginx -t systemctl restart nginx certbot --nginx -d xyzzy.ee,www.xyzzy.ee \ --agree-tos -m "hostmaster@xyzzy.ee" --no-eff-email \ --deploy-hook "systemctl reload nginx" certbot --nginx -d xyzzy.fi,www.xyzzy.fi \ --agree-tos -m "hostmaster@xyzzy.fi" --no-eff-email \ --deploy-hook "systemctl reload nginx" certbot --nginx -d git.xyzzy.ee \ --agree-tos -m "hostmaster@xyzzy.ee" --no-eff-email \ --deploy-hook "systemctl reload nginx" cp xyzzy.ee.conf /etc/nginx/sites-available/xyzzy.ee.conf cp xyzzy.fi.conf /etc/nginx/sites-available/xyzzy.fi.conf cp git.xyzzy.ee.conf /etc/nginx/sites-available/git.xyzzy.ee.conf nginx -t systemctl restart nginx ``` ## Gitea Setup All content lives under `/var/xyzzy`: ``` cp bin/teaup.sh /var/xyzzy/bin/ cd /var/xyzzy/bin export TVER="1.21.8" curl -L --output-dir /var/xyzzy/bin --remote-name-all \ "https://github.com/go-gitea/gitea/releases/download/v${TVER}/gitea-${TVER}-linux-amd64" \ "https://github.com/go-gitea/gitea/releases/download/v${TVER}/gitea-${TVER}-linux-amd64.sha256" sha256sum -c "gitea-${TVER}-linux-amd64.sha256" chmod +x "gitea-${TVER}-linux-amd64" ln -s "gitea-${TVER}-linux-amd64" gitea ``` Primary `git` user: ``` adduser \ --system \ --shell /bin/bash \ --gecos 'git' \ --group \ --disabled-password \ --home /var/xyzzy/git \ git ``` Gitea prep: ``` mkdir -p /var/xyzzy/gitea/{custom,data,log} chown -R git:git /var/xyzzy/gitea/ chmod -R 750 /var/xyzzy/gitea/ mkdir -p /var/xyzzy/etc/gitea chown root:git /var/xyzzy/etc/gitea chmod 770 /var/xyzzy/etc/gitea cp gitea.service /etc/systemd/system/ systemctl daemon-reload ``` Gitea init: ``` systemctl start gitea.service ( browser -> https://git.xyzzy.ee ) systemctl stop gitea.service ``` Gitea deploy: (app.ini needs secrets set) ``` cp custom/* /var/xyzzy/gitea/custom/ cp app.ini /var/xyzzy/etc/gitea/ chmod 750 /var/xyzzy/etc/gitea chmod 640 /var/xyzzy/etc/gitea/app.ini chown root:git /var/xyzzy/etc/gitea/app.ini systemctl enable --now gitea.service ``` ## AppArmor ``` cp apparmor.d/* /etc/apparmor.d/ systemctl restart apparmor.service ``` ## Backup See `teabak.sh`; prep: (HCPING needs set in script) ``` groupadd --system bkp mkdir /var/xyzzy/backup chmod 0750 /var/xyzzy/backup chown git:bkp /var/xyzzy/backup cp teaback.sh /var/xyzzy/bin/ chmod 0755 /var/xyzzy/bin/teabak.sh cp teabak.service teabak.timer /etc/systemd/system/ systemctl daemon-reload systemctl enable --now teabak.timer ``` Allow restricted backup user to rsync the data: ``` adduser \ --shell /bin/bash \ --gecos 'reposync' \ --ingroup bkp \ --disabled-password \ --home /home/reposync \ reposync ``` The "reposync" user has a restricted `.ssh/authorized_keys` like so: ``` command="/usr/bin/rrsync -ro /var/xyzzy/backup/",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty,no-user-rc,restrict ssh-ed25519 ... ``` The `rrsync` script is part of the Debian `rsync` package