Einrichten

Frisch installiert kommt der Server zum Ersten mal hoch. ssh login funktioniert, sudo auch? Sehr gut.

Netzwerk

Als erstes kümmert man sich um korrektes Netzwerk. Die /etc/rc.conf wird von DHCP auf fixe Adressen umgestellt:

# Network hostname="machine" ifconfig_igb0="inet <v4 Addresse vom Server>/32" gateway_if="igb0" gateway_ip="<v4 Addresse vom Gateway>" static_routes="gateway default" route_gateway="-host $gateway_ip -interface $gateway_if" route_default="default $gateway_ip" ipv6_default_interface="igb0" ifconfig_igb0_ipv6="inet6 <v6 Addresse vom Server> prefixlen 64 accept_rtadv" ipv6_defaultrouter="fe80::1%igb0" resolv_enable="NO"

Anmerkung der Redaktion: Kommt auf die Netwerk-Karte an wie der Device-Name ist: em0, bge0, … – Oder wie bei mir: igb0.

OpenSSH abdichten

Orientiere mich dabei an der cipherlist will aber (da es beim OS-Update nervt) die /etc/ssh/sshd_config nicht anfassen.

Deshalb kommt in die /etc/rc.config mittlerweile so was:

# OpenSSH sshd_flags=" \ -o ListenAddress=<v4 Addresse vom Server>:23 \ -o ListenAddress=[<v6 Addresse vom Server>]:23 \ -o Protocol=2 \ -o HostKey=/etc/ssh/ssh_host_ed25519_key \ -o HostKey=/etc/ssh/ssh_host_rsa_key \ -o HostKeyAlgorithms=ssh-ed25519,rsa-sha2-512,rsa-sha2-256 \ -o KexAlgorithms=curve25519-sha256@libssh.org,curve25519-sha256,diffie-hellman-group18-sha512,diffie-hellman-group16-sha512,diffie-hellman-group14-sha256,diffie-hellman-group-exchange-sha256 \ -o Ciphers=chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr \ -o MACs=hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com \ -o PermitRootLogin=no \ -o IgnoreRhosts=yes \ -o PasswordAuthentication=no \ -o PermitEmptyPasswords=no \ -o KbdInteractiveAuthentication=no \ -o UsePAM=no \ -o X11Forwarding=no \ " sshd_enable="YES"

Erwischt: Ja ich nutze den telnet Port für ssh.

NTPd listen local

Da habe ich noch keine Lösung wie man das mit ntpd_flags hin bekommt.

sockstat -l verrät uns, dass der NTPd auf jedem Interface Port 123 lauscht.

Die /etc/ntp.conf bekommt ein interface ignore wildcard, so wie auf einer eigenen Seite beschrieben.

Firewall

Noch nichts spannendes damit geplant, aber wenn Jails dazu kommen ist es gut eine Grundlage zu haben - /etc/pf.conf:

