メインコンテンツへスキップ

OpenVOSアーキテクチャでは、X.25通信用のNIO、ファイバーチャネルディスクアレイコントローラ、電源用UPS、IP経由のRSN用RSNインターネットコンソールサーバー、そしてこれらすべてのシステムがプライベートなEthernet/IPネットワーク上で通信できるようにするメンテナンス用イーサネットスイッチなど、いくつかの独立したシステムが利用されています。これらのシステムは、正常に動作していることを確認するために、さまざまなOpenVOSプロセスによって監視されています。しかし、ユーザーのログインなどの一部のイベントは監視対象外となっています。 RSNコンソールとネットワークスイッチには、誰かがログインしたりログインを試みたりするたびに、ログサーバーへメッセージを送信するオプションがあります。 ネットワークスイッチはStratusモジュールにのみ接続されているため、Stratusモジュール上でロギングサーバーを実行するのが合理的です。そのために、私は非常にシンプルなロギングサーバーを作成しました。このサーバーは、受信したメッセージに日時スタンプとメッセージ送信元のホストのIPアドレスを付加して、標準出力に書き出すだけです。このサーバーを起動プロセスとして実行することで、メッセージをプロセスのアウトファイルに保存することができます。

ネットワークスイッチの例
権限を持つ誰かが、ネットワークスイッチにrootとしてログインする際にrootパスワードの入力に手間取っていただけかもしれませんし、あるいは単にパスワードを当てるのが非常に上手なだけかもしれません。


2011-10-02 11:55:39 : 10.10.1.75 : >%AAA-W-REJECT: ユーザー「root」による新しいtelnet接続、送信元 10.10.1.1、宛先 10.10.1.75  拒否されました

2011-10-02 11:56:03 : 10.10.1.75 : >%AAA-W-REJECT: ユーザー ro による新しい Telnet 接続、送信元 10.10.1.1、宛先 10.10.1.75  拒否されました

2011-10-02 11:56:08 : 10.10.1.75 : >%AAA-I-CONNECT: ユーザー ro に対する CLI セッション(Telnet 経由)、送信元 10.10.1.1、宛先 10.10.1.75 受理

システム管理者のユーザーIDを推測している人がいます


2011-10-02 12:03:13 : 10.10.1.75 : >%AAA-W-REJECT: ユーザー「r admin」による新しいtelnet接続、送信元 10.10.1.1、宛先 10.10.1.75  拒否

2011-10-02 12:03:30 : 10.10.1.75 : >%AAA-W-REJECT: ユーザー 'sysadmin' による新しい Telnet 接続(送信元 10.10.1.1、宛先 10.10.1.75)が拒否されました

2011-10-02 12:04:39 : 10.10.1.75 : >%AAA-W-REJECT: 管理者による新しい Telnet 接続の要求です。
+送信元 10.10.1.1 宛先 10.10.1.75  拒否

ユーザーのログインに加え、ネットワークスイッチは設定が変更された際にも通知します


2011-10-02 15:16:29 : 10.10.1.75 : >%COPY-I-FILECPY: ファイルのコピー - ソース URL run-config、宛先 URL flash://startup-config

2011-10-02 15:16:43 : 10.10.1.75 : >%COPY-N-TRAP: コピー操作は正常に完了しました

また、リンクの接続状態(アップ/ダウン)に関するメッセージも表示されるため、通信トラブルのトラブルシューティングに非常に役立ちます。


2011-10-02 15:49:17 : 10.10.1.75 : >%LINK-W-Down:  2/e24

2011-10-02 15:49:20 : 10.10.1.75 : >%LINK-I-Up:  2/e24
  RSNインターネットコンソールサーバーの例
RSNコンソールに接続されたモジュールの誰かが、パスワードを2回間違えて入力した後、rootとしてログインしました。


