Inhaltsverzeichnis
sftp mit Change Root
Seit OpenSSH 4.9 unterstützt der SSH-Daemon des OpenBSD Projekts das Einsperren der Benutzer in einem beliebigen Verzeichnis über den chroot(2) Systemaufruf. Zuvor war dies nur mit einem Thirdparty Patch wie chrootssh oder im Fall der Einschränkung auf SFTP/SCP mit speziellen Shells wie scponly oder rssh möglich.
Ebenfalls mit Version 4.9 wurde eine Variante des sftp-server(8) eingeführt, die direkt in sshd(8) gelinkt ist. Das hat den großen Vorteil, dass nicht mehr alle Binaries und Programme, die ein Benutzer ausführen können soll oder muss (z. B. seine Shell oder die SFTP-Bibliothek) sowie die Gerätedateien /dev/null und /dev/urandom innerhalb der chroot-Umgebung vorhanden sein müssen. Das erspart dem Administrator die fehlerträchtige Erstellung einer solchen Umgebung sowie die Redundanz der in den chroot-Umgebungen benötigten Dateien.
Die Einrichtung erfolgt sehr einfach in der sshd_config(5). Zunächst muss das Subsystem "sftp" mit dem intern vorhandenen SFTP-Server ("internal-sftp") geladen werden:
Subsystem sftp internal-sftp
Danach können entweder global alle Benutzer in eine chroot-Umgebung eingesperrt werden (nicht zu empfehlen) oder über einen Match-Block nur einzelne Benutzer, Gruppen oder IP-Adressen bzw. IP-Adressbereiche. Die Festlegung des Verzeichnisses, in dem der Benutzer eingesperrt wird, erfolgt über die Direktive ChrootDirectory. Als Parameter wird das Verzeichnis erwartet, wobei die Zeichenkette einige Variablen enthalten kann:
Variable | Bedeutung ------------+-------------------------------- %h | Home-Verzeichnis des Benutzers %u | Benutzername des Benutzers %% | '%' Zeichen
Die Direktive ChrootDirectory /srv/www/%u würde den Benutzer "web1" also im Verzeichnis /srv/www/web1 einsperren. Soll der Benutzer zusätzlich wirklich nur via SFTP auf den Server zugreifen können, kann dies mit der Direktive ForceCommand internal-sftp erzwungen werden.
Achtung: Dadurch ist wirklich nur noch ein Zugriff via SFTP möglich. Auch SCP funktioniert dann nicht mehr!
Hier ein paar Beispieleinträge in der sshd_config. Die Match-Blöcke müssen unbedingt am Ende der Datei stehen, da sonst alle folgenden Direktiven, die auch in einem Match-Block stehen könnten, dem letzten Block zugeordnet werden!
# Clients aus dem IP-Adressbereich 10.0.1.0/24 einsperren. Match Address 10.0.1.* ChrootDirectory %h # Benutzer mit der Gruppe sftp im Homeverzeichnis einsperren und nur SFTP erlauben Match Group sftp ChrootDirectory %h ForceCommand internal-sftp # Benutzer web* (z. B. web1, web42, web123, web4711) in /srv/www/ einsperren und nur SFTP erlauben Match User web* ChrootDirectory /srv/www/%u ForceCommand internal-sftp
Sobald ein Benutzer mit dieser sshd-Konfiguration mit gpasswd -a sftp der Gruppe sftp hinzugefügt wird, kann dieser sich in Zukunft nur noch innerhalb seines zugewiesenen Verzeichnisses bewegen. Ideal zur Absicherung eines Servers mit mehreren nicht vertrauenswürdigen Benutzern.
SFTP-User mit Change Root
Hier wird ein User sftpmaster angelegt, der sich mit diesem Rechner nur per sftp verbinden kann und aus sein Home-Verzeichnis nicht raus kommt.
cp /etc/ssh/sshd_config /tmp/ && cat /tmp/sshd_config | sed 's/^Subsystem sftp.*sftp-server/#&/' > /etc/ssh/sshd_config && rm -f /tmp/sshd_config
echo "
Subsystem sftp internal-sftp -l INFO
Match user sftpmaster
ChrootDirectory /home/%u
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp
" >> /etc/ssh/sshd_config
/etc/init.d/ssh restart
groupadd sftp useradd -s /bin/false -d /home/sftpmaster -g sftp sftpmaster mkdir -p /home/sftpmaster chown 0:0 /home/sftpmaster chmod 0755 /home/sftpmaster mkdir /home/sftpmaster/DATEN chown sftpmaster:sftp /home/sftpmaster/DATEN chmod 0770 /home/sftpmaster/DATEN
Sub-SFTP-User mit Change Root
Hier werden zwei Sub-User, fritz und fratz angelegt, die von sftpmaster Dateien bekommen können aber sich gegenseitig keine Dateien schicken können und auch nicht in die Dateien des jeweils anderen rein sehen können.
Erstmal die SSH-Konfiguration ergänzen und aktivieren. Hier ist es wichtig, dass alle Gruppen (außer root) von dem Match erfasst werden, sonst kann sich ein neu angelegter User ohne Change-Root anmelden, wenn man in aus Versehen einer falschen Gruppe zugewiesen hat!
echo "
Match group !root,*
ChrootDirectory /home/sftpmaster/%u
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp
" >> /etc/ssh/sshd_config
/etc/init.d/ssh restart
Jetzt kann der erste Unterbenutzer oder wie wir ihn nennen "Sub-User" angelegt werden:
useradd -s /bin/false -g sftp -d /home/sftpmaster/fritz fritz mkdir -p /home/sftpmaster/fritz chown 0:0 /home/sftpmaster/fritz chmod 0755 /home/sftpmaster/fritz mkdir /home/sftpmaster/fritz/DATEN chown fritz:sftp /home/sftpmaster/fritz/DATEN chmod 0770 /home/sftpmaster/fritz/DATEN
Und weil es so gut geklappt hat, legen wir gleich noch einen zweiten an:
useradd -s /bin/false -g sftp -d /home/sftpmaster/fratz fratz mkdir -p /home/sftpmaster/fratz chown 0:0 /home/sftpmaster/fratz chmod 0755 /home/sftpmaster/fratz mkdir /home/sftpmaster/fratz/DATEN chown fratz:sftp /home/sftpmaster/fratz/DATEN chmod 0770 /home/sftpmaster/fratz/DATEN
SFTP mit Change Root als Scripte
# vi /root/bin/sftp_init.sh
#!/bin/bash
CFGDIR="/root/etc"
CFGDATEI="${CFGDIR}/sftp_chroot.conf"
BINDIR="/root/bin"
BINDATEI="${BINDIR}/sftp_sub_useradd.sh"
if [ -z "${2}" ] ; then
echo "${0} [User-Name des SFTP-Master-User's] [SFTP-Gruppe]"
exit 1
fi
################################################################################
# Dieses Script darf nur einmal ausgeführt werden,
# wenn es bereits ausgeführt wurde, dann wird ab hier nichts gemacht.
diff /etc/ssh/sshd_config /tmp/sshd_config > /dev/null
if [ "$?" -gt "0" ] ; then
mkdir -p ${CFGDIR} ${BINDIR}
echo "
#------------------------------------------------------------------------------#
# in dieser Konfigurationsdatei werden die zentralen Einstellungen vorgenommen die für alle SFTP-Scripte gelten sollen
UUSER=\"\${1}\"
OUSER=\"${1}\"
GRUPPE=\"${2}\"
if [ -z \"\${1}\" ] ; then
echo \"\${0} [User-Name des neuen SFTP-Sub-User's]\"
echo \"die aktuelle konfigurierte Sub-Gruppe ist: \${GRUPPE}\"
exit 1
fi
#------------------------------------------------------------------------------#
" >> ${CFGDATEI}
. ${CFGDATEI}
echo "
#------------------------------------------------------------------------------#
#
# Der sftp-Parapeter "-u" funktioniert erst seit "OpenSSH 5.4".
#
Match user ${OUSER}
ChrootDirectory /home/%u
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp -u 0007
Match group !root,*
ChrootDirectory /home/${OUSER}/%u
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp -u 0007
#------------------------------------------------------------------------------#
" >> /etc/ssh/sshd_config
/etc/init.d/ssh restart
################################################################################
# Master-SFTP-User anlegen
groupadd ${GRUPPE}
useradd -s /bin/false -d /home/${OUSER} -g ${GRUPPE} ${OUSER}
mkdir -p /home/${OUSER}/.ssh
touch /home/${OUSER}/.ssh/authorized_keys
chown 0:0 /home/${OUSER}
chmod 0755 /home/${OUSER}
chown -R ${OUSER}:0 /home/${OUSER}/.ssh
chmod -R 0700 /home/${OUSER}/.ssh
rm -f /tmp/sshd_config
#------------------------------------------------------------------------------#
echo "
#!/bin/bash
# Mit disem Script werden alle "Unter-SFTP-User" bzw. "Sub-SFTP-User" angelegt,
# die sich untereinander nicht gegenseitig in die Daten sehen können und
# sie können auch nicht in das Verzeichnisse des "SFTP-Master-User" gelangen.
#
# Sie können nur die Daten sehen und bearbeiten, die der "SFTP-Master-User"
# ihnen ins "Home-Verzeichnis" legt!
. /root/etc/sftp_chroot.conf
useradd -s /bin/false -g \${GRUPPE} -d /home/\${OUSER}/\${UUSER} \${UUSER}
mkdir -p /home/\${OUSER}/\${UUSER}/.ssh
touch /home/\${OUSER}/\${UUSER}/.ssh/authorized_keys
chown 0:0 /home/\${OUSER}/\${UUSER}
chmod 0755 /home/\${OUSER}/\${UUSER}
mkdir /home/\${OUSER}/\${UUSER}/DATEN
chown \${UUSER}:\${GRUPPE} /home/\${OUSER}/\${UUSER}/DATEN
chmod 0770 /home/\${OUSER}/\${UUSER}/DATEN
chown -R \${UUSER}:0 /home/\${OUSER}/\${UUSER}/.ssh
chmod -R 0700 /home/\${OUSER}/\${UUSER}/.ssh
" >> ${BINDATEI}
chmod -R 0755 ${BINDIR}
fi
Anwendung der Scripte
Als erstes oben abgebildete Script /root/bin/sftp_init.sh braucht nur einmal und sollte auch nur einmal ausgeführt werden!
z.B.:
/root/bin/sftp_init.sh sftpmaster sftpgruppe
Nachdem das Script ausgeführt wurde, liegen folgende Dateien vor:
- /root/bin/sftp_init.sh
- /root/etc/sftp_chroot.conf
- /root/bin/sftp_sub_useradd.sh
Jetzt wird nur noch das Script /root/bin/sftp_sub_useradd.sh verwendet, um alle gewünschten Unter-SFTP-User anzulegen!
/root/bin/sftp_sub_useradd.sh fritz
Jetzt braucht man nur noch die public-SSH-Schlüssel in den Dateien /home/sftpmaster/.ssh/authorized_keys und /home/sftpmaster/fritz/.ssh/authorized_keys für einen passwortlosen Login ablegen.
OpenSSH logging with ChrootDirectory (logleser)
Diese Anleitung beschreibt die Konfiguration des LogDienstes rSysLog. Um vom SysLog einen Socket generieren zu lassen, muss ihm in der Start-Option '-u /home/logleser/dev/log' mit übergeben werden.
Logs ohne Privilegien lesen:
# useradd -m -g adm logleser # mkdir -p /home/logleser/log /home/logleser/dev /home/logleser/.cache /home/logleser/.ssh # touch /home/logleser/.bash_history # touch /home/logleser/.ssh/authorized_keys # chmod 0600 /home/logleser/.ssh/authorized_keys # chown logleser:adm /home/logleser/.bash_history # chown -R logleser:adm /home/logleser/.ssh # chmod 0600 /home/logleser/.bash* # chmod 0600 /home/logleser/.profile # chmod -R 0700 /home/logleser/.cache
vi /etc/fstab
... # mount -o bind /var/log/ /home/logleser/log/ /var/log/ /home/logleser/log/ none bind 0 0 ...
# sed -ie 's|.*/var/log/sftp[.]log.*|# &|' /etc/rsyslog.conf
Jetzt die Datei aus dem Verzeichnis /etc/logrotate.d/ löschen, die die Rotation der Datei /var/log/sftp.log beschreibt.
vi /etc/rsyslog.d/sshd.conf
# Create an additional socket for some of the sshd chrooted users. $AddUnixListenSocket /home/logleser/dev/log $AddUnixListenSocket /home/logleser2/dev/log # Log internal-sftp in a separate file :programname, isequal, "internal-sftp" -/var/log/sftp.log :programname, isequal, "internal-sftp" ~
SFTP-Client
Mit Linux/BSD/Unix geht es ohne Frage intuitiv. Aber mit Windows dagegen muss man das richtige Programm kennen.
FileZilla Portable + PortableApps funktioniert zuverlässig:
- https://portableapps.com/de/suite → um den SSH-Schlüssel im richtigen Format der Anwendung bereitstellen
-
- die Portable-Version von FileZilla, integriert sich nahtlos in die PortableApps Suite
Was ist der Unterschied zwischen FTPS und SFTP?
https://www.dmsolutions.de/hilfe/anleitungen-faq/was-ist-der-unterschied-zwischen-sftp-und-ftps.html
FTPS → FTPS Methode Explizit:
- bei FTPS handelt der Client erst nach dem Verbindungsaufbau eine Verschlüsselung aus, die Verbindung bleibt auch unverschlüsselt bestehen, wenn sie sich auch keine Verschlüsselungsmethode einigen konnten
- FTPS ist ein klassisches FTP, welches SSL (X.509, ähnlich wie bei HTTPS) zur Verschlüsselung nutzt
SFTP → FTP Methode Implizit:
- hier geht ohne Verschlüsselung nichts
- SFTP ist ein Sub-System in SSH
