web-dev-qa-db-ja.com

多数のルーターのパスワードチェックを自動化するためのexpectスクリプトの使用

手元のタスクは、多数のルーターのパスワードを確認し、パスワードがデフォルトに設定されている場合はパスワードを変更することです。つまり、ログイン:ABC、パスワード:ABCなどです。

このためのexpectスクリプトを作成しましたが、少し問題が発生しました。

コードは次のとおりです。

#!/usr/bin/expect -f

spawn telnet 10.15.160.69 #using a test IP, later it will read IP's from a list.

expect {

 "Login: " {
   send "ABC\r"
   exp_continue
  }
 "Password: " {

    send "ABC\r"
    exp_continue
  }

  "> " {

    send "passwd\r"
    expect "Username: "
    send "ABC\r"
    expect "Password: "
    send "ABC\r"
    expect "New Password: "
    send "n3wp@ss\r"
    expect "Confirm New Password: "
    send "n3wp@ss\r"
    expect "> "
    send "save\r"

  }
}

現在、ルーターには、パスワードを3回試行してもログアウトしないという独特の動作があり、正しい資格情報が提供されるか、Ctrl+D(EOF)が押されるまで、ログインとパスワードの入力を求め続けます。

下記を参照してください:

Trying 10.15.160.69...
Connected to 10.15.160.69.
Escape character is '^]'.
BCM96816 Broadband Router
Login:     
Password: 
Login incorrect. Try again.
Login: 
Password: 
Login incorrect. Try again.
Login: 
Password: 
Authorization failed after trying 3 times!!!.

Login: Password: 
Login incorrect. Try again.
Login: 
Password: 
Login incorrect. Try again.
Login: 
Password: 
Authorization failed after trying 3 times!!!.
Login: 
Password: 
Login incorrect. Try again.

スクリプトでeofを送信すると、スクリプトは完全に終了します。

期待スクリプトはbashスクリプトから呼び出されます。

#!/bin/bash

for Host in $(cat ipnmap.txt);do
echo "${Host}";

/usr/bin/expect passchange1.sh $Host
done

同じ機能をexpectで実装できることはわかっていますが、好みとしてbashで実装しました。

必要なのは、ルーターが2回目に資格情報を要求するとすぐに、スクリプトが次のIPに移動することです。これは、最初に成功しなかった場合、ルーターが失敗したことを意味するためです。デフォルトのパスワードがあり、それが必要です。次のIP /ルーターに移動できます(ルーターにデフォルトのユーザー名/ルーターがある場合にのみ、パスワードの変更が必要です)。

この問題を解決するために提供できるガイダンスをいただければ幸いです。ありがとうございました

3
Mustafa Mujahid

すべてを単一のexpectステートメントに入れる代わりに、ログインの各部分を別々の一致に単純に広げることができます。特に、取得するシーケンスがわかっている場合は、多くの可能な応答にすべて対処する必要はありません。一度。例えば:

#!/usr/bin/expect 
proc abort { } { send_user "Timeout!" ; exit 2 }
set address [lindex $argv 0]
spawn telnet $address
expect timeout abort "Login: " 
set timeout 5
send "ABC\r"
expect timeout abort "Password: "
send "ABC\r"
expect timeout abort  "Login incorrect" exit  "> "
send "passwd\r"
expect timeout abort "Username: "
send "ABC\r"
expect timeout abort "Password: "
send "ABC\r"
expect timeout abort "New Password: "
send "n3wp@ss\r"
expect timeout abort "Confirm New Password: "
send "n3wp@ss\r"
expect timeout abort "> "
send "save\r"
expect timeout abort "> "
send "quit\r"
expect timeout abort eof

このスクリプトは関数abortを作成します。この関数は、メッセージを出力し、呼び出されると戻りコード2で終了します。変数addressをスクリプトに渡される最初のパラメーターに設定します。 telnetコマンドを起動し、ログインプロンプトに対してexpectを実行するか、タイムアウトを実行します(デフォルトのタイムアウトは10秒です。たとえば、後で5に設定します)。 timeoutは、パターンではなく特別なキーワードです。 expectコマンドの形式はpattern command pattern command ...です。最後のコマンドは省略でき、スクリプトの次の行に移動することを意味します。これは、同等の複数行と同じです。

expect {
  timeout abort
  "Login incorrect" exit 
  "> " 
}

ログインプロンプトが表示されない場合、タイムアウトによって中止が呼び出されて終了します。bashスクリプトでこの失敗をテストできます。

プロンプトが表示された場合は、ユーザーIDを送信してから、パスワードを送信します。 「ログインが正しくありません」と表示された場合は、パスワードがデフォルトではないことを意味するため、終了します(終了コード0)。それ以外の場合は、ログインして>プロンプトを表示し、構成を続行します。最後に、quitなどの便利なコマンドを送信して接続を完全に閉じることができ、expect eofは閉じるのを待ちます。

1
meuh