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"
netwait_enable="YES"
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ürssh
) und die60000
er Range fürmosh
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
.
- tbl_allow
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 clonen:
mkdir ~/code
cd ~/code
git clone https://gitlab.com/spookey/quicksnap.git
git clone https://github.com/spookey/dirty_little_helpers.git
git clone https://github.com/spookey/say_cheese_zfs.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 für quicksnap
mkdir /root/bin
cat << LOL >> /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 "$@"
LOL
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.
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/spky/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/spky/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.