0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

OSSECの各デーモンのソースコードリーディング

Last updated at Posted at 2022-03-06

はじめに

OSSECのソースコードリーディングの記事です。なお、OSSECのインストール手順にご興味のある方は以下の記事を参照ください。

maildデーモン

main()関数

  • /ossec-hids-master/src/os_maild/maild.c
  • デーモン起動オプションのチェック
  • 指定されたユーザー/グループが有効かどうかを確認する
  • Config設定の読み込み
  • 内部オプション読み込み
  • グルーピング取得
  • サブジェクトタイプ取得
  • ジオIP取得 ←コンパイルオプション有効の場合
  • 特権の分離
  • chroot変更
  • ユーザ変更
  • シグナル操作
  • PIDファイル生成
  • デーモンのメイン処理:OS_Run(&mail)をコール

OS_Run()関数

  • 現在時刻取得
  • ファイルキュー初期化 os_calloc()
  • メールリスト生成
  • デフォルトタイムアウト時間設定
  • グローバル変数クリア
  • 無限ループ while(1)
  • 時分秒の時が変わってたら、抑制していたメールを送信。pid = fork()で子プロセスを生成し、子プロセスでOS_Sendmail()をコールして、メールを送信。exit(0)でプログラムを正常終了させる。
  • do_not_groupオプションのメッセージをセーブ
  • キューからメッセージを取り出して、送信予定メールのリストに保存【OS_AddMailtoList()】。プライオリティを見て処理分岐。DONOTGROUPは低プライオリティ扱いかも。
  • 子プロセスが終了するのを待つ。while (childcount)でchildcountがゼロになるまで待つ。子プロセスがメールを送信終わるまでループしているのか。

execdデーモン

main()関数

  • /ossec-hids-master/src/os_execd/execd.c
  • デーモン起動オプションのチェック
  • 指定されたユーザー/グループが有効かどうかを確認する
  • 指定されたユーザー/グループが有効かどうかを確認する
  • Config設定の読み込み
  • シグナル操作 StartSIG2(ARGV0, execd_shutdown)
  • PIDファイル生成
  • execキュー開始 StartMQ(EXECQUEUEPATH, READ)
  • デーモンのメイン処理開始 ExecdStart(m_queue)

ExecdStart()関数

  • タイムアウトリスト生成 OSList_Create
  • 無限ループ while(1)
  • 子プロセスをクリーンアップ
  • 現在時刻を取得
  • 実行タイムアウトコマンドの存在有無をチェック
  • while (timeout_node)タイムアウトリストをループでチェックして、タイムアウトコマンドがあったら、コマンドを実行する
  • OSList_GetFirstNode(timeout_list) タイムアウトリストの先頭ノードを取得
  • ExecCmd(list_entry->command) コマンド実行
  • OSList_DeleteCurrentlyNode(timeout_list) タイムアウトリストから実行したノードを削除
  • timeout_node = OSList_GetNextNode(timeout_list) 次のノードをセットして、タイムアウトリストチェックのループの先頭に戻る
  • select()システムコールでキューを待ち受け select(q + 1, &fdset, NULL, NULL, &socket_timeout)
  • コマンド受信 OS_RecvUnix(q, OS_MAXSTR, buffer)
  • 実行コマンドを取り出し GetCommandbyName()
  • 実行コマンドの引数を取り出し
  • while (timeout_node) 再度、タイムアウトリストをチェックするループ処理
  • キューから取り出した実行コマンドをタイムアウトリストに追加する
  • 過去に追加したコマンドではない場合は、コマンド実行する ExecCmd(cmd_args)

analysisdデーモン

main()関数

  • /ossec-hids-master/src/analysisd/analysisd.c
  • デーモン起動オプションのチェック
  • 指定されたユーザー/グループが有効かどうかを確認する
  • ActiveResponse初期化 AR_Init()
  • Config設定の読み込み GlobalConf(cfg)
  • ジオIP有効の場合は、ジオIPデータベースの読み込み
  • サーバのホストネームを取得 gethostname()
  • chroot設定 Privsep_Chroot() nowChroot()
  • デコーダーの最大サイズを設定 MAX_DECODER_ORDER_SIZE 20
  • すべてのルールとリストの完成
  • デコードリスト取得
  • リスト取得
  • ルール取得
  • シグナル操作 StartSIG2(ARGV0, execd_shutdown)
  • PIDファイル生成
  • execキュー開始 StartMQ(DEFAULTQUEUE, READ)
  • デーモンのメイン処理開始 OS_ReadMSG(m_queue)

OS_ReadMSG()

  • 各種メモリの初期化 OS_InitLog(),SyscheckInit(),RootcheckInit(),HostinfoInit()
  • イベントリスト生成 OS_CreateEventList()
  • FTSリスト初期化 FTS_Init()
  • アキュームレーター初期化 Accumulate_Init()
  • キュー開始 StartMQ()
  • デーモンループ開始 while(1)
  • キューからメッセージを受信 OS_RecvUnix()
  • 受信したメッセージをデコード
  • ルールをチェックし、ルールに従って処理を実行

