7.2 KiB
Server Setup
Debian 12 minimal installation, ensure the SSH server and standard system tools are included.
Note: text files to help with nginx deployment and/or migrating sites to new hosts/VMs (certbot et. al) are ancillary to this document.
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
Ensure SSH client alive is configured in /etc/ssh/sshd_config:
TCPKeepAlive yes
ClientAliveInterval 60
ClientAliveCountMax 3
After confirming the sshd_config changes are correct:
systemctl restart sshd.service
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
Forgejo 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
Forgejo Setup
All content lives under /var/xyzzy:
cp bin/forgejo_*.sh /var/xyzzy/bin/
cd /var/xyzzy/bin
export FVER="7.0.7"
curl -f -L --output-dir /var/xyzzy/bin --remote-name-all \
"https://codeberg.org/forgejo/forgejo/releases/download/v${FVER}/forgejo-${FVER}-linux-amd64" \
"https://codeberg.org/forgejo/forgejo/releases/download/v${FVER}/forgejo-${FVER}-linux-amd64.sha256"
sha256sum -c "forgejo-${FVER}-linux-amd64.sha256"
chmod +x "forgejo-${FVER}-linux-amd64"
ln -s "forgejo-${FVER}-linux-amd64" forgejo
Primary git user:
adduser \
--system \
--shell /bin/bash \
--gecos 'git' \
--group \
--disabled-password \
--home /var/xyzzy/git \
git
Forgejo prep:
mkdir -p /var/xyzzy/forge/{custom,data,log}
chown -R git:git /var/xyzzy/forge/
chmod -R 750 /var/xyzzy/forge/
mkdir -p /var/xyzzy/etc/forgejo
chown root:git /var/xyzzy/etc/forgejo
chmod 770 /var/xyzzy/etc/forgejo
cp forgejo.service /etc/systemd/system/
systemctl daemon-reload
Forgejo init:
systemctl start forgejo.service
( browser -> https://git.xyzzy.ee )
systemctl stop forgejo.service
Forgejo deploy: (app.ini needs secrets set)
cp custom/* /var/xyzzy/forge/custom/
cp app.ini /var/xyzzy/etc/forgejo/
cp *secret *token /var/xyzzy/etc/forgejo/
chmod 750 /var/xyzzy/etc/forgejo
chmod 640 /var/xyzzy/etc/forgejo/*
chown root:git /var/xyzzy/etc/forgejo/*
systemctl enable --now forgejo.service
AppArmor
cp apparmor.d/* /etc/apparmor.d/
systemctl restart apparmor.service
Backup
See forgejo_backup.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 forgejo_backup.sh /var/xyzzy/bin/
chmod 0755 /var/xyzzy/bin/forgejo_backup.sh
cp forgejo_backup.service forgejo_backup.timer /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now forgejo_backup.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