2011-10-02 12:11:03 : 10.10.1.200 : in.telnetd[2942]: 10.10.1.1 (10.
10.1.1) からの接続
2011-10-02 12:11:03 : 10.10.1.200 : telnetd[2942]: doit: getaddrinfo: 名前解決の一時的な失敗
2011-10-02 12:11:07 : 10.10.1.200 : login[2943]: `10.10.1.1' からの `ttyp0' における `root' のパスワードが無効です
2011-10-02 12:11:15 : 10.10.1.200 : login[2943]: `10.10.1.1' からの `ttyp0' における `root' のパスワードが無効です
+
2011-10-02 12:11:35 : 10.10.1.200 : login[2945]: `10.10.1.1' からの `ttyp0' への root ログイン

無効なユーザーIDでログインを試みた場合、RSNコンソールはユーザーIDとして「UNKNOWN」と表示することに注意してください。


2011-10-02 12:12:31 : 10.10.1.200 : in.telnetd[2946]: 10.10.1.1 (10.
10.1.1) からの接続
2011-10-02 12:12:32 : 10.10.1.200 : telnetd[2946]: doit: getaddrinfo: 名前解決の一時的な失敗
2011-10-02 12:12:37 : 10.10.1.200 : login[2947]: `10.10.1.1' からの `ttyp0' における `UNKNOWN' のパスワードが無効です
2011-10-02 12:12:45 : 10.10.1.200 : login[2947]: `UNKNOWN' のパスワードが無効です。
+`ttyp0` 経由で `10.10.1.1` から
2011-10-02 12:12:54 : 10.10.1.200 : login[2947]: `UNKNOWN' のパスワードが無効です;
+`ttyp0' 上で `10.10.1.1' から

RSNコンソールでは、有効なユーザーID「rsn_admin」を使用してログインしても、そのことが通知されません。ただし、接続は表示されます。「rsn_admin」ユーザーIDには、システム設定ファイルを変更する権限はありません。「rsn_admin」ユーザーがsuコマンドを使用してrootユーザーに切り替えようとすると、その操作はログに記録されます。


2011-10-02 12:15:37 : 10.10.1.200 : in.telnetd[2957]: 10.10.1.1 (10.
10.1.1) からの接続
2011-10-02 12:15:38 : 10.10.1.200 : telnetd[2957]: doit: getaddrinfo: 名前解決の一時的な失敗
2011-10-02 12:15:54 : 10.10.1.200 : su[2959]: + ttyp0 rsn_admin-root
2011-10-02 12:15:54 : 10.10.1.200 : PAM_unix[2959]: (su) rsn_admin(uid=500) によりユーザー root のセッションが開かれました

失敗に終わる試みもまた然り。


2011-10-02 12:19:50 : 10.10.1.200 : PAM_unix[2972]: 認証失敗; rsn_
+admin(uid=500) -> root (su サービス用)
2011-10-02 12:19:52 : 10.10.1.200 : su[2972]: pam_authenticate: 認証失敗
2011-10-02 12:19:52 : 10.10.1.200 : su[2972]: - ttyp0 rsn_admin-root

 

ネットワークスイッチを構成してOpenVOSモジュールにログメッセージを送信するには、rootとしてスイッチにログインし、loggingコマンドを実行してから、新しい設定を保存する必要があります:

telnet 10.10.1.75                                       
接続を試行中...
10.10.1.75 に接続しました。
エスケープ文字は '^]' です。

ユーザー名:root
パスワード:******

console# config
console(config)# logging 10.10.1.1
console(config)#

console# copy running-config startup-config

 

RSNコンソールからOpenVOSモジュールへログメッセージを送信するように設定するには、rootとしてコンソールにログインし、「syslogd –R 10.10.1.1:514」というコマンドでsyslogdプロセスを起動する必要があります。再起動後もsyslogdプロセスが確実に起動されるようにするには、/etc/tc.d/rc.local ファイルを変更する必要があります。

telnet 10.10.1.200
Trying...
Connected to 10.10.1.200.
Escape character is '^]'.

Moxa Embedded Linux, Professional Edition
Linux/armv5teb 2.4.18_mvl30-ixdp425

