Linux - SSH
SSH Authentifizierung
Debian SSH: Passwort für normale User, SSH-Key für root
Diese Anleitung zeigt, wie du OpenSSH so konfigurierst, dass sich normale Benutzer mit Passwort anmelden können, während sich root ausschließlich mit SSH-Schlüssel (Zertifikat/Key) anmelden darf.
Voraussetzungen
- Debian/Ubuntu mit
openssh-server - Zugriff als root (oder per
sudo) - Ein funktionierender SSH-Key für root (z. B. Ed25519)
1) SSH-Key für root vorbereiten
- Auf deinem Admin-Client (nicht auf dem Server) einen Key erzeugen (falls noch nicht vorhanden):
ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519ssh-keygen -t ed25519 -a 256 -f ~/.ssh/id_ed25519 -C "jj@little-snitch" - Öffentlichen Schlüssel auf den Server in die root-Authorized Keys kopieren:
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@server.example.comAlternativ manuell:
cat ~/.ssh/id_ed25519.pub | ssh root@server.example.com 'mkdir -p /root/.ssh && chmod 700 /root/.ssh && cat >> /root/.ssh/authorized_keys && chmod 600 /root/.ssh/authorized_keys'
2) Bestehende SSH-Konfiguration sichern
cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config.backup.$(date +%F-%H%M%S)
3) Kerneinstellungen
Die zentrale Idee:
PermitRootLogin prohibit-password→ verbietet root-Passwortlogin, erlaubt aber Schlüssel.PasswordAuthentication yes→ Passwortlogin global erlaubt (wird in Match-Blöcken eingeschränkt).Match User root→ für root nur SSH-Key.Match User <username>→ optional: für bestimmte User Verhalten festlegen.
4) Beispiel: vollständige /etc/ssh/sshd_config
Folgende Konfiguration entspricht deinem Beispiel und erzwingt für root Key-Login, lässt für master771 sowohl Passwort als auch Key zu. Andere Benutzer folgen den globalen Einstellungen (Passwort erlaubt, Key erlaubt):
root@mqtt:~# cat /etc/ssh/sshd_config
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/local/bin:/usr/bin:/bin:/usr/games
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.
Include /etc/ssh/sshd_config.d/*.conf
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key
# Ciphers and keying
#RekeyLimit default none
# Logging
#SyslogFacility AUTH
#LogLevel INFO
# Authentication:
#LoginGraceTime 2m
#PermitRootLogin prohibit-password
PermitRootLogin prohibit-password
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
#PubkeyAuthentication yes
PubkeyAuthentication yes
# Expect .ssh/authorized_keys2 to be disregarded by default in future.
#AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
# To disable tunneled clear text passwords, change to "no" here!
#PasswordAuthentication yes
PasswordAuthentication yes
#PermitEmptyPasswords no
# Change to "yes" to enable keyboard-interactive authentication. Depending on
# the system's configuration, this may involve passwords, challenge-response,
# one-time passwords or some combination of these and other methods.
# Beware issues with some PAM modules and threads.
KbdInteractiveAuthentication no
# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the KbdInteractiveAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via KbdInteractiveAuthentication may bypass
# the setting of "PermitRootLogin prohibit-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and KbdInteractiveAuthentication to 'no'.
UsePAM yes
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
PrintMotd no
#PrintLastLog yes
#TCPKeepAlive yes
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
# no default banner path
#Banner none
# Allow client to pass locale and color environment variables
AcceptEnv LANG LC_* COLORTERM NO_COLOR
# override default of no subsystems
Subsystem sftp /usr/lib/openssh/sftp-server
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs server
Match User root
PasswordAuthentication no
PubkeyAuthentication yes
Match User master771
PasswordAuthentication yes
PubkeyAuthentication yes
5) Syntax prüfen und SSH neu laden
- Syntaxcheck:
sshd -tWenn keine Ausgabe erfolgt, ist die Syntax OK.
- Dienst neu laden (ohne laufende Sessions zu kappen):
systemctl reload sshFalls
reloadnicht verfügbar, dann:systemctl restart ssh
6) Sicher testen (zweite Session!)
- Neue Terminal-Session öffnen, bestehende Sitzung nicht schließen.
- Test root per Key:
ssh -i ~/.ssh/id_ed25519 root@server.example.com - Test root per Passwort (soll scheitern):
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no root@server.example.com - Test normaler Benutzer per Passwort (soll funktionieren):
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no master771@server.example.com
Optionen & Varianten
- Nur Passwort für bestimmte Benutzer erzwingen:
Match User alice,bob PasswordAuthentication yes PubkeyAuthentication no - Key-Login global erlauben, aber root-Passwort strikt verbieten: Bereits abgedeckt durch
PermitRootLogin prohibit-passwordund denMatch User root-Block. - Brute-Force eindämmen:
fail2banverwenden undMaxAuthTriessenken (z. B.MaxAuthTries 3).
Rollback
Falls etwas schiefgeht, via Konsole (z. B. VM-Konsole) die Sicherung zurückspielen:
mv /etc/ssh/sshd_config.backup.YYYY-MM-DD-HHMMSS /etc/ssh/sshd_config
systemctl restart ssh
Hinweise zur Sicherheit
- Lege für alle Benutzer starke Passwörter fest oder nutze ggf. 2FA (z. B.
google-authenticator) zusätzlich. - Bevorzuge Ed25519-Schlüssel. RSA nur mit ausreichend großer Länge (min. 3072 Bit).
- Überlege, den SSH-Port zu ändern und/oder Port-Knocking bzw. VPN vorzuschalten.
- Halte
openssh-serveraktuell (apt update && apt upgrade).
Stand: aktualisiere diese Seite, wenn sich deine Policy ändert oder neue Benutzer hinzukommen.
SSH - only key
Ziel: Auf dem Client ein Ed25519-Schlüsselpaar mit Passphrase erzeugen und in ~/.ssh/config hinterlegen. Auf dem Server Logins für root und jj auf Public-Key-Authentifizierung beschränken.
Platzhalter
SERVER_IP: IP oder FQDN des Zielservers$Dieser_Client: Kommentar (z. B. Hostname des Clients)little-ghost: frei wählbarer Schlüsselnamens-Ordner
1) Client: SSH-Key mit Passphrase erzeugen
Befehl (kopierbar)
ssh-keygen \
-t ed25519 \
-a 1024 \
-o \
-Z aes256-ctr \
-C "$Dieser_Client" \
-f "/root/.ssh/$org/$device_name/id_ed25519"
Beispielausgabe
Generating public/private ed25519 key pair.
Enter passphrase for "/root/.ssh/JSc/little-ghost/id_ed25519" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/JSc/little-ghost/id_ed25519
Your public key has been saved in /root/.ssh/JSc/little-ghost/id_ed25519.pub
The key fingerprint is:
SHA256:**************************** little-ghost
The key's randomart image is:
+--[ED25519 256]--+
|*****************|
|*****************|
|*****************|
|*****************|
|*****************|
|*****************|
|*****************|
|*****************|
|*****************|
+----[SHA256]-----+
Optional: Rechte setzen
chmod 700 /root/.ssh /root/.ssh/JSc /root/.ssh/JSc/little-ghost
chmod 600 /root/.ssh/JSc/little-ghost/id_ed25519
chmod 644 /root/.ssh/JSc/little-ghost/id_ed25519.pub
Beispielausgabe
# (keine Ausgabe bei Erfolg)
# Kontrolle:
ls -ld /root/.ssh /root/.ssh/JSc /root/.ssh/JSc/little-ghost
ls -l /root/.ssh/JSc/little-ghost/
2) Client: SSH-Konfiguration für Zielhost
In /root/.ssh/config eintragen/ergänzen:
Dateiinhalt (kopierbar)
Host SERVER_IP
HostName SERVER_IP
IdentitiesOnly yes
IdentityFile /root/.ssh/JSc/little-ghost/id_ed25519
ForwardAgent no
ForwardX11 no
StrictHostKeyChecking ask
UserKnownHostsFile /root/.ssh/known_hosts
Beispielausgabe
# Kontrolle:
cat /root/.ssh/config
3) Client: Public Key anzeigen/kopieren
Befehl (kopierbar)
cat /root/.ssh/JSc/little-ghost/id_ed25519.pub
Beispielausgabe
ssh-ed25519 AAAAAAAAAABBBBBBBBBB/CCCCCCCCCC little-ghost
Diesen Einzeiler auf dem Server in die Datei ~<user>/.ssh/authorized_keys einfügen (eine Zeile pro Key, keine Umbrüche).
4) Server: root nur per Public Key
Datei /etc/ssh/sshd_config.d/10-root-only-key.conf anlegen/ändern.
Dateiinhalt (kopierbar)
# Root: nur noch Public-Key, keine Passwörter/Keyboard-Interactive
Match User root
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
AuthenticationMethods publickey
PermitRootLogin prohibit-password
Beispielausgabe
# Kontrolle:
cat /etc/ssh/sshd_config.d/10-root-only-key.conf
5) Server: jj nur per Public Key
Datei /etc/ssh/sshd_config.d/20-jj-only-key.conf anlegen/ändern.
Dateiinhalt (kopierbar)
# jj: nur noch Public-Key, keine Passwort-/Keyboard-Interactive-Logins
Match User jj
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
AuthenticationMethods publickey
Beispielausgabe
# Kontrolle:
cat /etc/ssh/sshd_config.d/20-jj-only-key.conf
6) Server: Syntax prüfen & Dienst neu laden
Befehl (kopierbar)
sshd -t
sleep 30
systemctl reload ssh # Debian-Standarddienstname
Beispielausgabe
# Bei korrekter Konfiguration keine Ausgabe.
# Fehler würden hier mit Zeile/Datei gemeldet werden.
7) Client: Login zum Server testen
Befehl (kopierbar)
ssh SERVER_IP
Beispielausgabe
The authenticity of host 'SERVER_IP (SERVER_IP)' can't be established.
ED25519 key fingerprint is SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'SERVER_IP' (ED25519) to the list of known hosts.
Enter passphrase for key '/root/.ssh/JSc/little-ghost/id_ed25519':
Last login: Wed Sep 24 12:34:56 2025 from 203.0.113.42
root@server:~#
Hinweise
- Dateirechte: Verzeichnisse
700, Private Key600, Public Key644. - Known Hosts: Datei heißt
known_hosts(nichtknown_hos). - Debug bei Problemen:
ssh -v SERVER_IPzeigt, welchen Key der Client nutzt.
Stand: 25.09.2025
SSHFS - Storage
🔐 SSHFS-Mount Anleitung für Linux + Nextcloud
Beispiele nutzen Fantasie-Namen und RFC-5737-Dummy-IP (192.0.2.0/24):
Client: orion-client • Server: atlas-storage • Server-IP: 192.0.2.55
Zielpfad auf dem Server: /srv/projects/ai/labs/local-sdxl-cpu
0. Voraussetzungen (Server)
# Gruppe für SSHFS-Nutzer anlegen (falls noch nicht vorhanden)
groupadd sshfsusers
# Verzeichnis für hinterlegte Public Keys anlegen und absichern
mkdir -p /etc/sshfs_keys
chown root:root /etc/sshfs_keys
chmod 0755 /etc/sshfs_keys
1. SSH-Schlüssel erstellen (Client)
# moderner Schlüssel (ed25519)
ssh-keygen -t ed25519 -a 2048 -o -Z aes256-ctr -f ~/.ssh/orion_to_atlas -C "sshfs orion-client → atlas-storage"
2. Öffentlichen Schlüssel auf den Server übertragen
scp ~/.ssh/orion_to_atlas.pub root@192.0.2.55:/etc/sshfs_keys/sshfs_orion.pub
# auf dem Server:
chown root:root /etc/sshfs_keys/sshfs_orion.pub
chmod 0644 /etc/sshfs_keys/sshfs_orion.pub
3. SSHFS-Benutzer auf dem Server anlegen
# Benutzer ohne Home (kein Risiko durch dotfiles), in Gruppe sshfsusers
useradd -M -g sshfsusers -s /usr/sbin/nologin sshfs_orion
# Ziel-Verzeichnisstruktur (nur Beispielpfad)
mkdir -p /srv/projects/ai/labs/local-sdxl-cpu
# Eigentümer/Gruppe setzen, setgid auf dem Zielordner
chown -R root:sshfsusers /srv/projects
chmod 2750 /srv/projects/ai/labs/local-sdxl-cpu
Wichtig (Traversal nur für die Gruppe): Damit der Benutzer sshfs_orion den Zielordner erreicht, müssen alle Elternordner das x-Recht für die Gruppe haben, ohne Leserechte (kein Listing). Das hält den Pfad geschlossen und erlaubt nur Durchgang.
# Elternordner: Gruppe setzen + nur Durchgang (710)
chgrp sshfsusers /srv
chmod 710 /srv
chgrp sshfsusers /srv/projects
chmod 710 /srv/projects
chgrp sshfsusers /srv/projects/ai
chmod 710 /srv/projects/ai
chgrp sshfsusers /srv/projects/ai/labs
chmod 710 /srv/projects/ai/labs
# Zielordner: nur Besitzer+Gruppe, setgid damit neue Dateien in der Gruppe bleiben
chgrp sshfsusers /srv/projects/ai/labs/local-sdxl-cpu
chmod 2770 /srv/projects/ai/labs/local-sdxl-cpu
4. SSH-Konfiguration auf dem Server
Datei /etc/ssh/sshd_config bearbeiten und am Ende hinzufügen:
Match User sshfs_orion
AuthorizedKeysFile /etc/sshfs_keys/%u.pub
PubkeyAuthentication yes
KbdInteractiveAuthentication no
PasswordAuthentication no
AllowTcpForwarding no
X11Forwarding no
PermitTTY no
PermitTunnel no
ForceCommand internal-sftp
# Syntax prüfen und Dienst neu laden
sshd -t
systemctl reload ssh
5. FUSE erlauben (Client & ggf. Server)
Datei /etc/fuse.conf öffnen und sicherstellen, dass die Zeile ohne Kommentar vorhanden ist:
user_allow_other
6. Bequemer Host-Alias auf dem Client (empfohlen)
Datei ~/.ssh/config (Client) ergänzen:
Host atlas
HostName 192.0.2.55
User sshfs_orion
IdentityFile ~/.ssh/orion_to_atlas
IdentitiesOnly yes
ServerAliveInterval 15
ServerAliveCountMax 3
StrictHostKeyChecking yes
7. SSHFS-Mount auf dem Client
# lokaler Mountpunkt
mkdir -p /mnt/atlas_labs
# Mount (streng: others=0 → umask=007)
sshfs -o IdentityFile=~/.ssh/orion_to_atlas \
-o reconnect \
-o ServerAliveInterval=15 \
-o ServerAliveCountMax=3 \
-o allow_other \
-o default_permissions \
-o uid=1000 \
-o gid=1000 \
-o umask=007 \
-o idmap=user \
atlas:/srv/projects/ai/labs/local-sdxl-cpu /mnt/atlas_labs
Hinweise:
umask=007ergibt effektiv 770/660 auf dem Mount (keine Rechte für others). (umask=002würde 775/664 zulassen.)default_permissionssorgt dafür, dass Kernel-Rechte lokal erzwungen werden.
8. Optional: Dauerbetrieb per /etc/fstab (Client)
sshfs#sshfs_orion@192.0.2.55:/srv/projects/ai/labs/local-sdxl-cpu /mnt/atlas_labs fuse.sshfs \
IdentityFile=/root/.ssh/orion_to_atlas,allow_other,default_permissions,uid=1000,gid=1000,umask=007, \
reconnect,ServerAliveInterval=15,ServerAliveCountMax=3,idmap=user,_netdev 0 0
🎁 Bonus: Nutzung mit Nextcloud
Mount für www-data (uid/gid 33):
mkdir -p /mnt/nextcloud_data
sshfs -o IdentityFile=/root/.ssh/nextcloud_key \
-o reconnect -o ServerAliveInterval=15 -o ServerAliveCountMax=3 \
-o allow_other -o default_permissions \
-o uid=33 -o gid=33 -o umask=007 -o idmap=user \
nextcloud_svc@192.0.2.55:/srv/nextcloud/export /mnt/nextcloud_data
- In Nextcloud: Admin → Externer Speicher → Pfad
/mnt/nextcloud_dataeinbinden.
9. Troubleshooting (kurz & sicher)
- Passwort-Prompt statt Key: Rechte prüfen:
/etc/sshfs_keys= 0755, Dateien = 0644, Owner = root:root. Dannsshd -T -C user=sshfs_orionauf dem Server und aufauthorizedkeysfileachten. - Zugriff verweigert trotz korrektem Key: Elternordner-Traversal mit
namei -l /srv/projects/ai/labs/local-sdxl-cpuprüfen. Jeder Ordner brauchtg+xbei Gruppesshfsusers. - Host verwechselt: Host-Alias in
~/.ssh/confignutzen, nicht rohe IPs tippen.