# public addresses ip_igb0_p4 = "<v4 Addresse vom Server>" ip_igb0_p6 = "<v6 Addresse vom Server>" # tables table <tbl_allow> const { "my.other.host.example.net", "dyndns.example.org" } table <tbl_block> persist {} # services hosted on this box # 60000: mosh inbound_tcp = "{ telnet }" inbound_udp = "{ 60000:60010 }" # services consumed by this box outbound_tcp = "{ ssh, telnet, domain, http, https, ftp }" outbound_udp = "{ domain, ntp }" # icmp types icmp_types_p4 = "{ echoreq, unreach }" icmp_types_p6 = "{ echoreq, echorep, unreach, toobig, timex, routersol, routeradv, neighbrsol, neighbradv, redir }" # allow loopback traffic set skip on { lo0 } # do not reject, just drop set block-policy drop # incoming traffic is normalized and defragmented scrub in on igb0 all fragment reassemble # default rule - block all block log all # apply tables block drop in from <tbl_block> to any pass in from <tbl_allow> to any # allow ping pass inet proto icmp all icmp-type $icmp_types_p4 keep state pass inet6 proto icmp6 all icmp6-type $icmp_types_p6 keep state # allow access to outside world pass out proto tcp to any port $outbound_tcp keep state pass out proto udp to any port $outbound_udp keep state # allow outside access into this box pass in log proto tcp to any port $inbound_tcp keep state (max-src-conn 5, max-src-conn-rate 2/10, overload <tbl_block> flush global) pass in log proto udp to any port $inbound_udp keep state (max-src-conn 5, max-src-conn-rate 2/10, overload <tbl_block> flush global)
  • Eher unspannend, von außen sind nur noch die Ports telnet (für ssh) und die 60000er Range für mosh offen.
  • Wichtiger sind die zwei Tables:
    • tbl_allow
      • Sind fixe Adressen von meinen anderen Kisten.
      • Soll verhindern, dass ich mich versehentlich aussperre.
    • tbl_block
      • Wird auf alle offenen Ports angesetzt und macht ein Rate-Limiting
      • Wehrt stumpfsinnige DoS Angriffe ab.
      • Das pf_auth Script erweitert die noch um Einträge aus der /var/log/auth.log.

In der /etc/rc.conf noch einschalten:

# Firewall pf_enable="YES" pf_rules="/etc/pf.conf" pflog_enable="YES" pflog_logfile="/var/log/pflog"

(Wobei man pflog auch weglassen kann.)

Tools

Habe mir im Laufe der Zeit eine paar Scripte geschrieben die das Leben einfacher machen.

pkg install vim git-lite

(git-lite bringt weniger Abhängigkeiten mit als git, gut für den Server)

Und dann als User klonen:

mkdir ~/code cd ~/code git clone https://github.com/spookey/dirty_little_helpers.git git clone https://github.com/spookey/geli_remote_unlock.git git clone https://github.com/spookey/say_cheese_zfs.git git clone https://gitlab.com/spookey/quicksnap.git

quicksnap

Einfach, aber effektiv. Hat eine input.txt mit einem Pfad pro Zeile und kopiert die Files rüber. Das ganze in ein git repo packen und zack, hat man seine Config versioniert und ein Backup davon.

Erst mal einen Key anlegen:

ssh-keygen -t ed25519 -f `/root/.ssh/quicksnap_ed25519` -C 'root@machine'

Bei dem git Hoster des geringsten Misstrauens ein private Repo anlegen, und /root/.ssh/quicksnap_ed25519.pub hinterlegen.

Eine entsprechende ssh config für root:

cat << LOL >> /root/.ssh/config Host git.example.net User git IdentityFile ~/.ssh/quicksnap_ed25519 Host * VisualHostKey true LOL

Das Repo clonen:

mkdir /root/code cd /root/code git clone ssh://git.example.net/user/conf_machine.git

Als letztes noch das Wrapper-Script unter /root/bin/quicksnap

#!/usr/bin/env sh INPUT=/root/code/conf_machine/input.txt \ OUTPUT=/root/code/conf_machine/output \ /usr/home/user/code/quicksnap/quicksnap.sh "$@"

dirty little helpers

Hier brauchen wir nur wenige Sachen..

pf_auth

Macht nur Sinn, wenn man pf so eingerichtet hat, dass Einträge von tbl_block auch wirklich blockiert werden.

Alles was wir brauchen ist ein Eintrag in der crontab von root:

*/2 * * * * /usr/home/user/code/dirty_little_helpers/pf_auth/pf_auth.sh -n 3 /var/log/auth.log >> /var/log/pf_auth.log 2>&1

Es lassen sich der auth.log Parameter mehrfach angeben.

