Mit der Secure Shell Daten sicher transferieren

Aus LinuxUser 01/2018

Mit der Secure Shell Daten sicher transferieren

© Solarseven, 123RF

Sicherer Tunnel

Die Secure Shell ist der Goldstandard für sicheren Shell-Zugriff auf entfernte Rechner.

Selbst in einem lokalen Netzwerk lohnt es sich, das Übertragen der Daten auf einem verschlüsselten Kanal zu erledigen. Als Bordmittel drängt sich die Secure Shell dabei als naheliegende Lösung geradezu auf.

Mit SFTP und dem FUSE-Dateisystem SSHFS gibt es dafür zwei Ansätze, die einen unterschiedlichen Grad an Komfort bieten. SFTP, eine verschlüsselte Variante des bekannten, aber mittlerweile in die Jahre gekommenen Protokolls FTP, erlaubt es, den Zugriff auf Daten oder sogar auf einen Rechner erheblich einzuschränken. So setzen Sie einen kleinen Server auf, dessen Infrastruktur nicht für alle Teilnehmer im LAN bereitsteht.

Umgebung abschotten

Es bietet sich an, SFTP-Benutzer in eine Art Chroot-Umgebung einzusperren, die keinen Zugriff auf die Shell erlaubt. Auf diese Weise kann eine nicht ausgelastete Maschine beispielsweise nebenbei noch NAS-Aufgaben übernehmen. Aber selbst für einen Daten-Pool, den Sie vom Internet aus bedienen, ist dies interessant.

Wenn Sie eine solche Lösung implementieren, lohnt es sich, einige Gedanken in die Sicherheit des SFTP-Servers zu investieren. So erhöhen Sie diese, wenn Sie root allenfalls den Zugriff aus dem lokalen Netz oder besser ausschließlich via localhost erlauben.

Diese und andere Maßnahmen legen Sie in der Konfiguration des SSH-Daemons unter /etc/ssh/sshd_config fest. Parallel lohnt es sich, eine zusätzliche Gruppe (im Beispiel nennen wir sie speichergruppe) anzulegen. Um den SFTP-Server zu aktivieren, kommentieren Sie als Erstes in der Konfigurationsdatei die folgende Zeile aus:

Subsystem sftp /usr/lib/openssh/sftp-server

Anschließend fügen Sie einen neuen Eintrag am Ende der Datei hinzu (Listing 1). Dabei geben Sie das abzuschottende Verzeichnis an, die Benutzergruppe sowie weitere Anweisungen. Eine davon verhindert ein TCP-Forwarding, die andere beschränkt die Benutzer der angegebenen Gruppe auf das Ausführen von sftp. Ein Login in eine Shell gelingt so nicht.

Listing 1

Subsystem sftp internal-sftp
Match Group speichergruppe
  ChrootDirectory /home/speicher
  ForceCommand internal-sftp
  AllowTcpForwarding no

Anschließend starten Sie den SSH-Server neu, was Sie je nach Distribution über einen der beiden Befehle aus Listing 2 erledigen. Legen Sie die Speichergruppe an (Listing 3, Zeile 1) sowie das Verzeichnis, das Sie in der Variablen ChrootDirectory in der Konfiguration des SSH-Servers (Listing 1, Zeile 4) angegeben haben (Listing 3, Zeile 2).

Listing 2

### SysVinit
$ /etc/init.d/ssh restart
### Systemd
$ systemctl restart ssh.service

Listing 3

$ sudo addgroup speichergruppe
$ sudo mkdir -p /home/speicher
$ sudo usermod -G speichergruppe User
$ sudo usermod -s /bin/false User

Damit haben Sie die Vorarbeiten abgeschlossen. Nun legen Sie bei Bedarf noch den oder die Benutzer an. Möchten Sie diese Benutzer aus allen anderen Gruppen entfernen, erledigen Sie das mit dem Befehl aus Listing 3. Außerdem lohnt es sich, in diesem Fall die Login-Shell zu ändern und das Home-Verzeichnis entsprechend zu modifizieren.

Dieses manuelle Anlegen eines solchen Benutzers besteht aus einigen Einzelschritten. Mittels Skript (Listing 4) erledigen Sie diese aber fast automatisch.

Listing 4

