Bashスクリプトのパスワードを使用してsftpコマンドを実行する方法


173

Linuxホストからsftpを使用してログファイルをリモートホストに転送する必要があります。オペレーショングループから同じものの資格情報が提供されています。ただし、他のホストを制御できないため、RSAキーを生成して他のホストと共有することはできません。

ではsftpcronジョブを介してBashスクリプト内からコマンドを(提供されたユーザー名/パスワードを使用して)実行する方法はありますか?

同様のスタックオーバーフローの質問、Bashスクリプトsftpのパスワードを指定するを見つけましたが、私の問題に対する満足のいく答えはありませんでした。

回答:


178

公開鍵認証を使用する以外に、いくつかのオプションがあります。

  1. キーチェーンを使用
  2. sshpassを使用します(安全性は低くなりますが、おそらく要件を満たします)
  3. expectを使用します(安全性が最も低く、コーディングが必要です)

sshpassにチャンスを与えることにした場合、これを行うための実用的なスクリプトスニペットを次に示します。

export SSHPASS=your-password-here
sshpass -e sftp -oBatchMode=no -b - sftp-user@remote-host << !
   cd incoming
   put your-log-file.log
   bye
!

3
:Mac上でそれを使用するためのstackoverflow.com/questions/9102557/...
anubhava

18
エクスポートする必要はないと思います。SSHPASS=password sshpass -e ...すべきです
イェンス

9
:私は、ログファイルdowloadするワンライナーを行うことができましたsshpass -p "my_password" sftp -oPort=9999 user@host:dir/file.log
クラウド職人

6
@gorus:ワンライナーはとてもかっこいいですが、スヌーピングのリスクが高まるため、コマンドラインでパスワードを使いたくありませんでした。
anubhava 2013年

8
-oBatchMode=no私にとって欠けていた欠片でした。
richardkmiller 2014

98

別の方法はlftpを使用することです:

lftp sftp://user:password@host  -e "put local-file.name; bye"

この方法の欠点は、コンピューター上の他のユーザーがツールなどからパスワードを読み取るpsことができ、パスワードがシェル履歴の一部になる可能性があることです。

LFTP 4.5.0以降で利用できるより安全な代替手段は、LFTP_PASSWORD環境変数を設定し、でlftpを実行することです--env-password。ここに完全な例があります:

LFTP_PASSWORD="just_an_example"
lftp --env-password sftp://user@host  -e "put local-file.name; bye"

LFTPには、クールなミラーリング機能も含まれています(転送の確認後に削除を含めることができます--Remove-source-files)。

lftp -e 'mirror -R /local/log/path/ /remote/path/' --env-password -u user sftp.foo.com

9
代替案を提案するための+1ですが、コマンドラインでのパスワードの入力を回避できますか?
anubhava 2013

1
同じコンピューター上の誰にでもパスワードを表示することに
反対の投票

10
lftpのスクリプトファイルを作成できます。これにより、コマンドラインでパスワードを入力する必要がなくなります。ファイルの作成put-scriptopen sftp://user:password@host; put local-file.name; exit 実行よりlftp -f put-script この方法では、コマンドラインにユーザー名とパスワードを入力する必要はなく、スクリプトファイルへの制限付きのアクセス許可を設定できます。
obaranovsky 2015年

@obaranovskyそれは良い考えです。これをエイリアスまたは関数として環境変数に追加するとしたら、安全で他のユーザーから非表示にすることはできますか?
sdkks 2017

1
lftpsftpをいじるよりもはるかに簡単sshpassです。いい答えだ。
MeanEYE

53

Expectは優れたプログラムです。

Ubuntuでは、次のようにインストールします。

sudo apt-get install expect

CentOSマシンにインストールする場合:

yum install expect

sftpサーバーに接続して、ローカルマシンからリモートsftpサーバーにローカルファイルをアップロードするとします。

#!/usr/bin/expect

spawn sftp username@hostname.com
expect "password:"
send "yourpasswordhere\n"
expect "sftp>"
send "cd logdirectory\n"
expect "sftp>"
send "put /var/log/file.log\n"
expect "sftp>"
send "exit\n"
interact

これにより、サーバーへのパスワードでsftp接続が開きます。

次に、ファイルをアップロードするディレクトリ、この場合は「logdirectory」に移動します

これにより、/ var / log /にあるローカルディレクトリからファイル名がfile.logのログファイルがリモートサーバーの「logdirectory」にアップロードされます。


あなたの答えをありがとう、私はこのタスクを達成するための私の選択肢の1つとして期待していました。
anubhava 2013年

ありがとうございました。私はあなたの答えを検索で見つけ、それを使用し、期待通りにスクリプトを作成しました。ポタリティのスクリプトを投稿しました
rezizter

回答いただきありがとうございます。すでに賛成しています:)
anubhava 2013年

これを使用して、ssh秘密鍵のパスフレーズを入力しています。すべてのサーバーに同じ公開鍵を配置し、秘密鍵のパスフレーズを定期的にローテーションする方が便利です。
sdkks 2017

24

シェルスクリプトでlftpを対話的に使用して、次のようにして、パスワードが.bash_historyなどに保存されないようにすることができます。