logcollectorデーモン

main()関数

  • /ossec-hids-master/src/logcollector/main.c
  • キュー開始logr_queue = StartMQ(DEFAULTQPATH, WRITE)
  • デーモンのメイン処理 LogCollectorStart()
    LogCollectorStart()関数
  • /ossec-hids-master/src/logcollector/logcollector.c
  • while(1) 無限ループ
  • タイムアウトまで待つ select()システムコール if ((r = select(0, NULL, NULL, NULL, &fp_timeout)) < 0)
  • 2秒おきにチェック処理を走らせている etc/internal_options.conf:logcollector.loop_timeout=2
  • チェック対象のファイル有効性をチェック for (i = 0; i <= max_file; i++)
  • keep aliveメッセージを送信 チェックに時間がかかるからか?
  • rand_keepalive_str(keepalive, 700)
  • SendMSG(logr_queue, keepalive, "ossec-keepalive", LOCALFILE_MQ);
  • ファイルタイムスタンプの日付が変わっているか
  • ファイルがオープンされている場合、テンポラリファイルを開いている
  • ログローテートされたことを通知 SendMSG(logr_queue, msg_alert,"ossec-logcollector", LOCALFILE_MQ)
  • ファイルサイズが小さくなっている(reduce)場合、ファイルreduceのアラートを通知SendMSG(logr_queue, msg_alert,"ossec-logcollector", LOCALFILE_MQ)
  • 当日のファイル変更はアラート通知対象外にしているようだ

remotedデーモン

main()関数

  • /ossec-hids-master/src/remoted/main.c
  • それぞれの接続をハンドルするプロセスをfork()して、HandleRemote()

HandleRemote()関数

  • /ossec-hids-master/src/remoted/remoted.c
  • syslog接続の場合、接続許可IPリストを取得
  • ソケットをBind() OS_Bindporttcp(),OS_Bindportudp()
  • POSIXスレッド機構を使用して、メッセージ送信(sendto())を行っている。pthread_mutex_init(),pthread_mutex_lock()

syscheckedデーモン

main()関数

  • /ossec-hids-master/src/syscheckd/syscheck.c
  • キュー書き込みしている syscheck.queue = StartMQ(DEFAULTQPATH, WRITE))
  • デーモン開始 start_daemon()

start_daemon()関数

  • /ossec-hids-master/src/syscheckd/run_check.c
  • 無限ループ while(1)
  • リアルタイム監視の処理もある
  • MD5とSHA1のチェックサムを比較しているようだ

monitordデーモン

main()関数

  • /ossec-hids-master/src/monitord/main.c
  • デーモンメイン処理 Monitord()コール

Monitord()関数

  • /ossec-hids-master/src/monitord/monitord.c
  • 無限ループ while(1)
  • 2分間隔でチェックしている sleep(120)
  • エージェント監視処理 monitor_agents()
  • エージェントからマネージャーに生存通知を投げていて、それをチェックしているのかも

agentdデーモン

  • Sender処理とReceiver処理がいる
  • Senderはサーバへの生存通知をしているようだ
  • ReceiverはサーバからのメッセージをNWソケットで受信して、execd向けのOSキューに登録している
    main()関数
  • /ossec-hids-master/src/client-agent/main.c
  • agentdデーモン開始処理 AgentdStart(dir, uid, gid, user, group)

AgentdStart()関数

  • /ossec-hids-master/src/client-agent/agentd.c
  • キュー接続 agt->execdq = StartMQ(EXECQUEUE, WRITE)
  • サーバへの接続テスト
  • os_setwait()
  • start_agent(1)
  • os_delwait()
  • run_notify() 初回通知
  • 無限ループ while(1) 
  • run_notify() サーバへの継続通知をしている。エージェントからサーバーに対する生存通知か。
  • select()システムコールによる待ち fdtimeout.tv_sec = 1 1秒停止
  • receive_msg()もしている。サーバからのメッセージ受信か。

receive_msg()関数

  • /ossec-hids-master/src/client-agent/receiver.c
  • ソケット受信処理
  • while ((recv_b = recv(agt->sock, buffer, OS_SIZE_1024, MSG_DONTWAIT)) > 0) MSG_DONTWAITなので、メッセージが無ければ抜けるのかも。
  • ReadSecMSG()
  • execd向けのキューに登録 OS_SendUnix(agt->execdq, tmp_msg, 0) < 0)

おわりに

基本的にデーモン処理なので、while(1)の無限ループ処理のなかで、いろいろ処理を行っていました。デーモン間のやり取りはOSのメッセージキューを使用していて、エージェントとサーバ間はNWソケットでのメッセージ送受信をしていました。

今回の記事は以上です。では、また。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?