Unixery & daemon worship 🔥


It's a Unix system! I know this!

Homserver Schnellanleitung

Ich schreibe mir hier nur ein paar Notizen für die Installation eines Homeservers mit FreeBSD auf. Ohne Anspruch auf Vollständigkeit. Als Hardware kann z.B. ein Fujitsu TX1320 M3 dienen: https://watchmysys.com/blog/2023/03/fujitsu-tx1320-m3/

Inhalt:

  • Teil 1: Installation und grundlegende Konfiguration von SSH, E-Mail, Hardware, ZFS, …
  • Teil 2: Fileserver
  • Teil 3: VMs und Jails

Installation

Zunächst einmal muss FreeBSD vom USB-Stick oder remote per KVM installiert werden.

SSH

Um SSH rudimentär abzusichern, wird die Datei /etc/ssh/sshd_config_custom erstellt, um ein paar SSH-Einstellungen zu ändern:

PermitRootLogin prohibit-password
PubkeyAuthentication yes
KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org
PasswordAuthentication no
KbdInteractiveAuthentication no
UseBlacklist yes

Include /etc/ssh/sshd_config

Und folgenden Befehl ausführen, um die Custom-Config zu nutzen:

sysrc sshd_flags="-f /etc/ssh/sshd_config_custom"

E-Mailversand

Damit der Server Mails versenden kann, muss ein Smarthost (Relay) konfiguriert werden. Für den E-Mailversand empfehle ich den Dragonfly Mail Agent. Er ist bei FreeBSD im Basissystem. In der Datei /etc/dma/dma.conf zum Beispiel eintragen:

# Your smarthost (also called relayhost).
SMARTHOST mail.example.com
PORT 587

# SMTP authentication
AUTHPATH /etc/dma/auth.conf

# Uncomment if yout want TLS/SSL support and STARTTLS support
SECURETRANSFER
STARTTLS

# Masquerade envelope from addresses with this address/hostname.
MASQUERADE no-reply@example.com

Außerdem die Zugangsdaten in /etc/dma/auth.conf in folgender Form ablegen:

no-reply@example.com|mail.example.com:password

Und mit chmod 640 /etc/dma/auth.conf passende Zugriffsberechtigungen setzen.

Zuletzt in /etc/mail/mailer.conf (bei FreeBSD 14.2 schon voreingestellt):

# mailer.conf for use with dma(8)

sendmail    /usr/libexec/dma
mailq       /usr/libexec/dma
newaliases  /usr/libexec/dma

Auch nicht vergessen, in /etc/aliases die gewünschten Mail-Aliases zu setzen!

Danach kann der Mailversand getestet werden:

echo "Here I am!" | mail -s "Test from $(hostname)" root

Periodic

Damit man nicht täglich mit periodic E-Mails belästigt wird, kann man den Versand bei erfolgreicher Ausführung der Skripte einfach abstellen:

# /etc/periodic.conf overrides the defaults in /etc/defaults/periodic.conf
# This file can be overriden by /etc/periodic.conf.local

# *_show_success, *_show_info & *_show_badconfig are disabled to get less annoying mails.
# per recomendation of periodic(8) and "Absolute FreeBSD, 3rd Edition" p. 327-328
# and "Essential system administration, 3rd Edition" p. 98
# *_show_badconfig="NO" will suppress messages for tools which are not installed on this system
# (e.g. ZFS on a system without ZFS).

daily_show_success="NO"
daily_show_info="NO"
daily_show_badconfig="NO"

weekly_show_success="NO"
weekly_show_info="NO"
weekly_show_badconfig="NO"

monthly_show_success="NO"
monthly_show_info="NO"
monthly_show_badconfig="NO"

# Include security jobs with daily email. No need to send second email.
daily_status_security_inline="YES"
security_show_success="NO"

# Don't need to know about denied packets every day
daily_status_security_ipfdenied_enable="NO"

#
# Put other options after this line
#

Hardware

CPU checken

Der verwendete CPU kann mit folgendem Befehl angezeigt werden:

sysctl hw.model hw.machine hw.ncpu

IPMI

Um IPMI zu nutzen, muss das Kernelmodul geladen und die Tools installiert werden:

kldload ipmi
sysrc kld_list+=ipmi
pkg install ipmitool

Dann können z.B. die Sensoren über IPMI abgefragt werden:

ipmitool sensor | cut -f1-4 -d '|'

Stromverbrauch senken

ASPM im BIOS aktivieren und prüfen, ob es von den PCIe-Geräten genutzt wird:

pciconf -lcv | grep ASPM

In die rc.conf eintragen:

performance_cx_lowest="Cmax"
economy_cx_lowest="Cmax"

Und prüfen, welche C-States tatsächlich genutzt werden:

sysctl dev.cpu | grep cx

USV

Auch für den Homeserver kann man sich eine kleine USV gönnen, z.B. eine günstige Eaton Ellipse ECO. Die verbrät selbst nicht sonderlich viel Strom, lässt sich per USB anschließen und erfüllt ihren Job.

pkg install nut
rm /usr/local/etc/nut/ups.conf
printf "# Set maxretry to 3 by default, this should mitigate race with slow devices:\nmaxretry = 3\n\n" > /usr/local/etc/nut/ups.conf
nut-scanner -U >> /usr/local/etc/nut/ups.conf

Dann die /usr/local/etc/nut/ups.conf kontrollieren, bzw. editieren. Ich ändere z.B. den Namen der USV schlicht in “ups”.

Es stellt sich die Frage: Soll nur dieser Server heruntergefahren werden (MODE=standalone) oder sollen sich auch andere Server verbinden können, um bei Stromausfall sicher herunterzufahren (MODE=netserver). Das muss dann in /usr/local/etc/nut/nut.conf eingetragen werden:

