Neuen Server Einrichten
Vorwort
Für ein Projekt, bei dem ich mitwirke, haben wir uns dieses Jahr dazu entschlossen einen eigenen Server einzurichten. Der Hauptgrund dafür, war das einige der gewünschten Funktionen, schnell über die Möglichkeiten eines WebSpaces hinausgingen und auch zu erwarten war das der Speicherplatz bedarf schnell Wachsen wird.
Da ich aktuell aber nicht soviel Zeit habe, musste ich schauen das ich den Server erst mal schnell absichere. Damit er auch im Zweifel mal ein Paar Tage unbeaufsichtigt nicht zu einer Spam Schleuder mutiert.
Hier wird also erst mal aufgeführt wie ich den Server Absichere. Was ich mit SSH Public Key Authentifizierung, fail2ban und iptables mache.
SSH
Zur Absicherung des SSH Dienstes nutzte ich im wesentlichem zwei Systeme. SSH Public Key Authentifizierung und Abschaltung der Möglichkeit dies via Passwort zu machen und fail2ban.
Was einige noch gerne machen ist den SSH Port von 22 auf einen anderen zu legen. Da aber ein nmap mit ‚-Pn -p 1-65535‘ den SSH Port einfach findet, halte ich diese Maßnahme für vergebliche mühen. SSH Public Key Authentifizierung und fail2ban sind immer noch dann wirkungsvoll wenn ich die Informationen dazu veröffentliche.
SSH Konfiguration anpassen
Bevor wir die Anmeldung via Passwort sperren und nur Public Key Authentifizierung zulassen, müssen wir natürlich sicherstellen das diese Funktioniert. Dazu generieren wir uns einen SSH Key auf unserem System. Ich nehme hierbei noch RSA da der Gnome Keyring noch nicht mit ed25519 klar kommt/kam(?).
ssh-keygen -t rsa -b 8192 -C "Beschreibung für den Key
Ihr solltet unbedingt eine Passphrase angeben. Da man sonst nur mir dem Key sich an eurem Server anmelden darf. Nach dem Befehl habt ihr unter ~/.ssh die beiden Dateien id_rsa und id_rsa.pub. Die Datei id_rsa stellt dabei euren Privaten Schlüssel dar und ist vertraulich zu behandeln. id_rsa.pub enthält hingegen euren öffentlichen Schlüssen den ihr nun auf den Server packen müsst. Einfachster Weg dafür ist der Befehl ssh-copy-id.
ssh-copy-id USER@server.example
Nach der Eingabe der Passphrasen für den Key und den Server, wird unter ~/.ssh des angegeben Benutzers die Datei authorized_keys mit eurem Public Key hinterlegt oder ggf. erweitert. Wenn ihr euch nun mit dem Befehl ’ssh USER@server.example‘ am Server anmelden könnt und nicht mehr dessen Passwort angeben müsst, können wir die Passwort Authentifizierung abschalten.
Dazu müsst ihr in die Datei ‚/etc/ssh/sshd_config‘ folgenden Eintrag stehen haben:
… PasswordAuthentication No …
Anschließend könnt ihr mit dem Befehl von systemd ’systemctl restart sshd‘ den SSH Daemon neu starten. Die Aktuelle SSH-Session könnt ihr aber offen halten, als Sicherheit und parallel eine neue Anmeldung via SSH probieren. Klappt nun alles, habt ihr die Sicherheit das sich keiner mehr via Passwort beim SSH Dienst anmelden kann.
Fail2Ban
Kurz erklärt, sperrt fail2ban IP Adressen, von denen aus man versucht hat, sich zu oft erfolglos anzumelden. Dies wird von fail2ban normalerweise über iptables durchgeführt. Da ich dies später auch noch für weitere Absicherung nutzten werde, installieren wir iptables-persistent gleich mit.
apt update && apt install fail2ban iptables iptables-persistent
Von fail2ban ist es vorgesehen die lokalen Einstellunken in der ‚jail.local‘ zu ändern. Diese müssen wir erst mal hinterlegen.
cp /etc/fail2ban/jail.{conf,local}
Ihr könnt die ‚jail.local‘ Datei nun anpassen. Die Standard werte sind aber schon funktionsfähig. Ich Persönlich ändere noch folgende werte:
… bantime = 3600 #Sperrt eine IP für 3600 Sekunden. … findtime = 600 #Sucht in einem Zeitrahmen von 600 Sekunden nach doppelten Anmelden. … maxretry = 3 #Erlaubt nur drei gescheiterte Anmeldung je IP, bevor gebannt wird. …
Nun startet ihr iptables und fail2ban am besten neu und habt euer Ziel erreicht.
systemctl restart iptables fail2ban
Iptables
Bei der Frage iptables vs. nftables ist wichtig zu beachten das nftables sehr neu ist und noch nicht von allen Systemen, wie bspw. fail2ban unterstützt wird. Es ist sicherlich möglich fail2ban nftables beizubringen aber aktuell sieht die default Konfiguration dies noch nicht vor. Daher kommt hier noch iptables zum Einsatz. Zusätzlich ist bei dem Paket iptables-persistent Vorsicht geboten. Mit Diensten die dynamisch iptables Regel laden, kann iptables-persistent regeln persistieren die dafür eigentlich nicht vorgesehen sind. Daher werde ich den Befehl ’netfilter-persistent save‘, welcher die iptables Regeln speichert, auch nur einmal einsetzten und später die Regeln manuell in iptables und der Datei ‚/etc/iptables/rules.v4‘ einpflegen. Dadurch habe ich nach einem reboot bspw. nicht doppelte Regeln.
Wichtig: ‚enp1s0‘ steht für mein externes Network Device und muss an den Namen von eurem angepasst werden.
Als aller erste Regeln für iptables, hinterlegen wir die Freigabe vom SSH Port.
iptables -A INPUT -i enp1s0 -p tcp --dport 22 -j ACCEPT
Um Sicher zustellen das dies Funktioniert hat und wir später das Standartverhalten von der INPUT CHAIN auf DROP stellen können, ohne uns auszusperren. Aktivieren wir das DROP nur temporär mit folgenden Befehl und versuchen uns während der 60 Sekunden vom sleep Befehl parallel via SSH anzumelden.
iptables -P INPUT DROP; sleep 60; iptables -P INPUT ACCEPT
Wenn wir uns während der 60 Sekunden via SSH noch anmelden konnten, können wir ab hier weiter machen und hinterlegen nun die Regeln damit der Server sich internen Traffic auf dem lo Interface nicht blockt und auch auf Pings reagiert.
iptables -I INPUT -i lo -m comment --comment "Local traffic" -j ACCEPT iptables -I INPUT -m conntrack --ctstate RELATED,ESTABLISHED -m comment --comment "Legitimate traffic" -j ACCEPT iptables -I INPUT -p icmp -m icmp --icmp-type 8 -m comment --comment Pings -j ACCEPT
Nun können wir das Standardverhalten von INPUT permanent ändern.
iptables -P INPUT DROP
Erstmal speichern wir die aktuellen regeln und bereinigen sie gleich von den fail2ban Einträgen.
netfilter-persistent save sed -i '/f2b-sshd/d' /etc/iptables/rules.v4
Anschließend sollte die Datei wie folgt aussehen:
… *filter :INPUT DROP [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [825:71156] -A INPUT -i lo -m comment --comment "Local traffic" -j ACCEPT -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -m comment --comment "Legitimate traffic" -j ACCEPT -A INPUT -p icmp -m icmp --icmp-type 8 -m comment --comment Pings -j ACCEPT -A INPUT -i enp1s0 -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -m comment --comment SSH -j ACCEPT COMMIT …
Dies war es nun. Die Regeln sollten aktive laufen und nach einem reboot sollte alles so vorgefunden werden wie gewünscht.
Abschluss
Auf Basis dieses Post werden viele meiner weiteren Artikel beruhen. Die besondere Handhabung von iptables ist zu großem Teil lxc-net von lxc geschuldet. Da dieses später sonst diverse doppelte Einträge generiert. Fail2Ban macht dies aber auch gerne.
Ich halte es für dämlich, für einen „sicheren“ Server diesen systemd-Unsinn zu nutzen. Aber gut – manche Menschen mögen Glücksspiel.
Ich denke die systemd Sache wurde schon oft genug Diskutiert. Ich kann die Kritik daran wirklich gut verstehen und bin da auch oft der gleichen Meinung. Sehe aber auch deutliche Vorteile, welche mMn inzwischen mehr Gewichtung haben als die Nachteile. Es kommt langsam so vor als wenn es mehr ein Glaubenskrieg sei.
Was nutzt du statt systemd?
„Was einige noch gerne machen ist den SSH Port von 22 auf einen anderen zu legen. Da aber ein nmap mit ‚-Pn -p 1-65535‘ den SSH Port einfach findet, halte ich diese Maßnahme für vergebliche mühen.“
Dabei geht es eher darum die logfiles etwas aufgeräumter zu halten. Bei Verwendung von Port 22 gehen sonst evtl. tatsächliche Angriffe im Rauschen unter.
Gut das kann ich Nachvollziehen, meine aber das so etwas durch Logfilterung, -analyse und das Monitorring abgedeckt werden sollte und nicht durch kleine Logs kompensiert gehört. An der stelle kann ich nur Kibana, Zabbix und lnav empfehlen.