azvos login: root
Password:
Welcome to

    ___  _____  __        _______    _____                   __
   / _ / __/ |/ / ____  /  _/ _   / ___/__  ___  ___ ___  / /__
  / , _/ /    / /___/ _/ // ___/ / /__/ _ / _ (_-</ _ / / -_)
 /_/|_/___/_/|_/       /___/_/     ___/___/_//_/___/___/_/__/ 

 Authorized Users Only!

root@azvos:~# syslogd -R 10.10.1.1:514
root@azvos:~# 
root@azvos:~# 
root@azvos:~# 
root@azvos:~# cd /etc/rc.d
root@azvos:/etc/rc.d# cp rc.local rc.local.bak
root@azvos:/etc/rc.d# echo syslogd -R 10.10.1.1:514 >> rc.local
root@azvos:/etc/rc.d# tail rc.local
fi
/etc/init.d/ssh start
/etc/init.d/apache stop
/etc/init.d/portmap stop
rm -f /rsn/call.log
/rsn/callhome &
lcmmessage -c -m "   Welcome to   " -l
lcmmessage -m " RSN-IP Console " -l
cat /etc/motd
syslogd -R 10.10.1.1:514
root@azvos:/etc/rc.d#

 

上記と同じ出力が表示されたら、「rm rc.local.bak」と入力して rc.local.bak ファイルを削除できます。

デバイスでのロギング設定が完了したら、Stratusモジュール上でlogdプログラムを実行する必要があります。以下のコマンドマクロを使用してプログラムを起動することをお勧めします。ログファイル名はlogd.(日付).(時刻).outとなります。何らかの理由で同名のファイルがすでに存在する場合、そのファイルはlogd.(日付).(時刻).old.outにリネームされます。 すでに .old.out という拡張子を持つファイルが存在する場合は、そのファイルは削除されます。タイムスタンプは秒単位で記録されるため、このような事態はまず起こりません。out ファイルには暗黙的なロックが設定されているため、いつでも読み取ることができます。なお、out ファイルは無限に大きくなり続けるため、ユーザー側で何らかのメンテナンスを行うか、プログラムを修正して出力処理をより適切に行うようにする必要があります。



& start_logd.cm はここから始まります
&
& バージョン 1.00 2002年11月11日
& [email protected]
&
& このスクリプトは、ログファイルを作成し、暗黙的なロックを設定して、logd
& プロセスを起動します。このプロセスは通常終了せず、ログファイルは極めて大容量になる可能性があります。
&
&
& 本ソフトウェアは「現状有姿」で提供され、いかなる保証も、またいかなる種類のサポートも提供されません。作者は、商品性および特定目的への適合性に関する黙示の保証を明示的に否認します。
& この免責事項は、作者またはその他の者によるいかなる口頭での表明があったとしても、適用されます。
&
&
&set DT (date).(time)
&if (exists logd.&DT&.out)
&then !rename logd.&DT&.out logd.&DT&.old.out -delete
!create_file logd.&DT&.out
!set_implicit_locking logd.&DT&.out
start_process logd -output_path logd.&DT&.out -privileged -process_name logd
&
& start_logd.cm はここで終了します

 

さて、ついにプログラムが完成しました。



/* logd.c starts here

   Version 1.00 11-11-02
   [email protected]

   This software is provided on an "AS IS" basis, WITHOUT ANY WARRANTY OR
   ANY SUPPORT OF ANY KIND. The AUTHOR SPECIFICALLY DISCLAIMS ANY IMPLIED
   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE.
   This disclaimer applies, despite any verbal representations of any
   kind provided by the author or anyone else.
*/

#define _POSIX_SOURCE

#include <sys/select.h>
#include <prototypes/inet_proto.h>
#include <stdlib.h>
#include <string.h>
#include <c_utilities.h>
#include <errno.h>
#include <time.h>

#define BUFFERLEN 10000
#define bzero(s, len)             memset((char *)(s), 0, len)

int errno;