#! /bin/sh
echo "Neuen Speicherbenutzer anlegen"
# Benutzernamen erfragen
echo -n "Benutzername: "; read ben
# Aktion wirklich durchführen?
echo -n "$ben anlegen? (j) "; read we
if [ "$we" != "j" ]; then
  exit
fi
# Neues Home-Verzeichnis fuer Benutzer anlegen,
# verhindert das Kopieren der Skel-Dateien.
mkdir /home/speicher/$ben
# Benutzer anlegen
useradd -b /home/speicher -s /bin/false -G speichergruppe $ben
# Verzeichnis anlegen und Rechte erteilen
chown $ben:speichergruppe /home/speicher/$ben/
chmod 700 /home/speicher/$ben/
# Kennwort manuell vergeben
passwd $ben

Mit dem Skript legen Sie ein Verzeichnis für den Benutzer unterhalb des Eintrags aus /etc/ssh/sshd_config an, im Beispiel also /home/speicher/User. Mittels chmod 700 schotten Sie die SFTP-Benutzer gegeneinander ab, niemand darf also in das Verzeichnis eines anderen SFTP-Benutzers absteigen.

Des Weiteren legen Sie bei Bedarf ein neues Konto unter Angabe der Gruppe speichergruppe und der Shell /bin/false an. Das Basisverzeichnis (hier: /home/speicher/) geben Sie bei useradd mit der Option -b an. Am Ende erhält der neue Account noch ein Passwort. Abbildung 1 zeigt das Anlegen eines Benutzers und ermöglicht einen Blick auf die entstandene Verzeichnisstruktur.

Abbildung 1: Ein Skript hilft beim Anlegen eines SFTP-Benutzers samt der zugehörigen Verzeichnisse.

Abbildung 1: Ein Skript hilft beim Anlegen eines SFTP-Benutzers samt der zugehörigen Verzeichnisse.

Für die Direktive ChrootDirectory sieht die Software eigentlich den Einsatz von Tokens wie %u für den Benutzernamen oder %h für das jeweilige Home-Verzeichnis vor. Das würde die Pfade dynamisch anpassen. Im Test funktionierte das aber in mehreren Konstellationen nicht.

Möglicherweise wollen Sie ein Benutzerkonten zu einem späteren Zeitpunkt wieder loswerden. Dazu löschen Sie den User aus der Benutzerverwaltung und entfernen das zugehörige Verzeichnis von Hand. Ein kleines Shell-Skript verdeutlicht hier wieder die Abläufe (Listing 5). Bei solchen Aktionen empfiehlt es sich, die entscheidenden Schritte mit einer Sicherheitsabfrage zu versehen. Abbildung 2 zeigt, wie der Administrator den Benutzer speicher2 wieder entfernt.

Listing 5

#! /bin/sh
echo "Löschen von Speicherbenutzern"
# Benutzernamen erfragen
echo -n "Benutzername: ";read ben
# Aktion wirklich durchführen?
echo -n "$ben löschen? (j) ";read we
if [ "$we" != "j" ]; then
  exit
fi
# Benutzer löschen
userdel $ben
# Verzeichnis löschen?
echo -n "Benutzerverzeichnis löschen? (j) "; read wn
# Aktion wirklich durchführen?
if [ "$wn" != "j" ]; then
  exit
fi
rm -r /home/speicher/$ben

Abbildung 2: Benötigen Sie einen Account nicht mehr, empfiehlt es sich, diesen zu löschen, um keine unnötigen Einfallstore auf dem Server zu haben.

Abbildung 2: Benötigen Sie einen Account nicht mehr, empfiehlt es sich, diesen zu löschen, um keine unnötigen Einfallstore auf dem Server zu haben.

Arbeiten mit SFTP

Der SFTP-Client verfügt über verschiedene Kommandos für den interaktiven Modus. Die Optionen decken sich mehr oder weniger mit denen von Ssh und Scp. In der Tabelle “SFTP-Kommandos” finden Sie die Anweisungen, getrennt nach der lokalen und entfernten Seite.

Aufgabe

lokal

entfernt

Verzeichnis wechseln

lcd Verzeichnis

cd Verzeichnis

Verzeichnisinhalt auflisten

lls Optionen

ls Optionen

Verzeichnis anlegen

lmkdir Verzeichnis