vi test_script.sh

以下をファイルに追加します。

#!/bin/sh
HOST=<yourhostname>
USER=<someusername>
PASSWD=<yourpasswd>

cd <base directory for your put file>

lftp<<END_SCRIPT
open sftp://$HOST
user $USER $PASSWD
put local-file.name
bye
END_SCRIPT

ホスト、ユーザー、パス、およびディレクトリを編集してputファイルを入力した後、viエディターを書き込み/終了します。次に:wq、スクリプトを実行可能にchmod +x test_script.shして実行し./test_script.shます。


2
既存のファイルを上書きするには、lftp << END_SCRIPTの後に「set xfer:clobber on」を追加します
Balaji Natarajan

17

最近、サーバー間のファイル転送を保護するために、ftpからsftpに切り替えるように依頼されました。Tectia SSHパッケージを使用しています。これには--password、コマンドラインでパスワードを渡すオプションがあります。

例: sftp --password="password" "userid"@"servername"

バッチの例:

(
  echo "
  ascii
  cd pub
  lcd dir_name
  put filename
  close
  quit
    "
) | sftp --password="password" "userid"@"servername"

ヘルプコマンド(sftp -h)を実行する前にさまざまなWebサイトを見ていたので、この情報を共有する必要があると思い、パスワードオプションを見て驚いた。


9
+1をおすすめします。ただし、これにはコマンドラインでパスワードを渡す必要があり、コマンドを実行しているシステムの誰もがpsパスワードを見ることができます。
anubhava 2013

4
私はそれを試しました、私は得ましたunknown option -- - usage: sftp [-1246aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher] [-D sftp_server_path] [-F ssh_config] [-i identity_file] [-l limit] [-o ssh_option] [-P port] [-R num_requests] [-S program] [-s subsystem | sftp_server] host sftp [user@]host[:file ...] sftp [user@]host[:dir[/]] sftp -b batchfile [user@]host
cyber8200

1
@ihueおそらくOpenSSHではなくTechia SSHが必要なため
qris

17

パスワードレス認証を有効にすることで上書きできます。ただし、その前にキー(pub、priv)をインストールする必要があります。

ローカルサーバーで次のコマンドを実行します。

Local $> ssh-keygen -t rsa 

プロンプトが表示されたすべてのオプションでEnterキーを押します。値を入力する必要はありません。

Local $> cd .ssh
Local $> scp .ssh/id_rsa.pub user@targetmachine:
Prompts for pwd$>  ENTERPASSWORD

次のコマンドを使用してリモートサーバーに接続します

Local $> ssh user@targetmachine
Prompts for pwd$> ENTERPASSWORD

リモートサーバーで次のコマンドを実行します

Remote $> mkdir .ssh
Remote $> chmod 700 .ssh
Remote $> cat id_rsa.pub >> .ssh/authorized_keys
Remote $> chmod 600 .ssh/authorized_keys
Remote $> exit

ローカルサーバーで次のコマンドを実行して、パスワードなしの認証をテストします。パスワードなしで接続する必要があります。

$> ssh user@targetmachine

1
答えは+1ですが、質問は公開鍵/秘密鍵なしでそれを行うことでした。
anubhava 2014

おっと..キー共有の制限を見た:)
SriniV '20

好奇心lftp -p ${port} -u ${login_id},${password} ${ip_number}から、このコマンドはシェルスクリプトから呼び出されたときにどこに出力されますか?sshpassとは別にどのように解決しましたか?
SriniV 2014

私はMacとLinuxの両方を必要lftpとしませんsshpass
anubhava 2014

純金。ありがとう!:)
Nikolay Tsenkov

7

sshpassをロックダウンされた認証情報ファイルと組み合わせると、実際にはそれは何よりも安全です。認証情報ファイルを読み取るためのボックスのルートを持っている場合、すべての賭けはとにかくオフです。


5

sftpがパスワードを要求するのを待ってから送信するBashプログラム:

#!/bin/bash
expect -c "
spawn sftp username@your_host
expect \"Password\"
send \"your_password_here\r\"
interact "

プロンプトを受け取ったものと一致するように、expectをインストールし、「パスワード」の文言を小文字の「p」に変更する必要がある場合があります。ここでの問題は、パスワードがファイルとコマンド履歴にプレーンテキストで公開されることです。これは、そもそもパスワードを設定する目的にほとんど反するものです。


+1しかし、私はあなたがこのアプローチの問題が何であるかを明確に述べていると思います。
anubhava 2014

5

sshpassを使用できます。以下が手順です

  1. Ubuntuにsshpassをインストール- sudo apt-get install sshpass
  2. 初めての場合は、既知のホストファイルにリモートIPを追加します。Ubuntuの場合-> ssh user @ IP->「yes」と入力します
  3. scpとsshpassを組み合わせたコマンドを指定します。以下は、リモートTomcatへの戦争対処のサンプルコードです。 sshpass -p '#Password_For_remote_machine' scp /home/ubuntu/latest_build/abc.war #user@#RemoteIP:/var/lib/tomcat7/webapps
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.