メインコンテンツへスキップ
検索
前回のブログでは、FTPを使ったファイル転送の自動化についてお話しました。FTPを使うことには3つの問題があります。第一に、パスワードがクリアテキストでネットワーク上に送信され、プロトコルアナライザを持っている人なら誰でも利用できるようになります。第二に、あなたのデータもクリアテキストで送信されます。3つ目は、モジュールのどこかにパスワードを記録しなければならないことです。これらの問題のため、多くのサイトでは FTP の代わりに SSH の安全な FTP サブシステムである SFTP を使用することを義務づけているか、あるいは義務づけようと考えています。しかし、コマンドマクロで ftp を sftp に置き換えることはできません (図 1)。

 

&attach_input
sftp 172.16.1.116
nd
MYPASSWORD
put foo
&if (command_status) ^= 226 &then &goto ERROR1
get bar
&if (command_status) ^= 226 &then &goto ERROR2
quit
&
&label ERROR1
..display_line Could not put file
quit
&return
&
&label ERROR2
..display_line Could not get file
quit
&return

図 1 - sftp1.cm - コマンドマクロで ftp コマンドを sftp に置き換えたもの

 

sftp1
Connecting to 172.16.1.116...
dup2: Bad file number.
Error on line 3 of sftp1.
command_processor: Object not found. nd. In command macro
%phx_vos#m15_mas>SysAdmin>Noah_Davids>sftp1.cm
ready  12:39:59

 

図 2 - sftp1.cm の実行
問題は、VOSのネイティブコマンドとPOSIXのオープンソースの入力の扱い方の非互換性です。しかし、SFTPはFTPのように、リクエストのリストを持つファイルを作成することができます(図3)が、それは自動的に実行されます(図4)。

 


put foo
get bar

 

図 3 - sftp2.input - sftp の実行要求を含むファイル

 


sftp -b sftp2_input nd@172.16.1.116
nd@172.16.1.116's password:
sftp> put foo
Uploading foo to /SysAdmin/Noah_Davids/foo
sftp> get bar
Couldn't stat remote file: No such file or directory
File "/SysAdmin/Noah_Davids/bar" not found.
Ready  13:06:45

 

図4 - リクエストの入力ファイルとパスワードプロンプトでの実行
図 4 を見ると、sftp がパスワードの入力を求めていることがわかります。入力ファイルにパスワードを入力する方法はありません。パスワードプロンプトを回避する唯一の方法は、公開鍵認証を使用することです (図 5)。

 

sftp -b sftp2_input nd@172.16.1.116
sftp> put foo
Uploading foo to /SysAdmin/Noah_Davids/foo
sftp> get bar
Couldn't stat remote file: No such file or directory
File "/SysAdmin/Noah_Davids/bar" not found.
Ready  13:12:28

 

図 5 - 公開鍵認証を使用したリクエストの入力ファイルでの実行、パスワードプロンプトの削除

 

公開鍵認証の設定方法についてはこちらの記事をご覧ください - http://members.cox.net/ndav1/self_published/publickey_authentication_setup.html

残念ながら、sftp は入力ファイル内のすべての要求を次々と実行してしまうので、転送がうまくいったかどうかをテストする仕組みがありません。

コマンドマクロが使えないので、何か代替案はありますか?gnu_tools 製品には expect というプログラムが同梱されています。これを使ってコマンドを送信したり、様々なレスポンスを待ったり、 出力ストリームで見たものに基づいて何かをしたりすることができます。私は expect の専門家ではありませんが、図 6 のスクリプトはあなたが始めるのに役立つでしょう。ウェブで"expect スクリプト"を検索すると、私の単純な例をカスタマイズするのに役立つ参考文献がたくさん見つかります。

 