mkdir Verzeichnis

Aktuelles Verzeichnis

lpwd

pwd

Daten senden

put Dateien

Verzeichnis übertragen

put -r Verzeichnis

Abgebrochenen Transfer fortsetzen

reput

Dateien herunterladen

get Dateien

Verzeichnis herunterladen

get -r Verzeichnis

Abgebrochenen Download fortsetzen

reget

Objekte umbenennen

rename Alt Neu

Dateien löschen

rm Datei

Verzeichnis löschen

rmdir Verzeichnis

Lokale Shell erreichen

!

Hilfe aufrufen

help

Client beenden

quit

Mit den Befehlen ermöglichen Sie eine recht weitgehende Kontrolle über alle wichtigen Dateioperationen. Anhand des Beispiels in Abbildung 3 sehen Sie, wie Sie den Inhalt eines lokalen Verzeichnisses auflisten, eine Datei senden, den Inhalt eines entfernten Verzeichnisses auflisten (Option -l), eine Datei herunterladen und den Vorgang kontrollieren, indem Sie nochmals den Inhalt des lokalen Verzeichnisses auflisten.

Abbildung 3: Das Übertragen von Dateien via SFTP gelingt trotz Einsatz auf der Kommandozeile nach ein wenig Einarbeiten häufig relativ problemlos.

Abbildung 3: Das Übertragen von Dateien via SFTP gelingt trotz Einsatz auf der Kommandozeile nach ein wenig Einarbeiten häufig relativ problemlos.

SSHFS im Einsatz

Es gibt einige Programme, die das SFTP-Protokoll unterstützen. Der Einsatz des Userspace-Dateisystems SSHFS macht den Zugriff jedoch etwas transparenter. Einige Dateimanager beherrschen das direkte Einbinden solcher Verzeichnisse.

Als Grundlage dient dafür der Befehl sshfs, der wiederum eine komplett eingerichtete FUSE-Umgebung erwartet. Sie ermöglicht es normalen Benutzern, entfernte Verzeichnisse in den Baum einzuhängen. Listing 6 zeigt die entsprechende Syntax.

Listing 6

$ sshfs User@Rechner:/Pfad /Verzeichnis

Mit dem eingehängten, auf einem entfernten Rechner liegenden Verzeichnis arbeiten Sie wie mit einem lokalen Ordner. Abbildung 4 zeigt Ihnen das Einhängen, das Verzeichnis selbst und das Aushängen. Für Letzteres verwenden Sie folgende Syntax:

fusermount -u /Verzeichnis

Beim Aushängen darf keine Applikation mehr auf das fragliche Verzeichnis zugreifen. Gegebenenfalls ermitteln Sie über lsof Verzeichnis, welcher Prozess das Aushängen blockiert (Abbildung 5).

Abbildung 4: Dank SSHFS greifen Sie auf entfernte Verzeichnisse transparent zu, als lägen diese auf dem lokalen Host.

Abbildung 4: Dank SSHFS greifen Sie auf entfernte Verzeichnisse transparent zu, als lägen diese auf dem lokalen Host.


Abbildung 5: Mit dem Befehl »lsof« ermitteln Sie, ob eine Applikation auf ein via SSHFS eingehängtes Verzeichnis zugreift. Ist das der Fall, lässt es sich nicht aushängen.

Abbildung 5: Mit dem Befehl lsof ermitteln Sie, ob eine Applikation auf ein via SSHFS eingehängtes Verzeichnis zugreift. Ist das der Fall, lässt es sich nicht aushängen.

SSH-Tunnel

Ansätze wie SFTP oder SSHFS sorgen dafür, dass der Datentransfer verschlüsselt über das Netzwerk läuft. Es gibt aber Programme, die keine eigenen Funktionen zum Verschlüsseln mitbringen. Diesen verhelfen Sie mit einem SSH-Tunnel zu einer sicheren Verbindung.

Als normaler Benutzer dürfen Sie zu diesem Zweck nur Port-Nummern über 1024 verwenden. Einen einfachen Tunnel bauen Sie auf, indem Sie in einem Terminal einen Befehl absetzen, der der Syntax aus der ersten Zeile von Listing 7 folgt.

Listing 7

