Dieser Leitfaden erklärt alle wesentlichen Linux-Sicherheitsgrundlagen für einen frischen Debian Linux Server und beschreibt alle erforderlichen grundlegenden Sicherheitsmaßnahmen.
Dieser Blogpost wurde von einer Maschine aus dem Englischen übersetzt. Die Originalversion finden Sie hier: Ultimate Guide About Linux Server Security Basics for Debian
Bitte kontaktieren Sie uns , wenn etwas nicht klar beschrieben ist, nicht funktioniert, falsch erscheint oder wenn Sie Unterstützung benötigen.
Dieses umfassende Tutorial erklärt gründlich die notwendigen Sicherheitsmaßnahmen zur Absicherung einer frischen Debian Linux Server-Installation. Es enthält und erklärt alle erforderlichen Schritte, um Ihren Server sicher zu halten, wenn er öffentlich über das Internet erreichbar ist.
Es ist für diejenigen geschrieben, die “einfach nur WordPress hosten” oder ähnliche Tools auf Debian-Servern betreiben möchten. Es deckt die wesentlichen Sicherheitsmaßnahmen ab, gibt Einblicke in zusätzliche Schritte, die Sie ergreifen können, und erklärt, warum grundlegende Sicherheit normalerweise für die meisten Hosting-Anforderungen ausreichend ist.
Wenn Sie diesem Tutorial folgen, können Sie Ihren Server als sicher betrachten.
Wenn Sie einen frischen Debian-Server von Ihrem Cloud- oder physischen Server-Anbieter erhalten, sollte der erste Schritt immer sein, alle verfügbaren Upgrades zu installieren und dann, falls erforderlich, neu zu starten. Die meisten IaaS-Anbieter haben leicht veraltete Templates.
apt update
apt upgrade
Sie können überprüfen, ob ein Neustart erforderlich ist - wenn die Datei existiert und Kernel-Pakete (linux-image) auflistet, ist ein Neustart erforderlich.
cat /var/run/reboot-required.pkgs
linux-image-6.1.0-20-amd64
linux-image-6.1.0-21-amd64
Wie Sie sehen können, ist ein neuer Kernel verfügbar und Sie sollten neu starten, um ihn zu verwenden:
reboot
Beginnen wir mit SSH, dem einzigen Dienst, der auf fast jedem Debian Linux Server mit einer öffentlichen IP-Adresse standardmäßig installiert ist.
Das erste Problem mit SSH ist, dass fast jeder Server- oder Cloud-Anbieter Ihnen ein frisches Debian mit irgendeiner Art von Passwort für SSH gibt. Dies liegt daran, dass die Verwendung der SSH-Schlüsselpaar-Authentifizierung für neue Benutzer oft kompliziert ist. Lassen Sie uns das entmystifizieren.
Lassen Sie uns ein neues SSH-Schlüsselpaar generieren. Wir werden ein Schlüsselpaar mit dem ed25519-Signaturalgorithmus generieren, der zum Zeitpunkt dieses Schreibens als die sicherste Wahl für neue SSH-Schlüsselpaare gilt. Geben Sie den folgenden Befehl ein und drücken Sie dann einfach weiter ENTER.
ssh-keygen -t ed25519
Es wird die folgende Ausgabe erzeugen:
1 Generating public/private ed25519 key pair.
2 Enter file in which to save the key (/home/user/.ssh/id_ed25519):
3 Enter passphrase (empty for no passphrase):
4 Enter same passphrase again:
5 Your identification has been saved in /home/user/.ssh/id_ed25519
6 Your public key has been saved in /home/user/.ssh/id_ed25519.pub
7 The key fingerprint is:
8 SHA256:aIxPK+6UxUWrgCAUWkBKDYMldx+nvOBqJnMW3xYVDxg user@host
9 The key's randomart image is:
10 +--[ED25519 256]--+
11 |OXB . Eo= |
12 |*=.+ o.= = |
13 |o . o + + . |
14 | . * * |
15 | . o @ S |
16 | + B o |
17 |o * = = |
18 | B o o |
19 | .o |
20 +----[SHA256]-----+
Lassen Sie uns diese Ausgabe Zeile für Zeile durchgehen:
Zeile 1 ist ziemlich offensichtlich.
Zeile 2 lässt Sie den Speicherort für Ihren neuen privaten Schlüssel definieren. Beachten Sie, dass ich hier einfach ENTER gedrückt habe, um den Standardspeicherort zu verwenden. Wenn Sie noch kein Schlüsselpaar haben, verwenden Sie einfach auch den Standardspeicherort. Wenn Sie mehrere SSH-Schlüsselpaare haben, geben Sie einen benutzerdefinierten Speicherort für das neue Schlüsselpaar an. In diesem Fall müssen Sie sie mit dem folgenden Befehl zu Ihrem ssh-agent hinzufügen:
ssh-add ~/.ssh/customer/id_ed25519
Identity added: /home/user/.ssh/customer/id_ed25519 (p.thurner@customer.com)
Zeile 3 und 4 fragen nach einem Passwort für den privaten SSH-Schlüssel, was bedeutet, dass Sie ihn zunächst mit einem Passwort entschlüsseln müssen, wenn Sie den privaten Schlüssel verwenden möchten, um sich bei einem Server anzumelden. Wenn Sie SICHER sind, dass Ihre Workstation nicht von einer anderen Person aufgerufen wird, während Sie angemeldet sind und nicht physisch anwesend sind (wie bei einem Evil-Maid-Angriff
), und wenn Sie nicht davon ausgehen, dass Malware auf Ihrem Computer installiert werden könnte, um Ihren privaten SSH-Schlüssel zu extrahieren, dann können Sie das Setzen eines Passworts für den privaten SSH-Schlüssel weglassen. Wenn Sie ein Passwort für Ihren privaten SSH-Schlüssel setzen, müssen Sie dieses eingeben, wenn Sie den privaten Schlüssel verwenden, um sich bei einem Server anzumelden. Das Programm ssh-agent speichert dieses Passwort standardmäßig unbegrenzt zwischen, aber Sie können das definieren, wenn Sie den ssh-agent mit dem -t-Argument starten. Aus man ssh-agent:
-t life
Set a default value for the maximum lifetime of identities added to the agent. The lifetime may be specified in seconds or
in a time format specified in sshd_config(5). A lifetime specified for an identity with ssh-add(1) overrides this value.
Without this option the default maximum lifetime is forever.
Wenn Sie also ssh-agent verwenden, was Sie sicherlich tun werden, um Ihr Passwort für den privaten SSH-Schlüssel nicht 50 Mal am Tag eingeben zu müssen, wird es standardmäßig dieses Passwort für immer zwischenspeichern (das bedeutet, bis Sie sich abmelden oder herunterfahren / neu starten). Wenn eine andere Person physischen Zugriff auf Ihren Laptop erhält, während Sie angemeldet sind, ist das Passwort daher nutzlos. Es ist daher am besten, sicherzustellen, dass Ihre Workstation ausgeschaltet ist, wenn Sie sie nicht verwenden.
Zeile 5 teilt Ihnen mit, dass der private SSH-Schlüssel jetzt unter /home/user/.ssh/id_ed25519 liegt. Dies ist das, was Sie verwenden, um sich bei Servern anzumelden. GEBEN SIE DIESE DATEI NIEMANDEM!
Zeile 6 teilt Ihnen mit, dass Ihr öffentlicher SSH-Schlüssel jetzt unter /home/user/.ssh/id_ed25519.pub liegt. Wie das Wort öffentlich impliziert, können Sie Ihre öffentlichen SSH-Schlüssel im Internet veröffentlichen, wenn Sie möchten
ohne jedes Sicherheitsrisiko. Der Inhalt dieser Datei ist das, was Sie später auf Server in die Datei ~/.ssh/authorized_keys hochladen.
Zeile 7 und 8 ist der Fingerabdruck des öffentlichen Schlüssels, der ein eindeutiger Identifikator ist, der vom öffentlichen Schlüssel abgeleitet wird und oft verwendet wird, um die Authentizität des Schlüssels zu überprüfen. Sie können den Fingerabdruck später mit dem folgenden Befehl anzeigen:
ssh-keygen -lf ~/.ssh/id_ed25519
256 SHA256:aIxPK+6UxUWrgCAUWkBKDYMldx+nvOBqJnMW3xYVDxg user@host (ED25519)
Der Fingerabdruck des öffentlichen SSH-Schlüssels ist ein base64-codierter SHA256-Hash des Schlüsselteils des öffentlichen SSH-Schlüssels. Zum besseren Verständnis, hier ist, wie Sie den Fingerabdruck aus einem öffentlichen SSH-Schlüssel mit Bash-Befehlen generieren:
cut -d ' ' -f 2 ~/.ssh/id_ed25519.pub | base64 -d | sha256sum | cut -d ' ' -f 1 | xxd -r -p | base64
aIxPK+6UxUWrgCAUWkBKDYMldx+nvOBqJnMW3xYVDxg=
Zeile 9 bis 20 dieses Zufallskunstbildes ist eine visuelle Darstellung des öffentlichen Schlüssels. Es soll einen einzigartigen und für Menschen leicht erkennbaren visuellen Fingerabdruck des Schlüssels bieten. Dieser visuelle Fingerabdruck soll Benutzern helfen, die Authentizität des öffentlichen Schlüssels zu überprüfen. Meiner Meinung nach ist dies für Menschen nicht wirklich nützlich. In meinen 20 Jahren Arbeit mit Linux habe ich das nicht ein einziges Mal gemacht. Sie können das Zufallskunstbild für einen vorhandenen öffentlichen (oder privaten) Schlüssel so anzeigen - es ist die gleiche Ausgabe für sowohl den privaten als auch den öffentlichen Schlüssel, da Sie den öffentlichen Schlüssel aus einem gegebenen privaten Schlüssel generieren können:
ssh-keygen -lv -f ~/.ssh/id_ed25519.pub
256 SHA256:aIxPK+6UxUWrgCAUWkBKDYMldx+nvOBqJnMW3xYVDxg user@host (ED25519)
+--[ED25519 256]--+
|OXB . Eo= |
|*=.+ o.= = |
|o . o + + . |
| . * * |
| . o @ S |
| + B o |
|o * = = |
| B o o |
| .o |
+----[SHA256]-----+
Falls Sie neugierig waren: So generieren Sie einen öffentlichen Schlüssel aus einem privaten Schlüssel, falls Sie jemals den öffentlichen Schlüssel “verlieren” sollten:
ssh-keygen -y -f ~/.ssh/id_ed25519
Um Ihren neuen öffentlichen SSH-Schlüssel auf dem Server zu “installieren”, den Sie verwalten, verwenden Sie den folgenden Befehl. Er wird Ihren neu generierten Standard-SSH-öffentlichen Schlüssel ~/.ssh/id_ed25519 nach root@server:/root/.ssh/authorized_keys kopieren. Wenn Sie mehrere öffentliche SSH-Schlüssel haben, verwenden Sie das -i ~/.ssh/customer/id_ed25519-Argument.
ssh-copy-id root@www.blunix.com
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@www.blunix.com's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@www.blunix.com'"
and check to make sure that only the key(s) you wanted were added.
Um zu überprüfen, dass der Schlüssel installiert wurde, versuchen Sie einfach, sich beim Server anzumelden. Es sollte nicht mehr nach einem Passwort fragen:
ssh root@blunix.com
Linux www.blunix.com 6.1.0-18-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.76-1 (2024-02-01) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun May 26 06:39:56 2024 from 146.70.134.46
root@www.blunix.com:~#
Danach ist es sicher, das Passwort für den Root-Benutzer zu entfernen. Beachten Sie, dass dies kein leeres Passwort setzt, das jedem erlaubt sich anzumelden, sondern es schreibt ein ! anstelle eines Passwort-Hashes in /etc/shadow, was bedeutet, dass kein Passwort jemals akzeptiert wird - die einzige Möglichkeit, dann der Root-Benutzer zu werden, besteht darin, sich über SSH mit dem privaten Schlüssel zum öffentlichen Schlüssel anzumelden, der jetzt in /root/.ssh/authorized_keys gespeichert ist.
passwd --delete --lock root
Jetzt, da wir uns ohne Passwort beim Server anmelden können, sollten wir die passwortbasierte Authentifizierung auf dem Server vollständig deaktivieren. Danach ist die einzige Möglichkeit, sich mit SSH beim Server anzumelden, der private SSH-Schlüssel, den wir im vorherigen Abschnitt eingerichtet haben.
Früher war es üblich, /etc/ssh/sshd_config direkt zu bearbeiten. Neuere Debian Linux-Versionen verfügen jetzt über ein Verzeichnis /etc/ssh/sshd_config.d/, in dem Sie Überschreibungen zur Standardkonfigurationsdatei platzieren können. Dies wird bevorzugt, damit apt die ursprüngliche Konfigurationsdatei automatisch verwalten und bei Bedarf Updates der Standardkonfigurationsoptionen dort platzieren kann. Wenn Sie Änderungen daran vornehmen, wird apt diese Datei nicht mit neuen Versionen aktualisieren, die vom Paketbetreuer veröffentlicht werden.
echo "PasswordAuthentication no" | tee -a /etc/ssh/sshd_config.d/99-custom.conf
Die Standard-SSH-Daemon-Installation auf Debian kommt mit vielen Funktionen, die Sie HÖCHSTWAHRSCHEINLICH nicht benötigen. Wir können diese sicher deaktivieren. Häufige Kandidaten sind:
cat << EOF | tee -a /etc/ssh/sshd_config.d/99-custom.conf
AllowTcpForwarding no
HostbasedAuthentication no
PermitEmptyPasswords no
PermitTunnel no
X11Forwarding no
EOF
Weitere Informationen zu jeder Konfigurationsoption finden Sie auf der sshd-Konfig-Handbuchseite . Wie im nächsten Abschnitt beschrieben, überprüfen und starten Sie die SSH-Daemon-Konfiguration nach Änderungen neu.
Bevor Sie den SSH-Daemon neu starten, ist es hilfreich sicherzustellen, dass wir keine Syntaxfehler in den Konfigurationsdateien gemacht haben. Verwenden Sie dafür den folgenden Befehl:
sshd -t
/etc/ssh/sshd_config line 124: no argument after keyword "NoSuchOption"
/etc/ssh/sshd_config: terminating, 1 bad configuration options
Wie Sie sehen können, existiert die Konfigurationsoption NoSuchOption nicht und sshd beschwert sich darüber. Wenn der SSH-Daemon-Prozess mit systemd gesteuert wird, verwendet systemd ebenfalls diese Überprüfung:
grep ExecStartPre /lib/systemd/system/ssh.service
ExecStartPre=/usr/sbin/sshd -t
Wenn wir also versuchen würden, den SSH-Daemon mit systemd neu zu starten, während die Konfigurationsdatei fehlerhaft ist, würde es fehlschlagen:
systemctl restart sshd.service
Job for ssh.service failed because the control process exited with error code.
See "systemctl status ssh.service" and "journalctl -xeu ssh.service" for details.
journalctl _COMM=sshd --lines=2
May 26 07:00:52 www.blunix.com sshd[1615811]: /etc/ssh/sshd_config: line 125: Bad configuration option: NoSuchOption
May 26 07:00:52 www.blunix.com sshd[1615811]: /etc/ssh/sshd_config: terminating, 1 bad configuration options
Sie können zu 100% sicherstellen, dass Ihre Konfigurationsänderungen angewendet wurden, indem Sie sshd -T verwenden, um die Konfiguration zu drucken, die auf sshd angewendet wird, wenn es gestartet wird. Beachten Sie, dass die Laufzeitkonfigurationsoptionen kleingeschrieben werden, zum Beispiel passwordauthentication, während die Konfigurationsoptionen in /etc/ssh/sshd_config und in /etc/ssh/sshd_config.d/ in CamelCase geschrieben werden wie PasswordAuthentication.
sshd -T | grep --ignore-case PasswordAuthentication
passwordauthentication no
Nachdem Sie Änderungen an der Konfigurationsdatei des SSH-Daemons vorgenommen haben, müssen wir den SSH-Daemon neu starten, um die Änderungen anzuwenden. Wenn Sie alles zu Ihrer Zufriedenheit konfiguriert haben, starten Sie den SSH-Daemon mit dem systemd-systemctl-Befehl neu:
systemctl restart sshd.service
Und stellen Sie sicher, dass es korrekt läuft:
systemctl status sshd.service
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled; preset: enabled)
Active: active (running) since Sun 2024-05-26 06:44:44 CEST; 3min 16s ago
Docs: man:sshd(8)
man:sshd_config(5)
Process: 1615569 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
Main PID: 1615570 (sshd)
Tasks: 1 (limit: 2244)
Memory: 1.4M
CPU: 26ms
CGroup: /system.slice/ssh.service
└─1615570 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"
May 26 06:44:43 www.blunix.com systemd[1]: Starting ssh.service - OpenBSD Secure Shell server...
May 26 06:44:44 www.blunix.com sshd[1615570]: Server listening on 0.0.0.0 port 22.
May 26 06:44:44 www.blunix.com sshd[1615570]: Server listening on :: port 22.
May 26 06:44:44 www.blunix.com systemd[1]: Started ssh.service - OpenBSD Secure Shell server.
Der fail2ban-Filter für sshd ist so konzipiert, dass er alle Verbindungen von IP-Adressen dauerhaft verwirft, die innerhalb eines bestimmten Zeitrahmens mehr als eine bestimmte Anzahl von Authentifizierungen fehlschlagen lassen.
Es gibt Millionen von Bots, die das Internet nach SSH-Servern durchsuchen, die Passwörter akzeptieren, und wenn sie es tun, versuchen diese Bots schwache Passwörter, um zu sehen, ob sie sich anmelden können. Da wir jedoch die passwortbasierte Authentifizierung oben deaktiviert haben, ist die Anmeldung mit einem Passwort überhaupt nicht mehr möglich. Daher werden alle diese Bots scheitern. Die Chance, dass ein Angreifer unseren privaten SSH-Schlüssel “errät”, ist (lächerlich nahe an) null.
Das Deaktivieren der Passwort-Authentifizierung hält Bots natürlich nicht davon ab, es zu versuchen. Fehlgeschlagene SSH-Authentifizierungsversuche sind ein bisschen wie Käfer, die in Ihre Windschutzscheibe krachen, wenn Sie auf der Autobahn fahren - es ist völlig normal und in keiner Weise eine Gefahr. Hier sind die Logdateien für fehlgeschlagene Versuche vom Server, der die Website www.blunix.com betreibt, für den Zeitraum von 24 Stunden:
journalctl _COMM=sshd --grep='^invalid user' --no-pager --since "2024-05-25 00:00:00" --until "2024-05-25 23:59:59" | nl
1 May 25 01:18:59 www.blunix.com sshd[1608441]: Invalid myuser myusername from 85.209.11.27 port 54444
2 May 25 01:34:51 www.blunix.com sshd[1608627]: Invalid myuser myuser from 192.227.148.214 port 47718
3 May 25 01:34:52 www.blunix.com sshd[1608629]: Invalid myuser myuser from 192.227.148.214 port 47730
4 May 25 01:34:53 www.blunix.com sshd[1608631]: Invalid myuser myuser from 192.227.148.214 port 47736
[...]
863 May 25 23:29:49 www.blunix.com sshd[1612608]: Invalid user admin from 85.209.11.27 port 56752
864 May 25 23:38:25 www.blunix.com sshd[1612614]: Invalid user pi from 24.77.153.102 port 50518
865 May 25 23:38:25 www.blunix.com sshd[1612615]: Invalid user pi from 24.77.153.102 port 50524
866 May 25 23:48:24 www.blunix.com sshd[1612624]: Invalid user telecomadmin from 194.169.175.36 port 21468
Wie Sie sehen, stammen mehrere Versuche von denselben IP-Adressen. Fehlgeschlagene SSH-Anmeldeversuche verursachen vernachlässigbare Last auf dem Server. Es ist völlig sicher, das zu ignorieren. Es schadet natürlich auch nicht, fail2ban zu installieren, um diese zu blockieren. fail2ban zu haben, könnte einen Vorteil haben - es könnte einen SSH-Daemon-Exploit geben, der nicht öffentlich bekannt und behoben ist und bei dem ein Angreifer mehrmals versuchen muss, sich anzumelden. Durch das Sperren von IPs mit mehreren fehlgeschlagenen Anmeldeversuchen könnte dies verhindern, dass ein solcher Exploit erfolgreich ist. Ein Angreifer könnte jedoch natürlich mehrere IP-Adressen nutzen. Wenn ich fail2ban hier jedoch nicht einbeziehen würde, könnte dieser Blogpost ein bisschen unvollständig wirken. Daher hier ist, wie man fail2ban installiert und konfiguriert, um den SSH-Daemon zu schützen:
apt-get install fail2ban
systemctl enable fail2ban.service
Synchronizing state of fail2ban.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable fail2ban
systemctl restart fail2ban.service
systemctl status fail2ban.service
● fail2ban.service - Fail2Ban Service
Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; preset: enabled)
Active: active (running) since Sun 2024-05-26 07:43:39 CEST; 3s ago
Docs: man:fail2ban(1)
Main PID: 1616302 (fail2ban-server)
Tasks: 5 (limit: 2244)
Memory: 28.3M
CPU: 313ms
CGroup: /system.slice/fail2ban.service
└─1616302 /usr/bin/python3 /usr/bin/fail2ban-server -xf start
May 26 07:43:39 www.blunix.com systemd[1]: Started fail2ban.service - Fail2Ban Service.
May 26 07:43:39 www.blunix.com fail2ban-server[1616302]: 2024-05-26 07:43:39,686 fail2ban.configreader [1616302]: WARNING 'allowipv6' not defined in 'Definition'. Using default one: 'auto'
May 26 07:43:39 www.blunix.com fail2ban-server[1616302]: Server ready
Das ist alles, was es zur Verwendung von fail2ban zum Blockieren wiederholter fehlgeschlagener SSH-Authentifizierungsversuche gibt. Das SSH-Jail ist standardmäßig aktiviert. fail2ban wird jetzt die Datei /var/log/auth.log auf fehlgeschlagene Anmeldeversuche überwachen und IPs für mehrere fehlgeschlagene Versuche sperren.
Hier sind die Ergebnisse nach 28 Stunden:
systemctl status fail2ban | grep Active
Active: active (running) since Sun 2024-05-26 07:43:39 CEST; 1 day 4h ago
fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 1
| |- Total failed: 180
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 0
|- Total banned: 16
Weitere Informationen zur Konfiguration von fail2ban und wie es funktioniert, finden Sie im Linux-Handbuch-Artikel über fail2ban und in der offiziellen fail2ban-Dokumentation .
Die Installation allgemeiner apt-Upgrades sowie Sicherheits-Upgrades ist im Allgemeinen nichts, was von Hand durchgeführt wird, sondern stattdessen automatisch durch Installation und Konfiguration des apt-Pakets unattended-upgrades.
Um unbeaufsichtigte Upgrades zu verwenden, muss das folgende apt-Paket installiert werden:
apt install unattended-upgrades
Um sie zu aktivieren, geben Sie den folgenden Befehl ein:
dpkg-reconfigure unattended-upgrades
Dies wird Sie mit Folgendem auffordern:
Applying updates on a frequent basis is an important part of keeping systems secure. By default, updates need to be applied manually using package management tools. Alternatively, you can choose to have this system automatically download and install important updates.
Automatically download and install stable updates?
<Yes> <No>
Verwenden Sie die TAB-Taste, um <Yes> auszuwählen, und drücken Sie ENTER. Von nun an werden alle apt-Upgrades automatisch installiert. Die Konfiguration dieses Vorgangs wird in den folgenden Abschnitten beschrieben.
Es gibt zwei Schritte zum Aktualisieren von apt-Paketen: apt update, um eine Liste der Pakete herunterzuladen, die aktualisiert werden können, und apt upgrade, um diese Upgrades tatsächlich zu installieren. Beide dieser Schritte haben ihre eigenen individuellen systemd-Timer und zugehörigen systemd-Services.
Sowohl Systemd-Timer als auch Systemd-Services sind etwas komplex, und der unbeaufsichtigte Upgrade-Mechanismus von apt verwendet sicherlich einige der komplexeren Funktionen von systemd-Timern und systemd-Services. Es funktioniert kurz gesagt so: Systemd-Timer sind wie Cronjobs, aber mit viel feinkörnigeren Zeit- und Trigger-Mechanismen. Systemd-Timer machen selbst nichts, außer systemd-Services auszulösen, die denselben Namen wie der systemd-Timer haben. Diese systemd-Services sind dann in diesem Fall keine Daemons irgendeiner Art (wie der apache2-Webserver), sondern einfach Befehle oder in diesem Fall BASH-Skripte, die entweder apt update oder apt upgrade ausführen - auf eine ziemlich komplexe Weise.
Weitere Informationen zu systemd-Timern finden Sie in unserem sehr umfassenden Blogpost über absolut alles, was es über systemd-Timer zu wissen gibt .
Der folgende Abschnitt gibt einen Überblick darüber, was den unbeaufsichtigten Upgrade-Mechanismus auslöst, wie, wann und was er auslöst.
Für apt update wird dieser systemd-Timer verwendet:
systemctl status apt-daily.timer
● apt-daily.timer - Daily apt download activities
Loaded: loaded (/lib/systemd/system/apt-daily.timer; enabled; preset: enabled)
Active: active (waiting) since Mon 2024-02-26 17:30:11 CET; 2 months 28 days ago
Trigger: Sun 2024-05-26 19:36:19 CEST; 10h left
Triggers: ● apt-daily.service
Der standardmäßig um 6 Uhr und 18 Uhr ausgelöst wird:
systemctl show apt-daily.timer --no-pager | grep TimersCalendar
TimersCalendar={ OnCalendar=*-*-* 06,18:00:00 ; next_elapse=Sun 2024-05-26 18:00:00 CEST }
Der systemd-Timer apt-daily.timer löst den systemd-Service apt-daily.service aus:
systemctl status apt-daily.service
○ apt-daily.service - Daily apt download activities
Loaded: loaded (/lib/systemd/system/apt-daily.service; static)
Active: inactive (dead) since Sun 2024-05-26 07:43:16 CEST; 54min ago
TriggeredBy: ● apt-daily.timer
Docs: man:apt(8)
Main PID: 1616140 (code=exited, status=0/SUCCESS)
CPU: 584ms
Der systemd-Service apt-daily.service führt diesen Befehl aus:
systemctl show apt-daily.service --no-pager|grep ^ExecStart=
ExecStart={ path=/usr/lib/apt/apt.systemd.daily ; argv[]=/usr/lib/apt/apt.systemd.daily update ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }
Zu erklären, was /usr/lib/apt/apt.systemd.daily genau macht, würde über das Ziel dieses Blogposts hinausgehen. Einfach ausgedrückt führt es apt update aus ;-)
Um apt upgrade periodisch auszuführen, wird der systemd-Timer apt-daily-upgrade.timer verwendet:
systemctl status apt-daily-upgrade.timer
● apt-daily-upgrade.timer - Daily apt upgrade and clean activities
Loaded: loaded (/lib/systemd/system/apt-daily-upgrade.timer; enabled; preset: enabled)
Active: active (waiting) since Mon 2024-02-26 17:30:11 CET; 2 months 28 days ago
Trigger: Mon 2024-05-27 06:07:58 CEST; 21h left
Triggers: ● apt-daily-upgrade.service
Der systemd-Timer apt-daily-upgrade.timer wird standardmäßig um 6 Uhr ausgelöst:
systemctl show apt-daily-upgrade.timer --no-pager | grep TimersCalendar
TimersCalendar={ OnCalendar=*-*-* 06:00:00 ; next_elapse=Mon 2024-05-27 06:00:00 CEST }
Aber erst nachdem der apt-daily.timer, der apt update ausführt, die Ausführung abgeschlossen hat:
systemctl show apt-daily-upgrade.timer --no-pager | grep ^After
After=apt-daily.timer time-set.target time-sync.target -.mount sysinit.target
Der systemd-Timer apt-daily-upgrade.timer löst den systemd-Service apt-daily-upgrade.service aus:
systemctl status apt-daily-upgrade.service
○ apt-daily-upgrade.service - Daily apt upgrade and clean activities
Loaded: loaded (/lib/systemd/system/apt-daily-upgrade.service; static)
Active: inactive (dead) since Sun 2024-05-26 06:27:17 CEST; 2h 1min ago
TriggeredBy: ● apt-daily-upgrade.timer
Docs: man:apt(8)
Main PID: 1615272 (code=exited, status=0/SUCCESS)
CPU: 1.666s
Der diesen Befehl ausführt:
systemctl show apt-daily-upgrade.service --no-pager|grep ^ExecStart=
ExecStart={ path=/usr/lib/apt/apt.systemd.daily ; argv[]=/usr/lib/apt/apt.systemd.daily install ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }
Zu erklären, was /usr/lib/apt/apt.systemd.daily genau macht, würde über das Ziel dieses Blogposts hinausgehen. Vereinfacht gesagt führt es standardmäßig apt upgrade aus.
Wie oben beschrieben, müssen wir, wenn wir das Intervall konfigurieren möchten, in dem apt update und apt upgrade (für Sicherheits-Upgrades) ausgeführt werden, zwei systemd-Timer anpassen: apt-daily.timer und apt-daily-upgrade.timer jeweils.
Dies sind die Standardeinstellungen:
systemctl show apt-daily.timer --no-pager | grep TimersCalendar
TimersCalendar={ OnCalendar=*-*-* 06,18:00:00 ; next_elapse=Sun 2024-05-26 18:00:00 CEST }
systemctl show apt-daily-upgrade.timer --no-pager | grep TimersCalendar
TimersCalendar={ OnCalendar=*-*-* 06:00:00 ; next_elapse=Mon 2024-05-27 06:00:00 CEST }
Wenn Sie einigermaßen paranoid sind, können Sie dies einmal pro Stunde ausführen, um apt-Sicherheits-Upgrades häufiger zu installieren. Für die meisten gängigen Systeme ist dies nicht erforderlich. Wenn Sie eine größere Anzahl von Diensten verwalten und Sie dieses Intervall erhöhen möchten, sollten Sie in Erwägung ziehen, Ihre eigene Instanz von apt-cacher-ng zu betreiben, der apt-Pakete für Sie zwischenspeichert , um die von Debian bereitgestellten apt-Repository-Server nicht zu belästigen. Viele Hosting-Anbieter stellen auch ihre eigenen apt-cacher-ng-Instanzen bereit (wie hetzner.de) - in diesem Fall könnte es in Ordnung sein.
Sie können das Intervall bearbeiten, in dem die apt-Timer laufen, mit dem folgenden Befehl:
systemctl edit apt-daily.timer
systemctl edit apt-daily-upgrade.timer
Dies öffnet einen Editor, der /etc/systemd/system/apt-daily.timer.d/override.conf und /etc/systemd/system/apt-daily-upgrade.timer.d/override.conf jeweils erstellt. Fügen Sie die folgende Konfiguration zwischen den dafür vorgesehenen Zeilen ein, die in der Datei beschrieben sind, die beide Befehle öffnen werden:
[Timer]
OnCalendar=hourly
RandomizedDelaySec=1m
Systemd-Konfigurationsdatei
Da wir die systemd-Konfiguration bearbeitet haben, müssen wir systemd selbst neu laden, damit die Änderungen wirksam werden:
systemctl daemon-reload
Überprüfen Sie, ob Ihre Änderungen wirksam wurden, mit den folgenden Befehlen - die LEFT-Zeit sollte weniger als eine Stunde betragen.
systemctl list-timers apt-daily*
NEXT LEFT LAST PASSED UNIT ACTIVATES
Sun 2024-05-26 12:00:17 CEST 20s left Sun 2024-05-26 11:28:52 CEST 31min ago apt-daily.timer apt-daily.service
Sun 2024-05-26 12:00:45 CEST 47s left Sun 2024-05-26 11:04:51 CEST 55min ago apt-daily-upgrade.timer apt-daily-upgrade.service
Wie im vorherigen Abschnitt erläutert, ruft der systemd-Service das BASH-Skript /usr/lib/apt/apt.systemd.daily auf. Dieses Skript hat eine Konfigurationsdatei unter /etc/apt/apt.conf.d/20auto-upgrades, die standardmäßig Folgendes enthält:
cat /etc/apt/apt.conf.d/20auto-upgrades
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
Die "1" steht für das Mindestintervall für die Ausführung in Tagen. Wir müssen das in etwas ändern, das weniger als eine Stunde ist, sonst wird das Skript /usr/lib/apt/apt.systemd.daily ausgeführt und erfolgreich beendet, tut aber tatsächlich nichts:
cat << EOF | tee /etc/apt/apt.conf.d/20auto-upgrades
APT::Periodic::Update-Package-Lists "30m";
APT::Periodic::Unattended-Upgrade "30m";
EOF
Die von unbeaufsichtigten Upgrades geschriebenen systemd-Journal-Logs sehen so aus:
journalctl _COMM=systemd -n 6
May 26 12:00:22 www.blunix.com systemd[1]: Starting apt-daily.service - Daily apt download activities...
May 26 12:00:23 www.blunix.com systemd[1]: apt-daily.service: Deactivated successfully.
May 26 12:00:23 www.blunix.com systemd[1]: Finished apt-daily.service - Daily apt download activities.
May 26 12:01:00 www.blunix.com systemd[1]: Starting apt-daily-upgrade.service - Daily apt upgrade and clean activities...
May 26 12:01:01 www.blunix.com systemd[1]: apt-daily-upgrade.service: Deactivated successfully.
May 26 12:01:01 www.blunix.com systemd[1]: Finished apt-daily-upgrade.service - Daily apt upgrade and clean activities.
Weitere Informationen finden Sie in diesem Stackoverflow-Thread sowie in der Debian-Dokumentation zu unattended-upgrades für eine ebenso verwirrende Erklärung ;-)
Auf einem regulären System besteht keine Notwendigkeit, das Intervall zu ändern, in dem unattended-upgrades läuft. Einmal am Tag ist in den meisten gängigen Fällen ausreichend.
Sie können konfigurieren, welche Pakete installiert werden sollen, indem Sie die Konfigurationsdatei /etc/apt/apt.conf.d/50unattended-upgrades verwenden:
Unattended-Upgrade::Origins-Pattern {
// "origin=Debian,codename=${distro_codename}-updates";
// "origin=Debian,codename=${distro_codename}-proposed-updates";
"origin=Debian,codename=${distro_codename},label=Debian";
"origin=Debian,codename=${distro_codename},label=Debian-Security";
"origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
}
Um diese Datei zu verstehen, schauen wir uns auch die Standard-/etc/apt/sources.list an:
deb http://deb.debian.org/debian/ bookworm main contrib non-free non-free-firmware
deb http://security.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware
deb http://deb.debian.org/debian/ bookworm-updates main contrib non-free non-free-firmware
origin=Debian bezieht sich auf den “Origin”-Schlüssel in der Releases-Datei des Repositorys:
curl -s http://deb.debian.org/debian/dists/bookworm/Release | grep Origin
Origin: Debian
curl -s https://security.debian.org/debian-security/dists/bookworm-security/Release | grep Origin
Origin: Debian
codename=${distro_codename}-updates bezieht sich auf den “Codename”-Schlüssel in der Releases-Datei des Repositorys:
curl -s http://deb.debian.org/debian/dists/bookworm/Release | grep Codename
Codename: bookworm
curl -s https://security.debian.org/debian-security/dists/bookworm-security/Release | grep Codename
Codename: bookworm-security
label=Debian bezieht sich auf den “Label”-Schlüssel in der Releases-Datei des Repositorys:
curl -s http://deb.debian.org/debian/dists/bookworm/Release | grep -i label
Label: Debian
curl -s https://security.debian.org/debian-security/dists/bookworm-security/Release | grep Label
Label: Debian-Security
Alle Pakete, die aus zusätzlich konfigurierten apt-Quellenlisten-Einträgen stammen, werden standardmäßig nicht aktualisiert, Sie müssen dies manuell konfigurieren.
Wenn Sie beispielsweise das sury PHP-Repository für Debian einrichten, das es Ihnen ermöglicht, mehrere spezifische PHP-Versionen und PHP-bezogene Pakete zu installieren, und Sie alle PHP-Pakete von sury automatisch aktualisieren möchten, können Sie die folgende Konfiguration verwenden.
Richten Sie zunächst das sury-Repository ein:
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | tee -a /etc/apt/sources.list.d/sury-php.list
wget -qO - https://packages.sury.org/php/apt.gpg | apt-key add -
apt update
Überprüfen Sie als Nächstes die Repository-Metadaten:
curl -s https://packages.sury.org/php/dists/$(lsb_release -sc)/Release
Origin: deb.sury.org
Suite: bookworm
Codename: bookworm
[...]
Mit diesen Informationen können Sie eine Zeile zu /etc/apt/apt.conf.d/50unattended-upgrades hinzufügen, um sie so aussehen zu lassen:
grep -v '//' /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Origins-Pattern {
"origin=Debian,codename=${distro_codename},label=Debian";
"origin=Debian,codename=${distro_codename},label=Debian-Security";
"origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
"origin=packages.sury.org,codename=${distro_codename}";
};
Um Ihre Konfiguration zu überprüfen, verwenden Sie den folgenden Befehl:
unattended-upgrade --dry-run --debug
Pakete von automatischen Upgrades ausschließen:
Unattended-Upgrade::Package-Blacklist {
"php"
}
Eine E-Mail an den Administrator senden, wenn es Probleme gibt:
Unattended-Upgrade::Mail "info@blunix.com";
Unattended-Upgrade::MailReport "only-on-error";
Das System automatisch neu starten, wenn apt die Datei /var/run/reboot-required erstellt, zum Beispiel nach der Installation einer neuen Kernel-Version:
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "02:00"
Beachten Sie, dass die Installation neuer Kernel nach einem Sicherheitspatch nutzlos ist, wenn Sie das Betriebssystem nicht neu starten. Sie können feststellen, ob ein Neustart erforderlich ist, indem Sie prüfen, ob diese Datei /var/run/reboot-required vorhanden ist - wenn sie fehlt, ist kein Neustart erforderlich. Die Datei /var/run/reboot-required.pkgs listet die Pakete auf, die diesen erforderlichen Neustart auslösen:
cat /var/run/reboot-required.pkgs
linux-image-6.1.0-20-amd64
linux-image-6.1.0-21-amd64
Die Ausgabe von apt in syslog protokollieren - oder systemd journald ab Debian 12:
Unattended-Upgrade::SyslogEnable "true";
Es gibt Dinge zu berücksichtigen und mehrere Einstellungen, die angewendet werden sollten, wenn neue Linux-Benutzer und -Gruppen sicher erstellt werden.
Ein gutes Beispiel für die Notwendigkeit, Linux-Benutzer und -Gruppen hinzuzufügen, ist, wenn mehrere Websites mit beispielsweise PHP betrieben werden. Jeder Website wird ihr eigener Linux-Benutzer und ihre eigene Gruppe zugewiesen.
Um einen Linux-Benutzer zu erstellen, der nicht für einen Menschen bestimmt ist, sondern stattdessen von einem Programm wie PHP-FPM verwendet werden soll, verwenden Sie den folgenden Befehl:
adduser\
--comment "www.example.com PHP website"\
--uid 5000\
--system\
--group www-example-com\
--home /var/www/www.example.com\
--shell /bin/false\
--disabled-password
info: Adding system user `www-example-com' (UID 5000) ...
info: Adding new group `www-example-com' (GID 5000) ...
info: Adding new user `www-example-com' (UID 5000) with group `www-example-com' ...
useradd warning: www-example-com's uid 5000 is greater than SYS_UID_MAX 999
info: Creating home directory `/var/www/www.example.com' ...
Wie Sie aus dem folgenden Befehl sehen können, wurde ein Benutzer namens www-example-com mit der Benutzer-ID und Gruppen-ID 5000 erstellt:
id www-example-com
uid=5000(www-example-com) gid=5000(www-example-com) groups=5000(www-example-com)
Zusammen mit seinem entsprechenden Home-Verzeichnis - beachten Sie, dass /var/www/ selbst www-data gehört, da auf dem System, das ich zum Schreiben dieses Blogposts verwende, ein Nginx-Webserver installiert ist ;)
sudo ls -lah /var/www/www.example.com
total 8.0K
drwxr-x--- 2 www-example-com www-example-com 4.0K Jun 3 05:12 .
drwxr-xr-x 4 www-data www-data 4.0K Jun 3 05:12 ..
Lassen Sie uns die verwendeten Argumente einzeln durchgehen:
–comment
Dies ist einfach eine für Menschen lesbare Erklärung, wofür der Benutzer verwendet wird. Es ist das fünfte Feld in /etc/passwd. Beispiele:
cut -d ':' -f 5 /etc/passwd
[...]
systemd Network Management
systemd Time Synchronization
DHCP Client Daemon,,,
systemd Resolver
usbmux daemon,,,
TPM software stack,,,
[...]
–uid
Setzt die Linux-Benutzer-ID sowie die Gruppen-ID, die eine numerische Darstellung für den Benutzer ist. Zum Beispiel hat der Benutzer root immer die UID 0:
grep ^root /etc/passwd | cut -d ':' -f 3
0
Wenn Sie eine größere Anzahl von Linux-Benutzern erstellen, zum Beispiel um mehrere Websites mit PHP zu hosten, möchten Sie etwas Ordnung in die verwendeten UIDs und GIDs bringen. Reguläre Benutzerkonten beginnen typischerweise bei UID 1000 aufwärts, wobei niedrigere Nummern (0-999) für System- und Administrationskonten reserviert sind (z.B. hat root die UID 0). Ähnlich folgen GIDs einer ähnlichen Konvention. Bei der Auswahl von UIDs und GIDs für neue Benutzer oder Gruppen ist es wichtig, Konflikte zu vermeiden, indem man sich an die Standardkonventionen hält: Auswahl von UIDs und GIDs über 1000 für reguläre Benutzer und Gruppen, es sei denn, es gibt einen spezifischen Bedarf, einen anderen Bereich zuzuweisen.
UIDs und GIDs unter 1000 sollten für über apt installierte Pakete reserviert sein, zum Beispiel hat www-data, das Nginx und Apache2 ausführt, immer UID und GID 33.
–system
Obwohl nicht streng erforderlich, bewirkt dies standardmäßig, dass der zu erstellende Benutzer kein Ablaufdatum hat (was sowieso die Standardeinstellung ist) und ihre UID unter 999 liegt (was wir mit –uid überschreiben). In unserem Fall bewirkt es auch, dass der /etc/shadow-Eintrag oben ein ! anstelle des Passworts enthält, was bedeutet, dass kein Passwort definiert ist (nicht dass es kein Passwort gibt, sondern dass kein Passwort funktionieren würde). Zusätzlich veranlasst dies adduser, den Benutzernamen des neuen Benutzers aus dem Argument --group www-example-com zu übernehmen.
–group www-example-com
Dieses Argument in Kombination mit dem --system-Argument weist den adduser-Befehl an, eine Gruppe mit demselben Namen wie der Benutzer zu erstellen, den wir erstellen möchten. Dieser Gruppe wird dieselbe Gruppen-ID wie die in --uid angegebene Benutzer-ID zugewiesen.
Beachten Sie, dass dieses Argument, obwohl es in diesem Fall etwas verwirrend ist, auch adduser den Namen des Benutzers mitteilt, den wir erstellen möchten. Üblicherweise ist der Name des zu erstellenden Benutzers das letzte Argument für adduser. In dieser Variante kann dies weggelassen werden.
Beachten Sie auch, dass der Benutzer- und Gruppenname, den wir hier als Argument angeben, Bindestriche (www-example-com) und keine Punkte (www.example.com) verwendet. Dies liegt daran, dass die Befehle adduser und addgroup die folgende Regex verwenden, um Benutzernamen zu überprüfen. Sie können diese Regex in der Datei /etc/adduser.conf anzeigen - eine Änderung wird nicht empfohlen und könnte Inkompatibilitätsprobleme mit anderen Tools und Programmen verursachen.
grep SYS_NAME_REGEX /etc/adduser.conf
#SYS_NAME_REGEX="^[A-Za-z_][-A-Za-z0-9_]*$?"
–home /var/www/www.example.com
Definiert und erstellt den Speicherort des Home-Verzeichnisses des Benutzers. Der Inhalt des Verzeichnisses wird von /etc/skel/ kopiert, danach werden alle Datei-Benutzer- und Gruppeneigentümerschaften unterhalb von /var/www/www.example.com auf den Benutzer und die Gruppe www-example-com geändert, oder genauer gesagt auf die Benutzer- und Gruppen-ID 5000.
–shell /bin/false
Definiert die Standard-Shell dieses Benutzers, zum Beispiel:
grep ^root /etc/passwd | cut -d ':' -f 7
/bin/bash
grep ^gdm /etc/passwd | cut -d ':' -f 7
/bin/false
Sie können dies auf /bin/false setzen, wenn Sie nicht beabsichtigen, diesen Benutzer für menschliche Interaktion zu verwenden, sondern nur um ein Programm auszuführen, zum Beispiel PHP-FPM. Sie können für diesen Benutzer immer noch eine Shell mit dem folgenden Befehl öffnen, der die definierte Standard-Shell überschreibt:
su -l www-data --shell=/bin/bash
–disabled-password
Setzt kein Passwort für den Benutzer. Beachten Sie, dass dies kein leeres Passwort setzt (Anmeldung ist ohne Passwort möglich), sondern KEIN Passwort (kein Passwort wird funktionieren). Dies bewirkt, dass ein * anstelle eines Passwort-Hashes in die Datei /etc/shadow geschrieben wird, falls der Benutzer ohne --system erstellt wurde, andernfalls schreibt es stattdessen ein !.
Beispiele:
sudo grep ^root /etc/shadow | cut -d ':' -f 2
*
sudo grep ^syslog /etc/shadow | cut -d ':' -f 2
!
Das Erstellen von Linux-Benutzern und -Gruppen für Menschen ist ähnlich wie das Erstellen von Linux-Benutzern und -Gruppen für Programme und Tools. Um einen Linux-Benutzer für einen Menschen hinzuzufügen, verwenden Sie den folgenden Befehl:
adduser\
--comment "john.doe@example.com"\
--uid 1010\
--home /home/john.doe-example-com\
--shell /bin/bash\
--disabled-password\
john-doe-example-com
info: Adding user `john-doe-example-com' ...
info: Adding new group `john-doe-example-com' (1010) ...
info: Adding new user `john-doe-example-com' (1010) with group `john-doe-example-com (1010)' ...
info: Creating home directory `/home/john.doe-example-com' ...
info: Copying files from `/etc/skel' ...
info: Adding new user `john-doe-example-com' to supplemental / extra groups `users' ...
info: Adding user `john-doe-example-com' to group `users' ...
Benutzer- und Gruppen-ID anzeigen:
id john-doe-example-com
uid=1010(john-doe-example-com) gid=1010(john-doe-example-com) groups=1010(john-doe-example-com),100(users)
Beachten Sie, dass standardmäßig neue Nicht-System-Benutzer automatisch zu einer Gruppe namens users hinzugefügt werden. Dies liegt daran, dass alle neu erstellten Nicht-System-Benutzer automatisch zu den in /etc/adduser.conf als USERS_GROUP definierten Gruppen hinzugefügt werden:
# Defines the groupname or GID of the group all newly-created
# non-system users are placed into.
# It is a configuration error to define both variables
# even if the values are consistent.
# Default: USERS_GID=undefined, USERS_GROUP=users
#USERS_GID=
#USERS_GROUP=users
Es gibt kein Kommandozeilenargument, um dies zu deaktivieren - es gibt ein Argument, um dies zu AKTIVIEREN, nämlich --add-extra-groups, aber dies ist sowieso die Standardeinstellung für adduser. Sie können dieses Verhalten deaktivieren, indem Sie Folgendes in /etc/adduser.conf definieren:
USERS_GID=-1
Wenn Sie jetzt einen neuen Benutzer erstellen, wird er nicht zu den zusätzlichen / extra Gruppen hinzugefügt:
sudo adduser --comment "john.doe@example.com" --uid 1010 --home /home/john-doe-example-com --shell /bin/bash --disabled-password john-doe-example-com
info: Adding user `john-doe-example-com' ...
info: Adding new group `john-doe-example-com' (1010) ...
info: Adding new user `john-doe-example-com' (1010) with group `john-doe-example-com (1010)' ...
info: Creating home directory `/home/john-doe-example-com' ...
info: Copying files from `/etc/skel' ...
Die Gruppen anzeigen, in denen sich der Benutzer befindet:
id john-doe-example-com
uid=1010(john-doe-example-com) gid=1010(john-doe-example-com) groups=1010(john-doe-example-com)
Linux-Benutzer für Menschen sowie Linux-Benutzer für Programme müssen oft über SSH erreichbar sein. Standardmäßig können alle Linux-Benutzer per SSH angemeldet werden. Es wird empfohlen, eine Gruppe einzurichten, um die Benutzer einzuschränken, die über SSH erreichbar sein können. Diese Gruppe wird dann in der sshd-Konfigurationsdatei definiert.
Fügen Sie eine oder, wenn es organisatorischen Zwecken dient, mehrere Linux-Gruppen so hinzu:
addgroup\
--gid 5000\
ssh_users
Fügen Sie dann Mitglieder zur Gruppe hinzu:
usermod -a -G ssh_users john-doe-example-com
Um zu überprüfen, dass der Benutzer jetzt in der Gruppe ist:
id john-doe-example-com
uid=1010(john-doe-example-com) gid=1010(john-doe-example-com) groups=1010(john-doe-example-com),5000(ssh_users)
Sie können jetzt die SSH-Daemon-Konfigurationsdatei so konfigurieren, dass nur Anmeldungen von Linux-Benutzern zugelassen werden, die sich in bestimmten Gruppen befinden:
cat << EOF | tee -a /etc/ssh/sshd_config.d/99-custom.conf
AllowGroups root admins
EOF
Überprüfen Sie die neue Konfiguration - beachten Sie, dass in der Ausgabe von sshd -T die Konfigurationsoptionen nicht CamelCase, sondern kleingeschrieben sind:
sshd -T | grep allowgroups
allowgroups root
allowgroups admins
Starten Sie den systemd-Service neu, um die Änderungen anzuwenden:
systemctl restart sshd.service
Um einen Linux-Benutzer zu einer bestehenden Gruppe hinzuzufügen, verwenden Sie den folgenden Befehl:
usermod -a -G existing-group existing-user
Obwohl oft nur eine Person ein Linux-System verwaltet oder nutzt, ist Debian Linux konstruktionsbedingt ein Mehrbenutzerbetriebssystem. Verschiedene Linux-Benutzer, wie www-data, werden verwendet, um Programme wie Apache2 oder Nginx nur mit den notwendigen Privilegien auszuführen, sollten aber nicht in der Lage sein, auf die privaten Dateien anderer Linux-Benutzer zuzugreifen.
Lassen Sie uns untersuchen, welche Schritte wir unternehmen können, um so viele Privilegien wie möglich von Linux-Benutzern zu entfernen, sodass, wenn ein Programm oder ein privater SSH-Schlüssel eines Linux-Benutzers kompromittiert wird, die Ausbreitung des Schadens minimiert werden kann und der Benutzer nicht Dateien ansehen, ändern oder ausführen kann, für die er nicht vorgesehen war.
Die umask, oder Benutzerdateierstellungsmaske, definiert, welche Standardberechtigungen alle Dateien und Verzeichnisse haben, die dieser Benutzer erstellt. Auf Debian Linux sind alle von einem Benutzer erstellten Dateien üblicherweise weltweit lesbar. Beispiel:
touch testfile.txt
ls -lah testfile.txt
-rw-rw-r-- 1 myuser myuser 0 May 27 23:04 testfile.txt
Wie Sie sehen können, sind die Berechtigungen für diese Datei -rw-rw-r--. Abhängig vom Verzeichnis, in dem sie sich befindet, können andere Benutzer das lesen. Dies ist natürlich nicht das, was wir wollen.
Eine vollständige Erklärung der umask würde den Rahmen dieses Blogposts sprengen. Wenn Sie das Wort umask zum ersten Mal hören, lesen Sie bitte dieses Tutorial auf geeksforgeeks.org über die Linux umask , das alles sehr gut erklärt, und kehren Sie dann zu diesem Blogpost zurück.
Sie können die aktuelle umask mit dem Befehl umask anzeigen:
umask
0002
Um eine neue umask für die aktuelle Shell zu definieren, verwenden Sie auch den Befehl umask:
umask 0007
touch testfile.txt
ls -lah testfile.txt
-rw-rw---- 1 myuser myuser 0 May 27 23:11 testfile.txt
Wie Sie sehen können, ist die jetzt erstellte Datei nicht mehr weltweit lesbar. Selbst wenn ein anderer Benutzer Zugriff auf das Verzeichnis hat, in dem sie gespeichert ist, und vorausgesetzt, der andere Benutzer ist nicht in der Gruppe myuser, ist er nicht in der Lage, die Datei zu lesen, darauf zu schreiben oder sie auszuführen.
Die umask-Einstellung muss für jede Shell definiert werden, die Sie verwenden - das ist üblicherweise /bin/bash oder /bin/zsh, kann aber je nach Ihren Vorlieben unterschiedlich sein. Jede dieser Shells bezieht eine oder mehrere Dotfiles, wenn Sie sie starten. Im Fall von /bin/bash wäre das ~/.bashrc:
echo umask 027 | tee -a ~/.bashrc
Öffnen Sie nun eine neue Bash, indem Sie einfach bash ausführen:
bash
Und erstellen Sie eine neue Datei:
touch testfile.txt
ls -lha testfile.txt
-rw-r----- 1 user user 0 May 27 23:36 testfile.txt
Sie können die Standard-Shell bestimmen, die geöffnet wird, wenn sich ein Benutzer per SSH anmeldet, mit dem folgenden Befehl:
grep ^root /etc/passwd | cut -d ':' -f 7
/bin/bash
Beim Erstellen neuer Benutzer muss auch die umask-Einstellung berücksichtigt werden, sodass das neue Home-Verzeichnis und alle darin enthaltenen Dateien sofort die richtigen Berechtigungen haben. Die Datei /etc/login.defs hat eine Einstellung, die die umask definiert, mit der das neue Home-Verzeichnis für Benutzer erstellt wird. Standardmäßig ist dies:
grep ^UMASK /etc/login.defs
UMASK 022
was ein /home/-Verzeichnis so erstellt:
ls -lha /home/
total 16K
drwxr-xr-x 4 root root 4.0K May 1 19:44 .
drwxr-xr-x 23 root root 4.0K May 1 19:22 ..
drwxr-x--- 54 user user 4.0K May 27 23:42 user
Und kopiert die Dateien aus /etc/skel, die in /etc/skel die folgenden Berechtigungen haben:
ls -lha /etc/skel/
total 28K
drwxr-xr-x 2 root root 4.0K Apr 24 06:47 .
drwxr-xr-x 158 root root 12K May 27 23:29 ..
-rw-r--r-- 1 root root 220 Mar 31 04:41 .bash_logout
-rw-r--r-- 1 root root 3.7K Mar 31 04:41 .bashrc
-rw-r--r-- 1 root root 807 Mar 31 04:41 .profile
mit den folgenden Berechtigungen:
ls -lha ~/.bash_logout ~/.bashrc ~/.profile
-rw-r----- 1 user user 220 May 1 19:29 .bash_logout
-rw-r----- 1 user user 4.1K May 27 23:36 .bashrc
-rw-r----- 1 user user 664 May 27 23:34 .profile
Dies ist im Allgemeinen sicher genug. Sie können die umask in /etc/login.defs auf 027 setzen, wenn Sie nicht möchten, dass die Dateien gruppenlesbar sind.
Wenn Sie möchten, dass neu erstellte Benutzer automatisch umask 027 in ihrer ~/.bashrc-Datei haben, können Sie dies tun, indem Sie die Datei /etc/skel/.bashrc vor dem Erstellen des Benutzers bearbeiten:
echo umask 027 | tee -a /etc/skel/.bashrc
So ziemlich alle Programme, die Sie als Daemons ausführen, wie PHP-FPM, werden über systemd auf modernen Debian Linux-Systemen verwaltet. Wenn diese Programme, in diesem Beispiel PHP-FPM, Dateien generieren, möchten Sie höchstwahrscheinlich, dass diese Dateien nicht weltweit lesbar sind. Zum Beispiel könnte Ihre Anwendung .pdf-Dateien generieren oder Benutzer können Bilder hochladen - diese Dateien sollten nicht mit weltweit lesbaren Berechtigungen erstellt werden. Dafür müssen Sie eine umask-Einstellung in der systemd-Service-Datei definieren, die das betreffende Programm ausführt.
Zum Beispiel, um eine umask für einen von einer systemd-Service-Unit verwalteten PHP-FPM-Prozess zu setzen, verwenden Sie den folgenden Befehl:
systemctl edit php8.3-fpm.service
Fügen Sie diese Konfiguration hinzu:
[Service]
UMask=0007
Systemd-Konfigurationsdatei
Um die Änderungen anzuwenden, laden Sie systemd neu und starten Sie den systemd-Service neu:
systemctl daemon-reload
systemctl restart php8.3-fpm.service
Der Befehl sudo ist so konzipiert, dass er feingranulierten Zugriff auf bestimmte Befehle ermöglicht.
Die häufigste Verwendung des Befehls ist oft sudo -i oder sudo su, was jedoch nicht wirklich der beabsichtigteste Anwendungsfall für den sudo-Befehl ist. Wenn Sie einem Benutzer passwortlose sudo-Berechtigungen gewähren, gibt es aus Sicherheitssicht keinen wirklichen Unterschied dazu, den öffentlichen SSH-Schlüssel des Benutzers direkt zu /root/.ssh/authorized_keys hinzuzufügen. Der einzige Vorteil ist, dass Sie in den Logs sehen können, welcher Benutzer sich per SSH angemeldet und dann sudo verwendet hat, um seine Berechtigungen auf root zu erhöhen. Wenn Sie Root-Berechtigungen auf Servern an Menschen gewähren möchten, ist dies eine gute Möglichkeit, den Überblick zu behalten, wer sich wann angemeldet hat.
Sie können einem Benutzer passwortloses sudo geben, indem Sie dies in /etc/sudoers so definieren:
username ALL=(ALL) NOPASSWD:ALL
Oder für eine Linux-Gruppe so - beachten Sie das %-Zeichen vor dem Namen der Linux-Gruppe, das angibt, dass es sich um einen Gruppennamen und nicht um einen Benutzernamen handelt:
%groupname ALL=(ALL) NOPASSWD:ALL
Um anzuzeigen, welcher Benutzer sich per SSH angemeldet hat:
journalctl _COMM=sshd -f
Jun 04 14:19:29 www.blunix.com sshd[1685548]: Accepted publickey for john-doe from 1.2.3.4 port 47314 ssh2: ED25519 SHA256:xT2+lV8yBBm7c/c+o29YGNsHFTUvsW+/j5uaLzIKg+M
Jun 04 14:19:29 www.blunix.com sshd[1685548]: pam_unix(sshd:session): session opened for user john-doe(uid=5010) by (uid=0)
Jun 04 14:19:28 www.blunix.com sshd[1684952]: pam_unix(sshd:session): session closed for user john-doe
Sie können ein Passwort verwenden, um die sudo-Rechteerweiterung mit einer Konfiguration in /etc/sudoers so zu schützen:
username ALL=(ALL:ALL) ALL
Oder für eine Gruppe:
%groupname ALL=(ALL:ALL) ALL
Wenn Sie einen Linux-Benutzer wie oben beschrieben erstellt haben, haben sie kein in /etc/shadow definiertes Passwort und dies wird nicht funktionieren. Sie können ein Passwort für einen Linux-Benutzer so setzen:
passwd john-doe
New password:
Retype new password:
passwd: password updated successfully
Der Benutzer muss sein Linux-Benutzerpasswort das erste Mal eingeben, bevor er sudo verwendet, danach wird es standardmäßig für 15 Minuten zwischengespeichert. Weitere Informationen finden Sie unter man sudoers und suchen Sie nach “timestamp_timeout”, Zitat:
“Number of minutes that can elapse before sudo will ask for a password again. The timeout may include a fractional component if minute granularity is insufficient, for example 2.5. The default is 15. Set this to 0 to always prompt for a password. If set to a value less than 0 the users time stamp will not expire until the system is rebooted. This can be used to allow users to create or delete their own time stamps via sudo -v and sudo -k respectively.”
Dies schützt Sie primär vor Evil-Maid-Angriffen , bei denen Sie Ihre Workstation unbeaufsichtigt lassen und sie beim Verlassen eingeschaltet ist und der Bildschirm nicht durch einen Bildschirmschoner passwortgeschützt ist.
Wenn Ihr Ziel ist, Root-Zugriff auf Server an Menschen zu gewähren, macht es nicht viel Sinn, ein Passwort für sudo zu verwenden. Der Benutzer ist verpflichtet, seinen privaten SSH-Schlüssel sicher zu speichern. Wenn der private Schlüssel kompromittiert wird, liegt dies höchstwahrscheinlich daran, dass seine Workstation kompromittiert wurde, was bedeutet, dass die in seinem Passwortspeicher gespeicherten Passwörter höchstwahrscheinlich ebenfalls kompromittiert sind oder, wenn sich der Benutzer sein Passwort merkt, anstatt es in einem Passwortspeicher zu speichern, es mit einem Keylogger entdeckt wird.
Verwenden Sie Qubes OS für Ihre Workstation, wenn Sie Gründe haben, paranoid zu sein.
Es macht oft Sinn, Linux-Benutzern nur Zugriff auf bestimmte Befehle zu gewähren, die erhöhte Berechtigungen erfordern. Hier sind zehn Beispiele für die Konfiguration in /etc/sudoers. Beachten Sie die Verwendung absoluter Pfade. Um den absoluten Pfad für einen Befehl zu bestimmen, verwenden Sie which so:
which systemctl
/usr/bin/systemctl
Einem Benutzer die Berechtigung erteilen, den Apache-Server neu zu starten:
john-doe ALL=(ALL) NOPASSWD: /bin/systemctl restart apache2
Einem Benutzer erlauben, die Systempakete zu aktualisieren:
john-doe ALL=(ALL) NOPASSWD: /usr/bin/apt-get update, /usr/bin/apt-get upgrade
Einem Benutzer erlauben, eine bestimmte Datei mit nano zu bearbeiten:
john-doe ALL=(ALL) NOPASSWD: /bin/nano /etc/hosts
Einem Benutzer erlauben, den Netzwerkdienst neu zu starten:
john-doe ALL=(ALL) NOPASSWD: /bin/systemctl restart networking
Einem Benutzer erlauben, das System neu zu starten:
john-doe ALL=(ALL) NOPASSWD: /bin/systemctl reboot
Einem Benutzer erlauben, eine bestimmte Partition zu mounten:
john-doe ALL=(ALL) NOPASSWD: /bin/mount /dev/sdb1 /mnt/backup
Einem Benutzer erlauben, ein bestimmtes Skript auszuführen:
john-doe ALL=(ALL) NOPASSWD: /home/jane-doe/scripts/backup.sh
Einem Benutzer die Berechtigung erteilen, die Eigentümerschaft eines bestimmten Verzeichnisses zu ändern:
john-doe ALL=(ALL) NOPASSWD: /bin/chown -R www-data:www-data /var/www/html
Einem Benutzer erlauben, einen Docker-Container zu starten und zu stoppen:
john-doe ALL=(ALL) NOPASSWD: /usr/bin/docker start mycontainer, /usr/bin/docker stop mycontainer
Einem Benutzer erlauben, eine bestimmte Logdatei zu verfolgen:
john-doe ALL=(ALL) NOPASSWD: /usr/bin/tail -f /var/log/nginx/access.log
Wenn Sie einen neuen Cloud-Server (oder physischen Server) einrichten, SSH-Schlüsselpaar-Authentifizierung für den Root-Benutzer einrichten und Passwortauthentifizierung in der sshd-Konfigurationsdatei deaktivieren und unbeaufsichtigte Upgrades sowie Neustarts konfigurieren, können Sie diesen Server sicher vom Internet aus mit einer öffentlichen IP-Adresse zugänglich machen. Bots werden versuchen zu testen, ob sie sich per SSH mit schwachen Passwörtern anmelden können, aber das ist irrelevant und kann als “Regen, der auf die Windschutzscheibe Ihres Autos trifft” betrachtet werden. Es ist normal und kein Sicherheitsrisiko, das auf irgendeine Weise für Server adressiert werden muss, die keine Hochrisikoanwendungen ausführen.
Die interessante Frage ist, was Sie als Nächstes mit diesem Server machen, nachdem Sie die oben beschriebenen Sicherheitsgrundlagen konfiguriert haben.
Hier ist ein sehr häufiges Beispiel für Fälle, in denen eine Firewall erforderlich ist. Ein Administrator installiert einen mariadb-server und konfiguriert ihn so, dass er auf 0.0.0.0 lauscht:
apt install mariadb-server
sed -i 's/^bind-address.*/bind-address = 0.0.0.0/g' /etc/mysql/mariadb.conf.d/50-server.cnf
systemctl restart mariadb.service
Der mariadb-server lauscht jetzt auf 0.0.0.0:
lsof -i :3306
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mariadbd 1684019 mysql 21u IPv4 28054081 0t0 TCP *:mysql (LISTEN)
Was bedeutet, dass darauf vom Internet aus zugegriffen werden kann:
telnet www.blunix.com 3306
Trying 5.6.7.8...
Connected to www.blunix.com.
Escape character is '^]'.
HHost '1.2.3.4' is not allowed to connect to this MariaDB serverConnection closed by foreign host.
In diesem Beispiel sind im MariaDB-Server keine GRANTs definiert, um jemandem den Remote-Zugriff zu ermöglichen. Es besteht jedoch keine Notwendigkeit, dem Code von MariaDB zu vertrauen, dies zu filtern. Nur IP-Adressen, die auf MariaDB zugreifen sollen, sollten auf MariaDB zugreifen dürfen.
In einigen Fällen kann es erforderlich sein, dass MariaDB so konfiguriert ist, dass es auf mehrere IP-Adressen oder Netzwerkschnittstellen lauscht. Leider ist es nicht möglich, dies zu konfigurieren . Daher ist die einzige Option in diesem Fall, MariaDB so zu konfigurieren, dass es auf 0.0.0.0 lauscht, und eine Firewall für eingehende Verbindungen zu verwenden, um zu filtern, wer darauf zugreifen darf und wer nicht.
Beachten Sie, dass Firewalls Konfigurationsfehler haben können und möglicherweise nicht starten, zum Beispiel nach Neustarts. Sie sollten regelmäßige Portscans mit Ihrem Überwachungssystem durchführen, um zu überprüfen, ob Ihre Firewall wie erwartet funktioniert.
Darüber hinaus machen Menschen (Administratoren) Fehler, und ein unerfahrener Administrator könnte versehentlich einen Dienst so konfigurieren, dass er auf 0.0.0.0 lauscht. Wenn Ihr MySQL-Server auf Port 3306 (mysql) aus dem öffentlichen Internet erreichbar ist, werden automatisierte Bots dies, ähnlich wie bei Port 22, bald durch Portscans herausfinden und beginnen, Zugriff zu erlangen oder den öffentlich erreichbaren Dienst auszunutzen. SSH öffentlich erreichbar zu haben ist (irgendwie) in Ordnung und oft erforderlich. Bei MySQL oder allem anderen außer einem Webserver ist das höchstwahrscheinlich nicht in Ordnung.
Deshalb existieren Firewalls zum Filtern eingehender Verbindungen.
Der beste Weg, Ihre Konfiguration zu überprüfen, besteht darin, einen Portscan mit Tools wie nmap durchzuführen, um zu sehen, welche Ports für die Öffentlichkeit geöffnet sind. Beachten Sie, dass das Scannen aller Ports von 0-65535 ziemlich zeitaufwendig ist und hier nur zu Illustrationszwecken dient. Für eine gute und kurze Einführung in nmap lesen Sie diesen Artikel auf linuxhandbook.com
.
nmap -p 0-65535 scanme.nmap.org
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-06-04 11:03 EDT
Nmap scan report for scanme.nmap.org (45.33.32.156)
Host is up (0.24s latency).
Other addresses for scanme.nmap.org (not scanned): 2600:3c01::f03c:91ff:fe18:bb2f
Not shown: 65524 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
25/tcp filtered smtp
53/tcp open domain
80/tcp open http
137/tcp filtered netbios-ns
138/tcp filtered netbios-dgm
139/tcp filtered netbios-ssn
445/tcp filtered microsoft-ds
1900/tcp filtered upnp
2869/tcp filtered icslap
9929/tcp open nping-echo
31337/tcp open Elite
Nmap done: 1 IP address (1 host up) scanned in 1292.51 seconds
Obwohl dies den Rahmen dieses Blogposts sprengt, verdient der Schwachstellenscanner greenbone eine ehrenvolle Erwähnung. Er ermöglicht es Ihnen, Ihre Anwendungen (automatisch) auf bekannte Schwachstellen zu scannen.
Es gibt zwei Gründe, eine Firewall zum Filtern des ausgehenden Traffics zu konfigurieren - um Traffic zu bestimmten Servern zu blockieren oder um Traffic zu allen außer einer Liste bestimmter Server zu blockieren und alle anderen (blockierten) Versuche zu protokollieren, um Überwachungswarnungen in der Annahme auszulösen, dass der Server kompromittiert wurde und eine Malware versucht, nach Hause zu telefonieren.
Der erste Grund zum Filtern des ausgehenden Traffics kann sein, dass Sie nicht aller auf einer Workstation oder einem Server installierten Software vertrauen, dass sie keine Kontakte zu Zielen aufnimmt, an die Sie keine Daten senden möchten. Ein häufiges Beispiel wäre, alle Facebook-Dienste auf Ihrer Workstation zu blockieren. Dies wird üblicherweise sowohl durch eine Firewall als auch durch eine Blacklist für DNS durchgeführt.
Wenn Sie Facebook-Dienste auf Ihrer Workstation blockieren möchten, können Sie Listen auf Github finden, die alle mit Facebook verbundenen Server sammeln, und ein Tool wie dnscrypt-proxy verwenden, um alle DNS-Anfragen für diese Domains zu blockieren. Auf diese Weise kann Ihr Browser, wenn er eine Website öffnet, die Tracking-Informationen an Facebook senden möchte, diese Domains nicht auflösen und daher nicht wissen, wohin diese Daten gesendet werden sollen. Dies ist das, was die meisten VPN-Anbieter tun, wenn Sie in den Einstellungen des VPN-Clients “Tracking blockieren” auswählen - sie geben Ihnen einen DNS-Resolver, der diese Domains blockiert.
Eine andere Möglichkeit, dies zu tun, besteht darin, all diese Domains selbst aufzulösen, um eine Liste von IPs zu erhalten, oder eine Liste von IPs direkt aus Quellen wie Github herunterzuladen. Sie können dann Ihre Firewall so konfigurieren, dass alle Verbindungen zu diesen IPs blockiert werden.
Wenn Sie genau wissen, mit welchen Diensten Ihr Server sich verbinden muss, um ordnungsgemäß zu funktionieren, können Sie diese whitelisten. Das ist, was wir bei Blunix für unsere Hosting-Kunden tun. Es hat den Vorteil, dass, wenn bösartige Software installiert wird und versucht, sich mit einem Command-and-Control-Server oder Ähnlichem zu verbinden, dies von der Firewall blockiert und protokolliert wird, was eine Warnung in einem SIEM (Security Information & Event Management) Überwachungssystem auslöst.
Für einen regulären Debian-Server müssen Sie mindestens die folgenden ausgehenden Verbindungen zu bestimmten IPs whitelisten, damit er ordnungsgemäß funktioniert:
Abhängig von den Anwendungen, die Sie auf Ihrem Server ausführen, zum Beispiel wenn Sie eine komplexere Webanwendung haben, die Drittanbieter-APIs aufruft, um zu funktionieren, wird die Liste länger.
Ein häufiger Fehler ist, IPv6 zu vergessen. Viele Cloud-Anbieter weisen jetzt standardmäßig IPv6-Adressen zu, jedoch behandelt insbesondere iptables nur IPv4-Traffic, und der ip6tables-Befehl behandelt IPv6-Traffic.
Mit neueren Debian-Versionen ist IPtables zugunsten von NFtables veraltet. Die Erklärung von nftables würde den Rahmen dieses Blogposts sprengen und es gibt bereits mehrere sehr gute Tutorials im Internet.
Es ist im Allgemeinen eine gute Idee, ein Wrapper-Programm zu wählen, das den größten Teil der Arbeit für Sie erledigt, wenn Sie eine Firewall konfigurieren, wie das Bereitstellen von Vorlagen zum “Eingehende HTTP(S) erlauben” sowie das Konfigurieren von Zonen und so weiter. Für iptables haben wir (blunix) viele Jahre lang shorewall verwendet und waren sehr zufrieden damit. Leider hat shorewall keine Pläne zur Migration auf nftables. Zum Zeitpunkt dieses Schreibens habe ich keinen zufriedenstellenden Wrapper für nftables gefunden, daher empfehle ich, nftables-Regeln einfach “von Hand” zu schreiben.
Wenn Sie eine einfach zu konfigurierende Firewall möchten, würde ich UFW - die unkomplizierte Firewall empfehlen, die ein Firewall-Wrapper ist, der sowohl nftables als auch das veraltete iptables als Backend verwenden kann.
Für die Verwendung fortgeschrittener Funktionen kommen Sie nicht darum herum, nftables selbst zu lernen. Es ist jedoch nicht allzu kompliziert, und Sie sollten es versuchen.
Wenn Sie ein Tool einrichten, das nur firmenintern verwendet werden soll, wie GitLab, einen Online-Passwortspeicher, ein Wiki oder ein Ticketmanagement-Tool, gibt es keinen Grund, dass jeder auf dem Planeten auf die Anmeldeseite dieses Tools zugreifen kann.
Der richtige Ansatz hierfür ist, eine firmeneigene VPN-Lösung wie Wireguard zu haben. Alle Geräte Ihrer Mitarbeiter verbinden sich dann mit diesem Wireguard, das entweder mit einem internen Wireguard-Mesh-Netzwerk verbindet, das sich mit all Ihren firmeninternen Servern verbindet, oder als Standard-Gateway für Traffic zum gesamten Internet oder zu bestimmten IPs (wie Ihren internen Servern) dient. Auf diese Weise können Sie die Firewall auf Ihren intern genutzten Servern so einrichten, dass nur Verbindungen auf TCP-Port 443 (HTTPS) von der IP Ihres VPN-Servers akzeptiert werden.
Es ist immer besser, eingehende Verbindungen auf bestimmte IPs zu beschränken, anstatt eine supersichere Anmeldeseite für Ihre Anwendung zu programmieren oder der Anmeldeseite von Open-Source-Anwendungen wie GitLab zu vertrauen.
Das Betreiben “einer Website” ist höchstwahrscheinlich der häufigste Anwendungsfall für die meisten Debian Linux-Server, wobei Nginx und Apache2 höchstwahrscheinlich die am häufigsten verwendeten Webserver dafür sind.
Sowohl Nginx als auch Apache sind standardmäßig einigermaßen sicher konfiguriert und erfordern nur eine geringe Menge an zusätzlicher Konfiguration für zusätzliche Sicherheit.
Sie sollten sicherstellen, dass Ihr Webserver oder die zugrunde liegende Anwendung, die er bereitstellt, keine intern verwendeten Header durchsickern lässt, die für den Endbenutzer kein legitimes Interesse darstellen. Ein häufiges Beispiel hierfür ist der Header x-powered-by, der üblicherweise von PHP gesetzt wird:
curl -I -L https://www.example.com
[...]
x-powered-by: PHP/8.2.1
[...]
Die Offenlegung dieser Informationen an Endbenutzer dient keinem Zweck und hilft nur Hackern, zusätzliche Informationen über Ihr System zu erlangen. Viele Tools und Programme geben standardmäßig Versionsinformationen in Response-Headern preis. Verwenden Sie curl -I -L https://www.your-website.com, um danach zu suchen, und verwenden Sie dann Ihre bevorzugte Suchmaschine, um zu bestimmen, wie Sie diese deaktivieren können.
Bei der Konfiguration von SSL für Nginx oder Apache sollten Sie Zertifikate von Letsencrypt verwenden und dann den Mozilla SSL Configuration Generator verwenden, um sichere SSL-Konfigurations-Snippets für Ihren Webserver zu generieren. Sie benötigen dafür die folgenden Informationen:
OpenSSL-Version
openssl version
OpenSSL 3.0.11 19 Sep 2023 (Library: OpenSSL 3.0.11 19 Sep 2023)
Nginx-Version
nginx -v
nginx version: nginx/1.22.1
Apache2-Version
apache2ctl -v
Server version: Apache/2.4.59 (Debian)
Server built: 2024-04-05T12:08:04
Dies ist nur relevant, wenn Sie einen physischen Server verwalten. Für Cloud-Server ist Ihr IaaS-Anbieter dafür verantwortlich, die physischen Server auf dem neuesten Stand zu halten, auf denen die virtuellen Cloud-Maschinen laufen.
Auf physischen Debian Linux-Servern sollten Sie das Paket fwupd installieren und konfigurieren. Von der Projekt-Website von fwupd
: Es “macht das Aktualisieren von Firmware auf Linux automatisch, sicher und zuverlässig.” Weitere Einzelheiten zur Verwendung finden Sie in der Dokumentation zur grundlegenden Verwendung
.
fwupd wird regelmäßig von einem systemd-Timer ausgeführt, der täglich um 6 Uhr und 18 Uhr ausgeführt wird:
systemctl cat fwupd-refresh.timer
# /lib/systemd/system/fwupd-refresh.timer
[Unit]
Description=Refresh fwupd metadata regularly
ConditionVirtualization=!container
[Timer]
OnCalendar=*-*-* 6,18:00
RandomizedDelaySec=12h
Persistent=true
[Install]
WantedBy=timers.target
Dieser Blogpost wurde entwickelt, um grundlegende Sicherheitsmaßnahmen zu behandeln, die Sie auf jeden Debian Linux-Server anwenden sollten, den Sie betreiben. Es ist im Allgemeinen nicht erforderlich, weiter zu gehen, es sei denn, Sie sind technisch neugierig oder betreiben einen Hochrisikodienst.
Hier sind einige Dinge, die Sie zusätzlich zu den oben beschriebenen grundlegenden Sicherheitsmaßnahmen tun können.
Suchen Sie
Linux Notfallunterstützung,
Linux-Beratung für Projekte,
Linux Managed Hosting,
Qubes OS Beratung und Support oder
Online- und Vor-Ort-Schulungen?