夜明け前の最も暗いとき

技術的なやったことをメモするブログ

ZabbixのMapからteratermで自動ログインする

ネットワーク機器も増えてきたこともあり、監視する必要がでてきたためにZabbixを使っています。MAP画面を使うと装置のつながりが一目で分かります。

f:id:jianlan:20190206002145j:plain
zabbix map
普段はWindowsTeratermを使っているので、マップから起動してログインできると便利です。ということで、ブラウザからローカルのexeファイルを実行する方法を調べたのですが、セキュリティの観点から禁止されているようです。Internet ExplorerであればActiveXを使うことでJavaScriptから呼び出せるようですが、IEはサポートされなくなるため別の方法を考えます。

ブラウザから次のようにプロトコルを指定したリンクを使うことにより特定のプログラムを実行させることができます。

telnet://localhost/

この例ではtelnet接続のためのクライアントが起動し、localhostへ接続しようとします。どのプログラムが起動するかはレジストリに記述されています。regeditを使って下記のレジストリを確認します。

[HKEY_CLASSES_ROOT\telnet\shell\open\command]
(規定)="C:\Windows\System32\rundll32.exe" "C:\Windows\System32\url.dll",TelnetProtocolHandler %l

この規定の値を変更してみます。

[HKEY_CLASSES_ROOT\telnet\shell\open\command]
(規定)="C:\Python\Python35\python.exe" "C:\usr\script\show_args.py" %l

なお、show_args.pyは次のようになっています。

import sys
import msvcrt

print('# of arguments:', len(sys.argv))
print('arguments:', str(sys.argv))

msvcrt.getch()

telnetのリンクをクリックすると次のように表示されます。

# of arguments: 2
arguments: ['C:\\usr\\script\\show_args.py', 'telnet://localhost/']

引数としてエンコードされたURL文字列自身が渡されます。したがって、次のように処理をします。

  1. zabbixのマップからtelnetリンクを生成
  2. telnetリンクをクリック
  3. レジストリに登録されたプログラムを起動
  4. URLエンコードされた文字列を処理
  5. teratermマクロでログイン処理を実行する

まずは、マップのURLsにリンクを張ります。

f:id:jianlan:20190210204138p:plain
Zabbix Map Edit element

URLsのNameとURLを設定します。URLはCGIIPアドレスとユーザ名を渡します。今回は次のようにします。

http://localhost/macro/login.cgi?type=≪実行するマクロ名≫&ip=≪ip アドレス≫&args=≪ユーザ名≫
---
http://localhost/macro/login.cgi?type=ssh_login&ip=192.168.11.10&args=jinglan

参照先のCGIは以下のようになっています。

#!/usr/bin/perl
use strict;
use warnings;
use CGI;

# クエリパラメータ取得
my $query = new CGI;
my $telnet_url = 'localhost/'.$query->param('type').'.ttl '.$query->param('ip').' '.$query->param('args');

# レスポンスヘッダの出力
print "Content-type: text/html", "\n\n";

# HTMLの出力
my $buff =<<"EOM";
<!DOCTYPE html> 
<html>
<head>
  <meta http-equiv="Pragma" content="no-cache">
  <meta http-equiv="Cache-Control" content="no-cache">
  <script language="javascript">
    function main() 
    {
       document.location.href = "telnet://$telnet_url";
       //history.go(-1);  //Chromeだとうまく動作しないのでコメントアウト
    }
  </script>
  <title>Login</title>
</head>
<body onload="main()"></body>
</html>
EOM

print $buff;

このスクリプトはHTMLページを作成し、telnet://のアドレスへ自動的にリダイレクトします。これにより、レジストリに登録されたプログラムが実行されます。レジストリへの登録は下記の内容を.regファイルにするとダブルクリックで変更できるので簡単です。

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\telnet\shell\open\command]
@="\"C:\\Program Files (x86)\\teraterm\\ttpmacro.exe\" C:\\usr\\script\\login.ttl %l"

telnetプロトコルteratermマクロに関連付け、C:\usr\script\login.ttlを実行しています。login.ttlの内容は以下のようになっています。

arg_str = param2
strreplace arg_str 1 'telnet://localhost/' ''
do
  strreplace arg_str 1 '%20' ' '
loop while result = 1
strsplit arg_str ' '

SSH_CONN_PARAM = ""
strconcat SSH_CONN_PARAM groupmatchstr3
strconcat SSH_CONN_PARAM "@"
strconcat SSH_CONN_PARAM groupmatchstr2

include "Login_ManagementServer.ttl"
sendln "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null " SSH_CONN_PARAM

ブラウザによるURLエンコードでスペースが%20に変換されるため、置換で戻しています。また、telnet://localhost/は不要なので削除しています。踏み台サーバ(Linux)にログインした後、sshコマンドで接続しています。

以上でMAPからワンクリックでパスワード入力まで自動化させることができました。注意点として、Windowstelnetプロトコルの処理を変更しているのでセキュリティには留意する必要があります。