$ ssh -LLokalerPort:Rechner:Port User@Rechner
$ ssh -N -R LokalerPort:localhost:Port User@Rechner

Abbildung 6 zeigt das Konstrukt im Einsatz: Auf dem Zielsystem arbeitet ein Webserver, auf den ein Benutzer verschlüsselt zugreift. Dazu baut er zunächst den Tunnel auf (großes Terminal). Anschließend startet er den Shell-Webbrowser Elinks mit der URL http://localhost:8080 in einem anderen Terminal.

Abbildung 6: Mit einem SSH-Tunnel bauen Sie für eine Applikation eine verschlüsselte Verbindung zu einem anderen Rechner für einen HTTP-Zugriff auf.

Abbildung 6: Mit einem SSH-Tunnel bauen Sie für eine Applikation eine verschlüsselte Verbindung zu einem anderen Rechner für einen HTTP-Zugriff auf.

In die umgekehrte Richtung arbeitet das Kommando mit der Option -R (“Reverse Tunnel”). Die zugehörige Syntax zeigt die zweite Zeile von Listing 7. Hier bauen Sie ebenfalls zunächst den Tunnel auf, bevor die Software darauf zugreift. Der Browser Elinks arbeitet in derselben Weise wie beim normalen Tunnel (Abbildung 7).

Abbildung 7: Bauen Sie einen Reverse Tunnel auf, bleibt der HTTP-Zugriff trotzdem möglich.

Abbildung 7: Bauen Sie einen Reverse Tunnel auf, bleibt der HTTP-Zugriff trotzdem möglich.

Kontrolle aus der Ferne

Listing 8 zeigt einen Anwendungsfall aus der Praxis. Ein Benutzer mit nur geringen Kenntnissen kann damit einen Rechner überwachen.

Listing 8

#!/bin/bash
# menu.sh  Befehle auf entferntem System ausführen
SSHUSER="hz@artikel"
while true; do
  clear
  echo "(1) Plattenbelegung"
  echo "(2) Aktive Benutzer"
  echo "(3) Last und Prozessanzeige"
  echo "(9) Ende"
  echo "----------------------------------"
  read -n1 -p "Aufgabe " auf
  echo ""
  if [ "$auf" = "9" ]; then
    echo ""
    echo "Programmende"
    exit
  elif [ "$auf" = "1" ]; then
    ssh $SSHUSER df
    read -p "----------- Weiter --------------" we
  elif [ "$auf" = "2" ]; then
    ssh $SSHUSER w
    read -p "----------- Weiter --------------" we
  elif [ "$auf" = "3" ]; then
    ssh -t $SSHUSER htop
  fi
done

Das Menü bedient die Befehle df, w und htop am entfernten Rechner. Entweder rufen Sie es in der Form bash menu.sh auf, oder Sie versehen es mit den entsprechenden Ausführungsrechten. In jedem Fall müssen Sie die hart kodierten Angaben für Benutzer und Rechner in der Variablen SSHUSER an die konkreten Gegebenheiten anpassen.

Die Optionen von read, die in diesem Skript zum Einsatz kommen, funktionieren nur mit der Bash. Mit -n1 prüft die Software die Stellenzahl der Eingabe, hier 1. Hat die Eingabe entsprechend viele Stellen, entfällt die Notwendigkeit, die Eingabetaste zu drücken.

Über den String -p "PROMPT": erzeugen Sie einen Eingabeprompt. Der Echo-Befehl sorgt dafür, dass das Skript die Eingabe des Passworts in einer neuen Zeile anfordert. Die If-Abfrage behandelt Zahlen alphanumerisch, sodass kein Fehler auftritt, wenn Sie statt Zahlen Buchstaben eingeben.

Wenn Sie ein nicht interaktives Kommando absetzen, scrollt die Anzeige durch, und das Skript legt wieder das Menü darüber. Also braucht es einen Stoppmechanismus, der einen weiteren Read-Befehl realisiert. Alternativ leiten Sie die Ausgaben an den Pager Less weiter, der von der Standardeingabe liest und den Sie über [Q] beenden.

In anderen Fällen, wie etwa beim dritten Menüpunkt, der den Befehl htop auf dem entfernten Host absetzt, erweitern Sie den Aufruf von SSH mit der Option -t. Andernfalls läuft das Skript durch, und Sie sehen wiederum nur das Menü im Terminal. Abbildung 8 zeigt das skriptgesteuerte Abarbeiten von df und den Einsatz des Stoppers.

