Automatische Datentransfers per SFTP mit Passwort und via Proxy
Dieser Artikel beschreibt einen Spezialfall aus dem Bereich OpenSSH, bei dem mehrere erschwerende Bedingungen zusammenkommen:
- Es sollen automatisiert Dateien per SFTP ausgetauscht werden
- Zugriff auf den Server ausschließlich mit SFTP möglich, keine normale SSH-Shell, kein scp, kein rsync+ssh oder ähnliches.
- Zugriff auf das Zielsystem nur per HTTP-Proxy möglich
- Zugriff auf den Account nur mit Benutzername und Passwort möglich, keine Public-Key Authentifikation möglich
- Zugriffe sollen gescriptet werden (Batch-Mode, Shell-Scripte), also nicht-interaktiv
Allgemein
Für jede der Bedinungen gibt es einzelne Lösungen, die im Zusammenspiel allerdings trickreich sein können.
nur SFTP, automatisiert
Für viele Anwendungsfälle aus dem Bereich automatisierter Filetransfer greift man zu Lösungen wie scp oder rsync+ssh oder andere Konstrukte die direkt auf ssh aufbauen. In diesem Fall ist auf dem Zielserver nur sftp möglich.
sftp ist ein sogenannte subsystem aus SSH und nur genau dieses Subsystem ist für uns erreichbar.
This service allows sftp connections only.
Wir müssen also für alle Zugriffe das "sftp"-Tool verwenden, oder zumindest das "sftp"-Subsystem per ssh ansprechen.
Mittels sftp -b kann man einfache vordefinierte Batchscripte ausführen, also eine Abfolge von diesen commands:
sftp> help Available commands: bye Quit sftp cd path Change remote directory to 'path' chgrp grp path Change group of file 'path' to 'grp' chmod mode path Change permissions of file 'path' to 'mode' chown own path Change owner of file 'path' to 'own' df [-hi] [path] Display statistics for current directory or filesystem containing 'path' exit Quit sftp get [-Ppr] remote [local] Download file help Display this help text lcd path Change local directory to 'path' lls [ls-options [path]] Display local directory listing lmkdir path Create local directory ln [-s] oldpath newpath Link remote file (-s for symlink) lpwd Print local working directory ls [-1afhlnrSt] [path] Display remote directory listing lumask umask Set local umask to 'umask' mkdir path Create remote directory progress Toggle display of progress meter put [-Ppr] local [remote] Upload file pwd Display remote working directory quit Quit sftp rename oldpath newpath Rename remote file rm path Delete remote file rmdir path Remove remote directory symlink oldpath newpath Symlink remote file version Show SFTP version !command Execute 'command' in local shell ! Escape to local shell ? Synonym for help
És gibt wiederum verschiedene Tools, die im Hintergrund sftp sprechen, zum Beispiel lftp mit seiner mächtigen Scriptsprache oder sshfs als FUSE-Treiber für ein auf sftp basiertes Dateisystem, das man in Linux (nicht Gnome, KDE) mounten kann. Diese Möglichkeiten sind hier out-of-scope.
Wichtig zu wissen ist, dass das sftp(1)-Tool die Datei ssh_config(5) (in /etc/ssh/ und ~/.ssh/config) verwendet.
Zielsystem nur per Proxy erreichbar
- Szenario
- Wir befinden uns im Backend eines DataWarehouse oder im einen Entwicklernetz ohne direkten Zugang zum Internet.
- Wir müssen den einen oder anderen Proxy verwenden, wenn wir auf Ziele im Internet zugreifen können möchten.
OpenSSH selbst kennt keine Mechanismen für SOCKS-Proxy oder HTTP(s)-Proxy, bietet allerdings eine Schnittstelle an, wo man eigene Proxy-Clients konfigurieren kann. Diesen Client mit allen erforderlichen Optionen konfiguriert man über ProxyCommand in ssh_config(5) ein.
- Beispiele dazu
- SOCKS Proxy nutzen/openssh
- Firewall Piercing/Beispiele/OpenSSH via HTTPS-Proxy als SOCKS Proxy verwenden
Gerade in Verbindung mit HTTP-Proxy ist wichtig, dass der HTTP-Proxy den CONNECT-Zugriff auf das Zielsystem erlaubt. Normalerweise ist das für HTTPS nur der Port 443, Details Dazu unter Firewall Piercing#Einen_Webproxy_als_Transportweg_verwenden
- HTTP-Proxy mit netcat, in ssh_config
ProxyCommand /bin/nc.openbsd -X CONNECT -x proxy.dmz.lan:3128 %h %p
Alternativ kann man eine Verbindung zur Außenwelt auch andere Konstrukte benutzen zum Beispiel eine SSH-Verbindung zu einem Server in der DMZ (erreichbar von innen und mit Zugriff auf das Internet):
- DMZ-Server mit netcat-openbsd, in ssh_config
ProxyCommand /usr/bin/ssh server.dmz.lan /bin/nc.openbsd %h %p
Zugriff nur mit Passwort
Falls man das unbeschreibliche Pech hat auf einen SFTP-Server zugreifen zu müssen, auf den man sich ausschließlich per Username+Passwort einloggen kann, muss man zu externen Hilfsmitteln greifen, eines davon ist sshpass, andere Lösungen bevorzugen expect.
OpenSSH kennt keine Methoden für eine Passwortübergabe, es fragt ausschließlich interaktiv (über ein Terminal/pty). sshpass ruft also ssh oder sftp auf und verwendet dazu ein Pseudo-TTY, damit das jeweilige Binary auch nach dem Passwort fragt. Dieses TTY ist unabhängig vom TTY der Shell, in der wir das ausprobieren.
sshpass wiederum akzeptiert ein Passwort über verschiedene Parameter:
- als Commandline Argument: -ppassword
- aus der ersten Zeile einer Datei mit -ffilename
- aus einem Filedescriptor über -dnumber
- oder aus einer Umgebungsvariable SSHPASS mittels -e