telnet と expect でヤマハルーターなどの制御を自動化する

会社でもおうちでもヤマハルーターばかり使っているけーのです。ファームウェア更新のために保守契約とかしなくていいのが良いです。

法人向けのネットワーク機器って、telnetは開放されてるけどそれ以外の方法で外部からの制御はできないものが多い気がしますが、そんな機器達をちゃちゃっとコマンド制御できたら便利だなーというような時に使えるのが expect(1) です。10KB程度の小さなバイナリですが、シンプルで便利なヤツです。

expect(1) のインストール

Debianの場合はパッケージがあるので apt-get 一発です。だいたいメジャーなLinux distributionには入っていると思います。

$ sudo apt-get install expect

サンプル: telnet(1) と expect(1) でネットワーク機器のコマンド実行を自動化する

私が作って使っていたのは以下のようなスクリプトです。これを実行すると、RTX1200などのヤマハルーターでPPTPサービスを有効にすることができます。(他の設定は予め入れておいてね)

#!/usr/bin/expect
set timeout 5
spawn telnet router.example.com
expect "Password: "
send "**********\n"
expect "> "
send "administrator\n"
expect "Password: "
send "**********\n"
expect "# "
send "pptp service on\n"
expect "# "
send "save\n"
expect "# "
send "quit\n"
expect "> "
send "quit\n"

別途、pptp service onpptp service off にしたスクリプトを用意しておくと、オンオフがそれぞれコマンド一発でできるようになります。シェルの引数から切り替えもできるような気がするけど調べてない。

これはMS-CHAPv2の脆弱性が発見された時に作ったもので、当時のOSのVPNプロトコル対応状況的にPPTPが使用できないと面倒ということがありました。そこで、『使う時には一時的に有効にして終わったら無効にする』運用をしていました。つまり SSHで別のサーバーにログイン→PPTP有効化コマンドを実行する→PPTP接続する→作業する→終わったらPPTP無効化コマンドを実行する のようなことをしてました。まあたまにしか使わないのでこんなもんで十分だろうと。

expect(1) の活用

前述の通り、telnetとの組み合わせでHTTPやPOP3やSMTPなどのサーバーとお話できますし、シリアルコンソールなどもイケます。対話型のインターフェイスをサクサク自動化できるので、様々な活用方法があります。是非、活用していきたいですね。

追記: smbclient を使って引数で指定されたファイルを空にする

expect で引数を使ってるスクリプトが出てきたのでサンプルとして。インタラクティブな操作が必要になるCUIプログラムは大抵なんでも自動化できますね。

#!/usr/bin/expect

set timeout 5
set username [lindex $argv 0]
set password [lindex $argv 1]
set sharename [lindex $argv 2]
set txtfile [lindex $argv 3]
set indexfile [lindex $argv 4]
set emptyfile [lindex $argv 5]

spawn cp /dev/null $emptyfile
spawn smbclient -q -U $username $sharename
expect "Enter $username's password: "
send "$password\n"
expect "smb: \\\\> "
send "put $emptyfile $txtfile\n"
expect "smb: \\\\> "
send "put $emptyfile $indexfile\n"
expect "smb: \\\\> "
send "quit\n"