Das Tool WinSCP kann sudo
auf dem Remotecomputer einen Befehl ausführen, um den Befehl als Sudo-Benutzer auszuführen . Das lässt mich annehmen, dass dies auch scp
mit der Befehlszeilenversion von möglich sein muss .scp
Wie führt WinSCP dies unter der Hand aus?
Ich möchte nicht durcharbeiteneine Lösung mit einem Benutzer-Staging-Verzeichnis. Dateien können so groß sein, dass ich sie direkt mit dem Benutzer posten muss sudo
. Daher wird die Datei kopiert, aber in mein lokales Verzeichnis, nicht in das Sudo-Verzeichnis.
Eine Lösung könnte darin bestehen,manuelles Weiterleiten über SSH:
tar zcvf - MyBackups | ssh user@server "cat > /path/to/backup/foo.tgz"
Ich denke, dass man es anpassen könnte, um sudo wie folgt auszuführen:
cat local.txt | ssh user@server "sudo -u sudouser cat > ~/remote_file"
Das einzige Problem ist, dass ich auf diese Weise eine Menge Lasten zu lösen habe, die scp
bereits mit Base implementiert wurden. Aus diesem und anderen Gründen möchte ich diese Lösung auch nicht verwenden.
Wie kann ich scp
eine direkte Kopie an einen Remote-Computer veranlassen, indem ich sudo
den Benutzer ändere, sodass ich Zugriff auf seine Berechtigungen erhalte?
Antwort1
Scp funktioniert, indem es eine SSH-Verbindung zum Remote-Server herstellt und diese Verbindung dann verwendet, um einen weiteren scp
Befehl auf dem Remote-System auszuführen. Die lokale SCP-Instanz und die Remote-Instanz kommunizieren über die SSH-Verbindung, um Dateien zu senden oder zu empfangen.
OpenSSH scp erstellt insbesondere eine scp-Befehlszeichenfolge, die auf dem Remote-System ausgeführt werden soll. Anschließend startet es ssh, um diesen Befehl auszuführen. Der letztendlich aufgerufene ssh-Befehl entspricht diesem:
/path/to/ssh [ssh options...] "scp [scp options...]"
- /Pfad/zu/ssh ist normalerweise ein integrierter Pfad zum SSH-Programm.
- [SSH-Optionen…] ist eine oder mehrere Optionen für das SSH-Programm.
- „scp [scp-Optionen ...]“ ist ein einzelnes Argument, das den scp-Befehl und seine Argumente zur Ausführung auf dem Remote-System enthält.
OpenSSH scp bietet nicht viele Optionen, um die Form des Remote-scp-Befehls zu ändern. Es gibt keine Möglichkeit, etwas anderes als „scp“ aufzurufen oder etwas wie „sudo“ vor den „scp“-Teil einzufügen.
Wie Sie bemerkt haben, bietet scp die Möglichkeit, ein anderes Programm als ssh aufzurufen. Jemand, der weiß, wie das geht, könnte ein SSH-Wrapperprogramm schreiben und scp den Wrapper aufrufen lassen, anstatt ssh direkt aufzurufen. Der Wrapper müsste seine Befehlszeilenargumente untersuchen, um dasjenige zu finden, das den scp-Befehl enthält, den Befehl wie gewünscht ändern und dann ssh mit den geänderten Befehlszeilenargumenten aufrufen.
Antwort2
So funktioniert SCP
Die internen Abläufe von scp
hängen von zwei nicht dokumentierten Formen von ab scp
, nämlich scp -f
und scp -t
. Dabei handelt es sich im Grunde genommen um Remote-Server, die auf stdin hören und Daten über stdout generieren. Diese Prozesse verwenden ein Protokoll, das dem von sftp ähnelt. Weitere Informationen finden Sie unterOracle Blog.
Beim scp
Start wird zuerst eine SSH-Sitzung gestartet, um scp -t
oder zu starten scp -f
. Ihr lokaler scp
Prozess kommuniziert dann mit dem Remote- scp
Prozess über stdout und stdin, die an ssh weitergeleitet werden (vollständig verschlüsselt) und dient als stdin/stdout für Ihre Remote- scp
Sitzung.
So passen Sie an
Der scp
Befehl bietet eine Option -s
, mit der Sie das Programm anpassen können, das zum Einrichten der Remote- scp
Sitzung verwendet wird. Es wird erwartet, dass es alle für typischen Optionen unterstützt ssh
. Um zu helfen, zu debuggen, wie das aussehen könnte, richten wir ein Dummy-Programm ein, das nur die Parameter ausgibt:
/tmp/scp-dump.sh:
echo $0 $*
Wir werden es wie folgt ausführen:
scp -S /tmp/scp-dump.sh /tmp/dump.txt [email protected]:/tmp
Und passend dazu erhalten wir folgende Ausgabe:
/home/me/dump.sh \
-x -oForwardAgent=no \
-oPermitLocalCommand=no \
-oClearAllForwardings=yes \
-l me -- server.com scp -t /tmp
Zur besseren Lesbarkeit wurden Zeilenumbrüche mit Backslash hinzugefügt.
Dadurch haben wir die Möglichkeit, die Parameter und Befehle zu ändern, bevor wir sie an den ssh
Befehl senden.
Einrichten von sudo
Jetzt können wir ein Programm schreiben, um die Parameter nach Bedarf zu ändern, SSH zu starten und eine geänderte Form zum Starten zu verwenden scp -t
. Wir erfassen grundsätzlich die Parameter, fangen diejenigen ab, die wir intern verwenden möchten, fügen nur zusätzliche hinzu und nehmen Änderungen vor.
/tmp/scp-sudo.sh
:
add_ssh_option() {
local option
if [ $# = 2 ]; then
option="$1 \"$2\""
else
option="$1"
fi
if [ -z "${ssh_options}" ]; then
ssh_options=${option}
else
ssh_options="${ssh_options} ${option}"
fi
}
parse_options() {
ssh_options=
local option
while [ $# > 0 ] ; do
case $1 in
-oSudoUser=* )
SSH_SUDO_USER=${option##*=}
shift
;;
-l ) ssh_user=$2 ; shift 2 ;;
-i ) add_ssh_option "$1" "$2" ; shift 2 ;;
-- ) shift ; break ;;
-* ) add_ssh_option "${1}" ; shift ;;
* ) break ;;
esac
done
ssh_host=$1
shift
ssh_command="$*"
}
parse_options "$@"
# To avoid intererence with Standard-In, we change this to
# Strict:
add_ssh_option "-oStrictHostKeyChecking=yes"
if [ -z "${SSH_SUDO_USER}" ]; then
# As before without sudo
cat | ssh $ssh_options -l $ssh_user $ssh_host $ssh_command
exit $?
else
# Send standard-in to the customized "scp -t" sink.
cat | ssh $ssh_options -l $ssh_user $ssh_host sudo -i -u ${SSH_SUDO_USER} $ssh_command
exit $?
fi
Jetzt können wir das geänderte SCP-Formular verwenden:
scp -oSudoUser=other \
-i /tmp/me-id_rsa \
/tmp/scp-sudo.sh \
/tmp/dump.txt \
[email protected]:/tmp
Das funktioniert gut, wenn man eine Datei an eine Remote-Remote-Verbindung sendet. Wenn ich jedoch eine Remote-Datei abrufe, bleibt sie irgendwie hängen. Wenn ich die Sitzung unterbreche (Strg+C), sehe ich zwar, dass die Übertragung erfolgreich war, aber ich habe irgendwie eine zusätzliche Datei mit dem Namen „0“. Kann mir wohl jemand dabei helfen?
Bessere Option: sftp
SFTP ist jedoch viel besser.
- es hat die
-S
Option, die gesamte SSH-Befehlszeile festzulegen. Ich hatte Probleme, das herauszufinden und zum Laufen zu bringen. Ich vermute, dass ich nicht verstehe, wie man stdin/stdout innerhalb eines Shell-SSH-Wrappers richtig bindet. - Es gibt eine
-s
Option (in Kleinbuchstaben), mit der nur der Unterbefehl festgelegt werden kann, der nur für die Einrichtung des Remote-Servers zuständig ist. Ich fand, dass es damit einfacher funktioniert. - Sie können den Remote-Pfad und die Remote-Dateiberechtigungen festlegen sowie Put/Get usw. gemäß den Manpages für SFTP ausführen.
In diesem Fall müssen wir einfach
sftp -s "sudo -u sudo-user -- /usr/libexec/openssh/sftp-server" [email protected]
Das gab mir die glückliche " sftp>
" Aufforderung
Beachten Sie, dass sich das Unterprogramm manchmal in unterschiedlichen Pfaden befindet, z. B. /usr/libexec/openssh/sftp-server
. Ich würde vorschlagen, die Subsystem sftp
Zeichenfolge " " innerhalb der /etc/ssh/sshd_conf
Datei zu analysieren.