getCurrentDateTime (char * szDT)
{
time_t tTime;
struct tm *tmLT;

tTime = time ((time_t *) 0);
tmLT = localtime (&tTime);

sprintf (szDT, "%4ld-%02ld-%02ld %02ld:%02ld:%02ld",
          tmLT -> tm_year+1900,
          tmLT -> tm_mon,
          tmLT -> tm_mday,
          tmLT -> tm_hour,
          tmLT -> tm_min,
          tmLT -> tm_sec);
}

main (argc, argv)
int    argc;
char   *argv [];

{
 struct sockaddr_in serv_addr;
 struct sockaddr_in cli_addr;
 int clilen = sizeof (cli_addr);

 int zeroCount = 0;
 int socks0;
 int recvBytes;

 char szSender [16];
 char  szDateTime [32];
 char szMessage [BUFFERLEN];
 short portNumber;

 if (argc == 1)  /* no arguments - use the default of 514 */
    {
    portNumber = 514;
    }
 else
 if (argc == 2) /* one argument, must be the expected port number */
    {
    portNumber = atoi (argv [1]);
    if (portNumber == 0)
       {
       printf ("nn%s argument was not the expected port number", argv [1]);
       printf ("nUsage: logd [port number, default = 514]n");
       exit (-1);
       }
    }
 else /* more than one argument gets a usage message */
    {
    printf ("nnToo many arguments");
    printf ("nUsage: logd [port number, default = 514]n");
    exit (-1);
    }

/* Leting you know what argument values will actually be used */

 printf ("logd %dnn", portNumber);

 if ((socks0 = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
    {
    perror ("logd: can't create dgram socket");
    exit (errno);
    }

/* build a sockaddr structure holding the address we will bind to. The IP
   address is INADDR_ANY meaning we will listen on all active IP addresses */

 bzero ( (char *) &serv_addr, sizeof (serv_addr));
 serv_addr.sin_family        = AF_INET;
 serv_addr.sin_addr.s_addr   = htonl (INADDR_ANY);
 serv_addr.sin_port          = htons (portNumber);

/* now bind to the address and port */

 if (bind (socks0, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0)
    {
    perror ("logd: can't bind local address");
    exit (errno);
    }

/* main loop just does a recv, blocking until something is available to read.
   Assuming we receive at least 1 byte we get the current date-time,
   convert the senders IP address to a printable string and print the
   date-time, address and message starting at the 5th character position.
   The first four characters of a syslog message are <NN> where NN is a
   severity and facility code. These can be used for message filtering. Since
   this program doesn't do any filtering I just skip them. */
 while (1)
   {
    recvBytes=recvfrom(socks0,szMessage, BUFFERLEN, 0,
          (struct sockaddr *) &cli_addr, &clilen);
    if (recvBytes > 0)
       {
       getCurrentDateTime ((char *) &szDateTime);
       strcpy (szSender, inet_ntoa ((struct in_addr) cli_addr.sin_addr));
       szMessage [recvBytes] = 0;
       printf ("%s : %s : %sn", szDateTime, szSender, &szMessage[4]);
       zeroCount = 0;
       }
    else
    if (recvBytes < 0) /* in the event of an error report it and exit */
       {
       getCurrentDateTime ((char *) &szDateTime);
       printf ("%s : Error %d returned - exitingn", szDateTime, errno);
       exit (errno);
       }
    else  /* I can't think of any reason we would be getting null messages */
       {  /* but if we get a stream of them we would silently loop. This */
       zeroCount++;          /* forces out a message if we get 100 null */
       if (zeroCount > 99)   /* messages in a row */
          {
          getCurrentDateTime ((char *) &szDateTime);
          strcpy (szSender, inet_ntoa ((struct in_addr) cli_addr.sin_addr));
          printf ("%s : %s %sn", szDateTime,
               "We have received 100 null messages, the last one from",
               szSender);
          zeroCount = 0;
          }
       }
   }
}

/* logd.c ends here */

 

© 2024 ストラタス・テクノロジーズ