# If we get an end-of-file (eof) it means that the sftp process
# terminated. Report the last command that was sent.
#
proc goteof {cmd} {
puts "sftp connection unexpectedly closed n"
puts "last text received wasn"
puts "<<"
puts $cmd
puts ">>nnn"
exit
}
# この手続きはキー文字列の正規表現マッチを行います
実行されたコマンドから収集された出力の中に # が含まれています。この場合
# 私はただエラーの種類を報告しているだけですが、他のこともできます
と同じように#もチェックしています。私も2つのエラーしかチェックしていません。他にもあります。があるでしょう。
# をクリックして追加してください。
#
proc checkforerrors {buf cmd} {...
if [regexp {.*not found} $buf] {.
puts "$cmd FAILED : not foundnnn"
復帰1
}
if [regexp {.*Permission denied} $buf] {.
puts "$cmd FAILED : access problemsnnn"
復帰1
}
還る
}# タイムアウトがないように-1に設定します。デフォルトは10秒です。
# と、ほとんどのファイル転送にはそれよりも時間がかかります。を設定しないことにしました。
# タイムアウトは変更可能です
セットタイムアウト-1

# start sftp
spawn sftp nd@172.16.1.116

# sftpのプロンプトを待ちますが、認証プロンプトが表示されたら、最後に
# yes/no でセキュリティ問題を報告して終了します。
期待する
"yes/no?"{ puts
"nnn間違ったサーバーに接続されたか、サーバーがリロードされました。"
puts
"このスクリプトを再度実行するには、サーバーキーを検証する必要があります.nnn"
終了 }。
sftp>
}

テストに適したディレクトリに変更します。
send "cd sftp_testr"
期待値 {
eof { goteof "cd sftp_test" }.
sftp>
}

# call check for errors passing it all collected characters up the
# sftp> プロンプトが表示されます。また、sftp に送信されたコマンドも表示されます。もし
# checkforerrorsプロシージャが1を返したら、スクリプトを終了します。ここでも、以下のことができます。
# 他のことができます。
if {[checkforerrors $expect_out(buffer) "cd sftp_test"] == 1}.{ exit }.

send "put foor"
expect {
eof { goteof "put foo" }.
sftp>
}
if {[checkforerrors $expect_out(buffer) "put foo"] == 1}.{ 出口 }。

send "get barr"
expect {
eof { geteof "get bar" }.
sftp>
}
if {[checkforerrors $expect_out(buffer) "get bar"] == 1}.{ 出口 }。

辞令を出す
勘ぐってしまう
script donenn"を置く

 

図 6 - sftp3.exp - SFTP を自動化するスクリプトを期待する

 

expect sftp3.exp
spawn sftp nd@172.16.1.116
Connecting to 172.16.1.116...
The authenticity of host 172.16.1.116(172.16.1.116)' can't be established
+.
RSA key fingerprint is 37:f4:1a:56:64:af:ab:8a:7c:0b:36:47:c5:6c:1d:1a.
Are you sure you want to continue connecting (yes/no)?
間違ったサーバーに接続してしまったのか、サーバーがリロードされてしまいました。
このスクリプトを再度実行するには、サーバーキーを検証する必要があります。

 

図 7 - セキュリティ警告のある sftp3.exp expect スクリプトの実行

 

expect sftp3.exp
spawn sftp nd@172.16.1.116
Connecting to 172.16.1.116...
sftp> cd sftp_test
sftp> put foo
Uploading foo to /SysAdmin/Noah_Davids/sftp_test/foo
sftp> get bar
リモートファイルを統計できませんでした。そのようなファイルまたはディレクトリがありません
ファイル"/SysAdmin/Noah_Davids/sftp_test/bar"が見つかりません。
sftp> get bar FAILED : not foundready 10:42:11

 

図 8 - sftp3.exp expect スクリプトを警告なしで実行しましたが、転送に失敗しました。

最後に、私はFTPブログで、FTPがまだ開いているファイルを読み取ることができ、これが時折不完全なファイルが転送される結果となっていることに触れましたが、FTPマクロがある場所でファイルが現れるのを待ってから転送する場合、マクロはファイルがロックされていないことを確認する必要があることを提案しました。SFTPでも同じ問題が発生する可能性があり、解決方法は同じです。コマンドマクロの中にファイルロックチェックを配置し(図9)、ファイルがロックされなくなったら適切なスクリプトでexpectをコールすればよい。

&label AGAIN
&if (exists new_file) = 1 & (locked new_file) = 0 &then &goto EXPECT
display_line new_file not ready for transfer as of (time)
sleep -seconds 15
&goto AGAIN
&
&
&label EXPECT
expect sftp3.exp

 

図 9 - expect を呼び出す前のファイルロックのコマンドマクロテスト
メニューを閉じる

© 2020ストラタステクノロジー.