Ab dem Moment wenn jails laufen sollte man den Eintrag noch um /usr/jails/*/var/log/auth.log erweitern, um alles einzusammeln.

Log Rotation – /usr/local/etc/newsyslog.conf.d/pf_auth.conf:

cat << LOL >> /usr/local/etc/newsyslog.conf.d/pf_auth.conf /var/log/pf_auth.log 644 4 * @T00 BCNX LOL

jail_pkg_list

Die Paket-Namen mit Version einfach in einer Text-Datei speichern. Das ganze ins quicksnap Repo legen, dann weiß man wann was installiert wurde.

ln -s /usr/home/user/code/dirty_little_helpers/jail_pkg_list/jail_pkg_list.sh /root/bin/jail_pkg_list

Und das ganze auch noch automatisch in der crontab von root:

*/30 * * * * /usr/home/user/code/dirty_little_helpers/jail_pkg_list/jail_pkg_list.sh > /var/log/jail_pkg_list.log

Geht auch als normaler user, aber aufpassen bei den Berechtigungen vom Log-File.

jail_pkg

Einmal pkg für alle Jails ausführen. Anwendungsfall zu 99% ist jail_pkg update und jail_pkg upgrade.

Hier reicht eine Verlinkung nach /root/bin (analog zu oben).

say cheese

Macht automatisch zfs Snapshots, und räumt auch wieder auf.

Python ist durch vim schon längst da, aber es fehlt noch das Meta-Package:

pkg install python3

In der crontab von root noch einrichten:

# say cheese 1 * * * * /usr/local/bin/python3 /usr/home/user/code/say_cheese_zfs/take_snapshots.py auto_hourly >> /var/log/say_cheese.log 2>&1 11 * * * * /usr/local/bin/python3 /usr/home/user/code/say_cheese_zfs/purge_snapshots.py 24 H -p auto_hourly >> /var/log/say_cheese.log 2>&1 3 0 * * * /usr/local/bin/python3 /usr/home/user/code/say_cheese_zfs/take_snapshots.py auto_daily >> /var/log/say_cheese.log 2>&1 13 0 * * * /usr/local/bin/python3 /usr/home/user/code/say_cheese_zfs/purge_snapshots.py 7 d -p auto_daily >> /var/log/say_cheese.log 2>&1 5 0 * * 0 /usr/local/bin/python3 /usr/home/user/code/say_cheese_zfs/take_snapshots.py auto_weekly >> /var/log/say_cheese.log 2>&1 15 0 * * 0 /usr/local/bin/python3 /usr/home/user/code/say_cheese_zfs/purge_snapshots.py 4 w -p auto_weekly >> /var/log/say_cheese.log 2>&1 7 0 1 * * /usr/local/bin/python3 /usr/home/user/code/say_cheese_zfs/take_snapshots.py auto_monthly >> /var/log/say_cheese.log 2>&1 17 0 1 * * /usr/local/bin/python3 /usr/home/user/code/say_cheese_zfs/purge_snapshots.py 12 m -p auto_monthly >> /var/log/say_cheese.log 2>&1 9 0 1 1 * /usr/local/bin/python3 /usr/home/user/code/say_cheese_zfs/take_snapshots.py auto_yearly >> /var/log/say_cheese.log 2>&1 19 0 1 1 * /usr/local/bin/python3 /usr/home/user/code/say_cheese_zfs/purge_snapshots.py 2 y -p auto_yearly >> /var/log/say_cheese.log 2>&1

Nach und nach sollten die Snapshots jetzt eintrudeln.

Log Rotation – /usr/local/etc/newsyslog.conf.d/say_cheese.conf:

cat << LOL >> /usr/local/etc/newsyslog.conf.d/say_cheese.conf /var/log/say_cheese.log 644 9 1000 * BCNX LOL

geli remote unlock (rc Script)

Das rc Script kopieren:

cp /usr/home/user/code/geli_remote_unlock/geliremoteunlock /usr/local/etc/rc.d/ chown root:wheel /usr/local/etc/rc.d/geliremoteunlock chmod +x /usr/local/etc/rc.d/geliremoteunlock

Erlaubt uns die Pools automatisch zu entsperren…

last update: 2025-02-07 14:35:53 +0100