rm /usr/local/etc/nut/nut.conf
printf "MODE=netserver\n" > /usr/local/etc/nut/nut.conf
rm /usr/local/etc/nut/upsd.conf
printf "LISTEN 127.0.0.1 3493\nLISTEN 10.0.0.10 3493" > /usr/local/etc/nut/upsd.conf
chmod 640 /usr/local/etc/nut/upsd.conf

Jetzt die Monitoring-User mit Passwörtern festlegen:

rm /usr/local/etc/nut/upsd.users
cat << EOF > /usr/local/etc/nut/upsd.users
[admin]
	password = mypass
	actions = SET
	instcmds = ALL

[monuser]
	password  = pass
	upsmon primary

[monclients]
	password  = pass
	upsmon secondary
EOF
chown nut:nut /usr/local/etc/nut/upsd.users
chmod 640 /usr/local/etc/nut/upsd.users

Und schließlich noch das Monitoring einrichten:

sed -i '' '/^#/d; /^$/d' /usr/local/etc/nut/upsmon.conf
printf "MONITOR ups@localhost 1 monuser pass primary\n" >> /usr/local/etc/nut/upsmon.conf

Auf das USV-USB-Gerät müssen die richtigen Berechtigungen gesetzt werden (Schreibzugriff für nut User). Das nut Paket bringt entsprechende Einstellungen für devfs mit, deshalb am besten neustarten:

sysrc nut_enable="YES"
reboot

Nach dem Reboot die Berechtigungen prüfen und die USV abfragen:

ls -l /dev/usb/
upsc ups

Standardtools

Ein paar Standardtools für den täglichen Gebrauch installieren:

pkg install nano micro tmux fish curl git bat zoxide eza

Fish

Fish als Standardshell setzen, ohne Fehlermeldungen in rc-Skripten zu erhalten:

printf "\n# switch to fish in interactive shell\ntest -t 0 && which -s fish && exec fish\n" >> $HOME/.shrc

Fish starten: exec fish. Den aktuellen Pfad mit drei statt nur einem Zeichen anzeigen: set -U fish_prompt_pwd_dir_length 3. Und einen Alias für ll setzen: alias --save ll "eza --long --group --git".

Zoxide

Zoxide in Fish initialisieren:

echo "\
if status is-interactive
    # Commands to run in interactive sessions can go here
    if which -s zoxide
        zoxide init fish | source
    end
end" > $HOME/.config/fish/conf.d/zoxide.fish

ZFS, Festplatten und Co.

Festplatten

Festplatten sollten mit den smartmontools, bzw. smartd überwacht werden:

pkg install smartmontools

Eine rudimentäre /usr/local/etc/smartd.conf erstellen:

# Ignore temperature and power-on hours reports in syslog.
# Send mail on SMART failures or when Temperature is > 50 Celsius.
# Monitor all attributes, enable automatic Attribute autosave, and
# start a short self-test every day between 2-3am, and a long self test
# Saturdays between 3-4am.
DEVICESCAN -a -I 194 -I 231 -I 9 -W 0,0,60 -S on -s (S/../.././02|L/../../6/03) -m root

Und den Service aktivieren:

service smartd enable
service smartd start

ZFS Fehlersuche, Behandlung und Benachrichtigung

Den zfsd aktivieren, der einige ZFS-Fehler automatisch behandeln kann, vor allem, wenn man ein Hot-Spare einsetzt:

sysrc zfsd_enable="YES"

Automatisches Scrubbing der Pools, das alle 35 Tage durchgeführt wird, aktiviert man mit:

sysrc -f /etc/periodic.conf daily_scrub_zfs_enable="YES"

Ein täglicheses Trimmen bei ZFS auf SSDs aktiviert man mit:

sysrc -f /etc/periodic.conf daily_trim_zfs_enable="YES"

Und eine tägliche Statusmail über den Zustand der Pools:

sysrc -f /etc/periodic.conf daily_status_zfs_enable="YES"

ZFS Tuning

Ein paar Infos über ZFS-Tuning finden sich in diesem Tuning-Guide:

ashift      12      4KiB block size
atime       off     Do not update atime on file read
recordsize  64KiB   Smaller record sizes for databases (match the database block size)
recordsize  128Kib  Standard usage (mixture of file sizes)
recordsize  1Mb     Recommended for large files
compression lz4     Set compression to use the lz4 algorithm

Pool erstellen

Einen Pool auf sechs SATA SSDs erstellen. Das dazugehörige Dataset soll nicht gemountet werden. Name des Pools ist hellraiser:

zpool create -o ashift=12 -O canmount=off -m none hellraiser raidz2 ada0 ada1 ada2 ada3 ada4 ada5

Verschlüsseltes Dataset erstellen

Prinzipiell sollten alle Daten verschlüsselt werden, dann muss man sich bei Verkauf der Festplatten keine Gedanken machen. Dazu in der Keydatei das Passwort speichern und ein verschlüsseltes Dataset erstellen:

mkdir /root/keys
chmod 700 /root/keys
echo "mypassword" > /root/keys/hellraiser_encrypted.key
chmod 600 /root/keys/hellraiser_encrypted.key
zfs create -o encryption=aes-256-gcm -o keyformat=passphrase -o keylocation=file:///root/keys/hellraiser_encrypted.key -o mountpoint=none -o canmount=off hellraiser/encrypted

Alle anderen Datasets können dann darunter erstellt werden und sind automatisch verschlüsselt.

Beim Systemstart sollen die Keys automatisch geladen werden:

sysrc zfskeys_enable="YES"