www/doc
2025-07-02 06:11:29 -05:00
..
00_nginx-base.txt import the dwarven empire 2024-03-31 10:44:34 -05:00
00_xyzzy-ee.txt import the dwarven empire 2024-03-31 10:44:34 -05:00
01_xyzzy-fi.txt import the dwarven empire 2024-03-31 10:44:34 -05:00
02_git-xyzzy-ee.txt import the dwarven empire 2024-03-31 10:44:34 -05:00
03_dwarvenruins-com.txt import the dwarven empire 2024-03-31 10:44:34 -05:00
04_dwarvenmail-com.txt import the dwarven empire 2024-03-31 10:44:34 -05:00
05_dwarvenvault-com.txt import the dwarven empire 2024-03-31 10:44:34 -05:00
06_airlocksix-com.txt add a6 setup 2024-08-01 12:28:59 -05:00
07_tenno-nz.txt adding tenno 2025-02-11 12:06:06 -06:00
08_teteoke-com.txt add tetóke 2025-06-22 10:44:27 -05:00
09_troyito-com.txt add troyito 2025-07-02 06:11:29 -05:00
README.md update README gitea -> forgejo 2024-08-24 07:38:24 -05:00

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