Abbildung 8: Mit einem einfachen Skript gelingt es selbst Einsteigern, Befehle auf entfernten Rechnern abzusetzen.

Abbildung 8: Mit einem einfachen Skript gelingt es selbst Einsteigern, Befehle auf entfernten Rechnern abzusetzen.

Sicheres Backup

Das Shell-Skript dasi.sh aus Listing 9 hat die Aufgabe, den Inhalt eines Verzeichnisses zu sichern (hier: Daten), das auf einem anderen Rechner liegt. Dafür bieten sich verschiedene Ansätze an: eine Kombination aus SSH und Tar, der Einsatz von SSHFS und Tar oder das Kopieren mit Scp. Am Ende des Transfers schreibt die Software eine Logdatei (dasi.log).

Listing 9

#!/bin/bash
# dasi.sh
if [ ! -d DASI ]; then
  mkdir DASI
fi
# Log anlegen
datum=$(date)
touch dasi.log
echo "Beginn Datensicherung: $datum" >> dasi.log
echo "----------------------------------------------------" >> dasi.log
# ssh + tar
ssh artikel 'cd /home/hz && tar czfv - UV1' | tar xzfv -
cd ..
tree DASI/UV1 >> dasi.log
echo "----------------------------------------------------" >> dasi.log
# scp
echo "Sicherung mit scp" >> dasi.log
cd DASI
scp -r artikel:/home/hz/UV2 .
cd ..
tree DASI/UV2 >> dasi.log
echo "----------------------------------------------------" >> dasi.log
datum=$(date)
echo "Ende der Datensicherung: $datum" >> dasi.log

Welche Kombination Sie anwenden möchten, hängt vom konkreten Fall ab. Das minimale Skript ist ausbaufähig: So wäre es möglich, mithilfe eines Cronjobs Verzeichnisse zeitgesteuert außerhalb der Arbeitszeit auf eine Backup-Maschine zu übertragen. In diesem Fall käme dann aber tatsächlich nur das Authentifizieren per Schlüssel infrage statt der üblichen Eingabe eines Passworts.

Listing 9 zeigt zwei Ansätze: Zum einen sichert es das Verzeichnis UV1 mittels Kombination von Ssh und Tar ins lokale Verzeichnis DASI, zum anderen kopiert es UV2 per scp -r auf einen anderen Host. Bei letzterem Vorgehen gerät oft der Doppelpunkt nach der Kombination User@Rechner unter die Räder.

Abbildung 9 zeigt den Ablauf. Mit dem Befehl tree erzeugt das kleine Programm eine Ausgabe und schreibt diese in das Log. Das hilft dabei, den Erfolg beim Sichern zu überprüfen.

Abbildung 9: Mit dem Skript »dasi.sh« sichern Sie Ordner mittels verschiedener Kombinationen von SSH und weiteren Tools.

Abbildung 9: Mit dem Skript dasi.sh sichern Sie Ordner mittels verschiedener Kombinationen von SSH und weiteren Tools.

Viele Rechner

Ein Kommando auf vielen Rechnern abzusetzen – das muss kein Traum bleiben. Neben dem Einsatz von Polysh [1] und Clusterssh [2] besteht die Möglichkeit, für dieses Szenario ein Shell-Skript mit weitgehenden Funktionen zu entwerfen. Vorbereitend sollten Sie Schlüssel ohne Passwörter auf den entfernten Rechnern installieren. In Schulungsumgebungen und abgeschotteten Netzen stellt das normalerweise kein Problem dar.

Das Shellskript multi.sh aus Listing 10 fragt den Zustand des SSH-Diensts mittels systemctl auf verschiedenen Rechnern ab und führt darüber in der Logdatei multi.log Buch.

Die Zielrechner liegen in der Datei ziele.liste, in der Sie pro Zeile eine Verbindung (unter .ssh/config definiert) eintragen. Die For-Schleife liest die Datei aus, sodass das Skript an jeden Rechner das Kommando systemctl status ssh.service absetzt. Über die Ausgabeumleitung schreibt es die Resultate in die Logdatei. Am Ende geben Sie diese am Terminal aus und sehen so, wie es um den angefragten Dienst steht (Abbildung 10).

