WinSCP ツールは、sudo
リモート マシン上でを実行してscp
、sudo ユーザーとして を実行できます。このことから、 のコマンド ライン バージョンでscp
もこれが可能であるはずだと私は考えます。
秘密裏に、WinSCP はこれをどのように実行しているのでしょうか?
私はやりたくないユーザーステージングディレクトリを使用したソリューションファイルが大きすぎるため、ユーザーを使用して直接投稿する必要がある可能性がありますsudo
。その結果、ファイルはコピーされましたが、sudo ディレクトリではなく、ローカル ディレクトリにコピーされました。
一つの解決策としては、手動でSSH経由でパイプする:
tar zcvf - MyBackups | ssh user@server "cat > /path/to/backup/foo.tgz"
次のように sudo を実行するようにカスタマイズできると思います。
cat local.txt | ssh user@server "sudo -u sudouser cat > ~/remote_file"
唯一の問題は、この方法を実行すると、ベースを使用してすでに実装されている多くの問題を解決しなければscp
ならないことです。このため、およびその他の理由から、このソリューションも使用したくありません。
ユーザーを変更してその権限にアクセスできるようにし、scp
リモートへの直接コピーを処理できるようにするにはどうすればよいでしょうか。sudo
答え1
Scp は、リモート サーバーに ssh 接続し、その接続を使用してscp
リモート システムで別のコマンドを実行することによって機能します。ローカルの scp インスタンスとリモート インスタンスは、ssh リンクを介して通信し、ファイルを送受信します。
特に OpenSSH scp は、リモート システムで実行される scp コマンド文字列を構築します。次に、そのコマンドを実行するために ssh を起動します。最終的に呼び出される ssh コマンドは、次のものと同等です。
/path/to/ssh [ssh options...] "scp [scp options...]"
- /path/to/ssh は通常、ssh プログラムへの組み込みパスです。
- [ssh オプション...] は、ssh プログラムに対する 1 つ以上のオプションです。
- 「scp [scp オプション...]」は、リモート システムで実行する scp コマンドとその引数を含む単一の引数です。
OpenSSH scp では、リモート scp コマンドの形式を変更するオプションはあまり提供されていません。「scp」以外のものを呼び出す方法や、「scp」の部分の前に「sudo」のようなものを挿入する方法はありません。
ご存知のとおり、scp には ssh 以外のプログラムを呼び出すオプションがあります。方法を知っている人なら、ssh ラッパー プログラムを作成して、scp に ssh を直接呼び出す代わりにラッパーを呼び出させることができます。ラッパーは、コマンドライン引数を調べて scp コマンドを含む引数を見つけ、必要に応じてコマンドを変更し、変更したコマンドライン引数で ssh を呼び出す必要があります。
答え2
SCPの仕組み
の内部動作は、とというscp
2 つの文書化されていない形式に依存します。これらは基本的に、stdin をリッスンし、stdout を介してデータを生成するリモート サーバーです。これらのプロセスは、sftp が行うのと似たプロトコルを使用します。詳細については、scp
scp -f
scp -t
Oracle ブログ。
が起動すると、最初にまたは をscp
開始するための ssh セッションが開始されます。次に、ローカル プロセスは stdout および stdin を介してリモート プロセスと通信し、ssh にパイプされ (完全に暗号化されます)、リモート セッションの stdin/stdout として機能します。scp -t
scp -f
scp
scp
scp
カスタマイズ方法
このコマンドには、リモート セッションのセットアップに使用するプログラムをカスタマイズできるscp
オプションがあります 。 の一般的なオプションをすべて処理することが期待されます。それがどのように見えるかをデバッグするために、パラメータをダンプするだけのダミー プログラムを設定します。-s
scp
ssh
/tmp/scp-dump.sh:
echo $0 $*
以下のように実行します。
scp -S /tmp/scp-dump.sh /tmp/dump.txt [email protected]:/tmp
そして、適切に次の出力が得られます。
/home/me/dump.sh \
-x -oForwardAgent=no \
-oPermitLocalCommand=no \
-oClearAllForwardings=yes \
-l me -- server.com scp -t /tmp
読みやすくするために、バックスラッシュによる改行が追加されました。
これにより、コマンドに送信する前にパラメータとコマンドを変更する機会が得られますssh
。
sudoの設定
これで、必要に応じてパラメータを変更し、ssh を起動し、変更されたフォームを使用して を起動するプログラムを作成できますscp -t
。基本的には、パラメータをキャプチャし、内部で使用したいパラメータのみをトラップして、追加のパラメータを追加し、変更を加えます。
/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
これで、修正された scp フォームを使用できるようになりました。
scp -oSudoUser=other \
-i /tmp/me-id_rsa \
/tmp/scp-sudo.sh \
/tmp/dump.txt \
[email protected]:/tmp
これはリモートにファイルを送信するにはうまく機能します。しかし、リモート ファイルを取得すると、何らかの理由でハングします。セッションを中断すると (control-c)、転送が成功したことがわかりますが、どういうわけか「0」という名前の余分なファイルがあります。誰か助けてくれる人はいませんか?
より良い選択肢: sftp
しかし、sftp の方がはるかに優れています。
- これには、ssh コマンドライン全体を設定するオプションがあります
-S
。これを理解して動作させるのに苦労しました。shell-ssh ラッパー内から stdin/stdout を正しくバインドする方法がわからないのではないかと思います。 - これには (小文字の) オプションがあり
-s
、リモート サーバーの設定のみを担当するサブコマンドのみを設定できます。これを使用すると、動作が簡単になりました。 - sftp のマニュアル ページに従って、リモート パス、リモート ファイルの権限を設定し、put/get の両方を実行できます。
この場合は単純に
sftp -s "sudo -u sudo-user -- /usr/libexec/openssh/sftp-server" [email protected]
それで私は嬉しい「sftp>
」プロンプトを受け取りました
サブプログラムは異なるパスに配置される場合があることに注意してください (例 ) 。ファイル内の " " 文字列/usr/libexec/openssh/sftp-server
から解析することをお勧めします。Subsystem sftp
/etc/ssh/sshd_conf