Listing 10

#!/bin/bash
# multi.sh
# Befehl an mehrere Rechner senden
# und Logdatei anlegen
touch multi.log
echo "Multilog" >> multi.log
echo "Start Ausführung" >> multi.log
date >> multi.log
for i in $(cat ziele.liste); do
  echo "-------------------------------------------------" >> multi.log
  echo "Rechner: $i" >> multi.log
  echo "" >> multi.log
  ssh -t $i systemctl status ssh.service >> multi.log
done
echo "------------------- E n d e ---------------------" >> multi.log

Abbildung 10: Das Skript »multi.sh« erlaubt es, einen Befehl auf mehreren Rechnern abzusetzen.

Abbildung 10: Das Skript multi.sh erlaubt es, einen Befehl auf mehreren Rechnern abzusetzen.

Datenverteiler

Das Skript senden.sh in Listing 11 funktioniert ganz ähnlich wie das vorige Beispiel. Diesmal geben Sie mittels Positionsparameter $1 an, welche Dateien es an die Rechner im Netzwerk verteilt. Dabei verwenden Sie die schon im vorigen Beispiel benutzte Datei ziele.liste. Unter senden.log zeichnen Sie auf, ob die Daten ankommen.

Listing 11

#! /bin/bash
# senden.sh
# Datei an mehrere Rechner senden
# Logdatei anlegen
datum=$(date)
touch senden.log
echo "Sendebericht vom $datum" >> senden.log
for i in $(cat ziele.liste); do
  echo "------------------------------" >> senden.log
  echo "Rechner: $i" >> senden.log
  echo "" >> senden.log
  scp $1 $i:/home/hz >> senden.log 2>&1
  if [ $? -eq 0 ]; then
    echo "ok" >> senden.log
    else
    echo "!!!!!! FEHLER !!!!!!!!" >> senden.log
  fi
done
echo "-------- F E R T I G ---------" >> senden.log

Im Beispiel enthält die Datei nutzlast.txt die Daten, die es auf die Rechner zu verteilen gilt. Der Benutzer ist hier bereits in der Konfiguration für die Verbindung in .ssh/config eingetragen. Steht dieser Mechanismus nicht bereit, benutzen Sie die vollständige Adresse unter Angabe des Benutzers.

Als Ziele kommen in ziele.liste zwei existierende und ein fiktiver Rechner zum Einsatz. Ohne vorkonfigurierte SSH-Verbindungen müssen Sie hier die Einträge in der Form User@Rechner, beziehungsweise bei abweichenden Pfaden als User@Rechner:/Pfad vornehmen. Abbildung 11 zeigt den Ablauf mit der Log-Kontrolle.

Abbildung 11: Mit dem Skript »senden.sh« transferieren Sie einzelne Dateien auf einer sicheren Leitung an einen Host im Netzwerk.

Abbildung 11: Mit dem Skript senden.sh transferieren Sie einzelne Dateien auf einer sicheren Leitung an einen Host im Netzwerk.

Fazit

Die Secure Shell hat sich bereits in vielen Fällen als das Werkzeug für den Zugriff auf entfernte Systeme bewährt. Dabei verbindet sie die Vorzüge starker Kryptografie mit zahlreichen Features, die den Einsatz im Alltag sinnvoll und vor allem komfortabel machen. In Kombination mit weiteren Werkzeugen wie Tar oder FUSE erstellen Sie so mit wenigen Zeilen Code eine einfache Backup-Lösung oder greifen transparent auf die Daten eines entfernten Systems zu. 

Glossar

Chroot

Change Root. Eine Umgebung, meist in Form einer Verzeichnisstruktur oder eines Containers, die aus Sicht des Anwenders ein komplettes System enthält, tatsächlich aber nur in einem Teilbaum des Hosts oder der virtuellen Maschine liegt.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDF
LinuxUser 01/2018 KAUFEN
EINZELNE AUSGABE
ABONNEMENTS
TABLET & SMARTPHONE APPS
E-Mail Benachrichtigung
Benachrichtige mich zu:

Hinweis: Dieser Artikel ist älter als ein Jahr, enthaltene Informationen sind möglicherweise veraltet.

0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben