古いMacBookの延命策
2006年の夏に購入したMacBook1,1は、その翌年には1年間の保証期間が切れるのを待っていたかのようにDVDドライブが壊れ、さらに数年後にはバッテリーの膨張であわやハードウェアの損傷か?とういトラブルが起きた。しかたないから蓋と一体型のバッテリーをはがし取り、ガムテでなんとかその体裁を維持している。
そんなMac君もお茶の間の娯楽用PCとしてはインターネットや動画再生でたくさん活躍してくれました。そしてこれからも充分使えそうなほど、前出のハードウェア以外は全く問題なく元気ハツラツなMac君。さすがアップル!伊達にニュートンにかじられちゃいません。
話は飛びますが、マイクロソフトはお釈迦さまの生まれた日(日本時間では4/9)にWindowsXPのサポートを終了するというじゃぁありませんか。サポート終了後も使い続けられるXPを狙って、よりいっそう攻撃が増加するという予想もされてますが、被害に遭わないためにも早めに使用をやめた方が無難かもしれません。
娯楽目的ではMacBookをWindowsXPメインでしか使用してこなかったバチ当たりな私ですが、今後Mac OS-X一本でMac君と付き合わなければなりません。とは言うものの購入当時のタイガーのままバージョンアップしてないので最新の動画再生ソフトなどがインストールできません。これではOS-Xも使い続けられず、このままではジャンク同然です。
Webの表示&動作テストの用途としての当初の役目を終えて以降、Mac君にはなんにも手当をしていなかったのが今になって悔やまれます。かといっていまさらOSをアップグレードするほどの価値もない。中古ノートを買うための資金調達でヤクオフに出しても買い叩かれるのがオチ。
Mac Book 1,1 にUbuntuを!
で、現在インストールしているXPを削除してLinuxがインストールできないか検索したらたくさんヒットする!おお「捨てる神あれば拾う神あり」ですね。中古のThinkPadでも買おうかと動かしはじめてた食指を止めることにした。
記事の多さではUbuntuのインストールが圧倒的で、短時間で確実にセットアップしたい私にとっては選択肢はそれしかなさそう。
https://help.ubuntu.com/community/MacBook1-1/Lucid を見ると少々問題はありそうだけど充分使えそうな雰囲気。XPのときもキーボードなどいろいろ不便な思いをしてきたわけだし。簡単にUbuntuがインストールできれば言うことなしなのだ。
インストールに関しては https://help.ubuntu.com/community/MactelSupportTeam/AppleIntelInstallation に記されている。Ubuntuのシングルブートも可能らしいが、ここはやはり何かあったときのためにデュアルブートの道を選択する。
まずブートローダーの rEFIt をインストールする。OS-Xのバージョンが古すぎてインストールできるかドキドキしたがあっさり通った。
BootCampを起動して一度XPの領域を削除してから再度Linux用のディスクスペースを確保しなおす。このときBootCampに試用期限切れで使えないと怒られるww。当時ベータバージョンで配布されていたものなのでしかたないのか?Macの日付を2007年に戻してから起動し直して無事にクリア。
あとはUbuntuのisoイメージからインストーラを起動できればOK。最新のバージョンにしたいところをぐっとこらえて、上のリンク先にあるように10.04をインストールしてからバージョンアップしていくのが無難そう。それより高いバージョンではドライバーがサポートされてないという記事も見たような気がするし、(直接関係ないけど)以前 Pentium M のマイクロPCにUbuntuサーバをインストールしようとしたときpaeサポートの問題で10.04.4LTSをインストールしてから順次バージョンアップしなければならない事もあったからだ。
光学ドライブが壊れているので、USB接続のCD/DVDドライブにUbuntuのisoイメージディスクを入れてMacを再起動…。ところが黒い画面のまま、いつになってもドライブから読み込みが始まらない。他のマシンのインストールに使った違うバージョンのUbuntuでやっても状況は変わらず。やはり、内蔵ドライブじゃないと起動できないのか?USBメモリーからはどうかと思って、Universal USB Installerを使って作成したが、これもダメだった。
あれやこれや検索ワードを変えてググってやっとたどり着いたのがココ http://gfs.sourceforge.net/wiki/index.php/Live_Ubuntu_Gerris_distribution
私と同じ境遇(内蔵光学ドライブが壊れている)の人がこれを解決してるじゃぁないですか!一筋の光明。
要はパーティション無しのライブUSBインストールイメージを作成すればい良いということらしい。それってどういうこと?
いろいろ考えたり戸惑っていても時間がもったいないので実行あるのみ。(※以下は備忘録を兼ねて記していますが、なにか抜けがあったらご容赦を)
Ubuntuの起動USBメモリーを作る
仕事で使ってるUbuntuマシンがあるので私はそれを使ったが、Ubuntu環境が無い場合はMacでも出来そうかな。ここでは上記サイトで紹介されているやりかたを、自分の環境で行った結果を記しています。
1. USBメモリーをフォーマットする
事前にUSBメモリがどこに割り当てられているのか調べる。アプリケーション >> ユーティリティ >> ディスク を起動して、デバイスのリストでUSBアイコンのドライブをクリックして、それに関するプロパティを見るか、$ sudo fdisk -l を実行して取得する。複数のUSBデバイスが接続されていると、どれがどれだか分からない場合もあるので要注意。
/dev/sdX のXの部分はそれぞれの環境に合わせて書き換える
$ sudo mkfs.vfat /dev/sdX -I既にFATフォーマットされていたら、これはやらなくてもOK
2.Ubuntuのisoイメージをマウントする
$ sudo mkdir /media/ubuntu-disk
$ sudo mount -o loop
mount: ブロックデバイス
3.USBメモリーをマウントする
$ sudo mkdir /media/usb
$ sudo mount /dev/sdX /media/usb
4.USBメモリーにUbuntuファイルをコピーする
※コピーでちょっと怒られますが、無視して進めてOKみたい
$ cd /media/ubuntu-disk
$ sudo cp -rf casper disctree dists install pics pool preseed .disk /media/usb
cp: `disctree' を stat できません: そのようなファイルやディレクトリはありません
cp: シンボリックリンク `/media/usb/dists/stable' を作成できません: 許可されていない操作です
cp: シンボリックリンク `/media/usb/dists/unstable' を作成できません: 許可されていない操作です
$ sudo cp -rf isolinux /media/usb/syslinux
$ cd /media/usb/syslinux
$ sudo mv isolinux.cfg syslinux.cfg
MacBook にUbuntuをインストールする
上記手順で作成したUSBメモリーをMacBookに刺して電源を入れる。ブートマネージャーのrEFIt画面にOSのアイコンが並ぶ。左からリンゴ、ウィンドウズ(っぽいアイコン)、ペンギン。ペンギンをクリックする・・・・・・・ちゃんと起動する、やっとここまでこれた。
インストーラを起動して普通にインストール作業をすすめる。ただここで一つ失敗したことに気付かされた。スワップ用のパーティションを切っていなかったことだ(Boot Campを使ってパーティションを切るのは間違いだったかもと少し後悔する)。後戻りはめんどうなのでスワップ領域は後でファイルとして持つようにすることにして、Ubuntuのインストールを続行する。それから、キーボードに不安があったのでログイン時にパスワード入力を必要としない自動ログインを選んだ。
スワップ領域以外は躓きもなくすんなりインストールできた。USBメモリーを抜いて再起動すると、ブートローダーに表示されるリンゴアイコン右隣りのウィンドウズアイコンがペンギンに変わっている。ペンギンをクリックすると待望のUbuntu10が今までの苦労が嘘のようにフツーに立ち上がった。ホッとする。仕上げは12.04LTSへのアップグレードだ。
アップグレードはアップデートマネージャーに従って進めることにした。結局 10.04LTS ⇒ 11.04 ⇒ 11.10 ⇒ 12.04LTS の三回アップグレードすることになる。この途中、11.04でキーボードが意図しない文字を入力するようになり焦ったが、マウスを使って12.04LTSまで無事にインストールできた。自動ログインにしておいて良かったぁ。(※10.04LTSからアップデートするときには/etc/apt/sources.listファイルを修正する作業が発生する。本家からダウンロードしたisoならその必要は無いかも)
Ubuntuをインストールしたらやること
Ubuntu12までアップグレードできたらシステムのアップデートの他、やらなければならない事や、やっておいた方が良いことがいくつかある。
スワップ領域を確保する
インストール時にスワップ領域を作れなかったので、一応メモリーと同じ分だけ確保する。
/etc/fstabに以下を追記する
$ sudo dd if=/dev/zero of=/swap bs=1G count=2
$ sudo chmod 600 /swap
$ sudo mkswap /swap
$ sudo swapon /swap
再起動してスワップ領域が確保されているか以下のコマンドを実行するか、システムモニターを開いて確認する。
/swap swap swap defaults 0 0
$ cat /proc/swaps
イヤホンジャックから音声が出ないのをなんとかする
内蔵スピーカーからは音は出るが、イヤホンジャックにヘッドフォンを刺しても音が出ない。
ソフトウェアセンターでgnome-alsamixerをインストールする。それを起動するとSpeakerのスライダーが二つあるので、そのどちらかがイヤホンなのでいい感じになるまでスラーダーを上げればよい。
デスクトップを変更する
好き嫌いがあると思うが、私はUnityデスクトップが嫌いなのでいつも古いタイプに戻している。ソフトウェアセンターにてgnome-session-fallbackを検索してそれをインストールする。
デスクトップをカスタマイズする
家族も使うので、デスクトップ画面にごみ箱やネットワークアイコンを表示させることにする。以下のコマンドを打つかソフトウェアセンターで「Advanced Settings」を検索してインストールする。
起動するときは アプリケーション ⇒ システムツール ⇒ 設定 ⇒高度な設定をクリックする。gnome-tweak-toolを端末で打っても良い。表示されたダイアログのデスクトップタブをクリックして。デスクトップに置きたいアイコンのトグルスイッチをクリックしてONにする。
$ sudo apt-get install gnome-tweak-tool
- Have file manager handle the desktop ※これをONにしないとそれ以下の設定が有効にならない
- Computer icon visible on desktop ※コンピュータアイコン
- Home icon visible on desktop ※ホームアイコン
- Networks Servers icon visible on the desktop ※ネットワークアイコン(我が家ではNASに置いてある動画ファイルを探すときに多少便利)
- Trash icon visible on desktop ※ゴミ箱アイコン
- Show mounted volumes on the desktop ※外付けUSB接続のHDDやメモリーなどがあった場合に表示されるアイコン
Snortのアラート検出時のログを見たい
SnortをIDSエンジンにしたBaseではいろんな角度からアラートを統計表示してくれるのでとても便利ですが、アラートが出た時点でなにが起きたのかを知りたくて、コマンドを叩いてログを検索することがたまにあります。しかし出先のスマホからはそれができない(できるけどやりたくないw)ので歯がゆい思いをすることがしばしば。いっそのことBaseからそれをやってしまおう(といってもリンクしてるだけですが)と思って作ったのがこのスクリプトです。SnortやBaseのインストールに関しては侵入検知ソフトSnortと周辺ツールをインストールするをご覧ください。
BaseのTimestampに表示されている時分秒に合致するログを/var/log/から根こそぎ拾ってきて左画像のように表示します。Baseのソースを熟読する時間的余裕が無いのでまったくのスタンドアロンとしました。ですのでBase本体のように体裁良く表示するわけではありません。
また、ログのパーミッションを甘くしたりとか、ツールを新たにインストールすることはせずに簡単に設置可能であることを目標としました。あくまでネットワークに繋がったPCの無い状況での簡易確認用途としてスマホから使うのが主な目的です。
大量のアクセスおよびログが吐かれるサーバでは検索条件を新たに加えなければ使い物にならないかもしれません。
一応ピックアップしたログの中でSource AddressとDest. Addressがハイライト表示して見やすくはなっています。ちなみにBase側の変更箇所はリンクの記述を追加する一ヶ所だけです。
主なファイル構成
Baseを設置したディレクトリ(/var/www/base)にfind_logディレクトリを作って以下のファイルを作成します。
- cache/ (キャッシュディレクトリ)
- del_exp.sh (期限切れキャッシュファイルを削除する)
- grep_log_dt.sh (指定された日時のログファイルを検索する)
- grep_result.txt (検索した結果を一時的に保存するファイル)
- index.php (ログ表示ページ)
- jquery-2.0.2.min.js (jquery、適当なやつをダウンロード)
- target_datetime (タイムスタンプを一時保存するファイル)
処理の流れ
BaseのTimestampのリンクをクリックする。 ↓ find_log/index.php キャッシュファイルがなかったらタイムスタンプをtarget_datetimeに書き込んで、grep_log_dt.shがキャッシュファイルを生成するのを待つ(指定秒間隔のリフレッシュ)。キャッシュファイルが既にあったらそれを表示する。 ↓ find_log/grep_log_dt.sh 定時実行してtarget_datetimeのタイムスタンプを読み込んで、ログファイルを検索、結果をキャッシュファイルに書き込む。target_datetimeに時刻が書き込まれていなかったら終了する。
Baseの改造
Baseディレクトリ直下のbase_qry_sqlcalls.phpの225行目あたり
qroPrintEntry($myrow[3]); ↓ qroPrintEntry("<a href='./find_log/index.php?timestamp=$myrow[3]&sip=$current_sip&dip=$current_dip'>".$myrow[3]."</a>");
cache/
キャッシュディレクトリにはBaseのタイムスタンプに紐づくキャッシュファイルを作成します。命名規則は、例えば"2013-12-31 23:59:59"のスペースの部分を'_'(アンダースコア)に置換した"2013-12-31_23:59:59"とする。
del_exp.sh
機能:キャッシュファイルの生成日から指定日数を過ぎたものを削除します。
crontabに
0 0 * * * /var/www/base/find_log/del_exp.sh
を記述して毎日実行。
#!/bin/bash
export LANG=en
CACHE_DIR="/var/www/base/find_log/cache/"
LIMIT=`date '+%s' -d '30 days ago'`
for FILE in `find ${CACHE_DIR} -type f | \
grep -e "[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}_[0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}"`
do
if [ `date '+%s' -r ${FILE}` -lt ${LIMIT} ]; then
rm -f ${FILE}
fi
done
exit 0
grep_log_dt.sh
主な機能:各種のログの日付フォーマットでログファイルを検索して、合致する行をピックアップしてhtmlタグをつけてキャッシュファイルに書き出します。
検索対象日は、index.phpがtarget_datetimeファイルに書き出した日付をピックアップします。そのためにこのスクリプトを一定時間毎に走らせて、日付が書き出されたか常に監視します。とりあえず5秒間隔で動作するように、crontabを指定秒ごとに実行するで書いたような方法で記述しています。なにもしなければほとんど負荷はかからないのでさらに短い秒数でもいいかもしれません。ただcrontabにあの記述をづらずら書くのが気が引けるのと、スマホからのアクセスで大量に短時間に処理したいわけでもないので5秒間隔で充分かなと…。
#!/bin/bash export LANG=en # "YYYY-MM-DD hh:mm:ss"の19の文字列を取得する DT_FILE="/var/www/base/find_log/target_datetime" DT=`cut -c-19 ${DT_FILE}` SIP=`cut -d' ' -f3 ${DT_FILE}` DIP=`cut -d' ' -f4 ${DT_FILE}` :> ${DT_FILE} # ターゲットの日時の文字列がなかったら終了する if [ ${#DT} -ne 19 ]; then exit 0 fi # キャッシュファイルディレクトリ CACHE_DIR="/var/www/base/find_log/cache/" # キャッシュファイル名はスペースに_を入れて"YYYY-MM-DD_hh:mm:ss"とする CACHE_FILE=`echo ${DT} | sed -e "s/\s/_/"` # キャッシュディレクトリに既存のファイルがあるか検索する EXIST_FILE=`find "${CACHE_DIR}" -name "${CACHE_FILE}"` # 同じファイルがキャッシュにあったら処理を終了する if [ ${#EXIST_FILE} -ne 0 ]; then exit 0 fi # ログファイルディレクトリ LOGDIR="/var/log/" # grepした結果の一時保存ファイル RES_FILE="/var/www/base/find_log/grep_result.txt" # messages maillog 他 のフォーマット(冒頭に日付があって西暦がない) *********** # e.g. "Jun 2 06:12:13" FORMAT_1=`date -d "${DT}" "+%b %e %T"` # apache access_log ssl_access_log ssl_request_log のフォーマット************* # e.g. "08/Jun/2013:06:22:57" FORMAT_2=`date -d "${DT}" "+%d/%b/%Y:%T"` # apache error_log ssl_error_log のフォーマット******************************* # e.g. "Wed Jun 19 10:20:44 2013" FORMAT_3=`date -d "${DT}" "+%a %b %d %T %Y"` # ↓ 検索文字列の先頭に"^"をつけてFORMAT_3にかぶらないようにする grep -r "^${FORMAT_1}" "${LOGDIR}" >> ${RES_FILE} grep -r "${FORMAT_2}" "${LOGDIR}" >> ${RES_FILE} grep -r "${FORMAT_3}" "${LOGDIR}" >> ${RES_FILE} CACHE_FILE=`echo ${DT} | sed -e "s/\s/_/"` # ホスト名を取得する SNM=`nslookup "${SIP}" | sed -n "s/.*\(in-addr.arpa\tname = \)\(.*\)/\2/p"` DNM=`nslookup "${DIP}" | sed -n "s/.*\(in-addr.arpa\tname = \)\(.*\)/\2/p"` # IPアドレスとホスト名を書き込む TBL="<table class='iptbl'>" TBL=${TBL}"<tr>" TBL=${TBL}"<td class='title'>Source Address</td><td>${SIP}</td><td>:</td><td>${SNM}</td>" TBL=${TBL}"</tr>" TBL=${TBL}"<tr>" TBL=${TBL}"<td class='title'>Dest. Address</td><td>${DIP}</td><td>:</td><td>${DNM}</td>" TBL=${TBL}"</tr>" TBL=${TBL}"</table>" echo "${TBL}" > ${CACHE_DIR}${CACHE_FILE} # 検索結果が得られなかったらメッセージ"No contents"を書き込む RES=`cat ${RES_FILE}` if [ ${#RES} -eq 0 ]; then echo "No contents" >> ${RES_FILE} fi # タグ(ログファイル名にdt 内容にdd)を埋め込んでキャッシュファイルに書き込む while read line do #echo ${line} | sed -e "s/\(^[^:]\+:\)\(.*$\)/<dt>\1<\/dt><dd>\2<\/dd>/g" >> ${CACHE_DIR}${CACHE_FILE} echo ${line} | sed -e "s/${SIP}/<span class='sip'>${SIP}<\/span>/g" \ | sed -e "s/${DIP}/<span class='dip'>${DIP}<\/span>/g" \ | sed -e "s/\(^[^:]\+:\)\(.*$\)/<dt>\1<\/dt><dd>\2<\/dd>/g" >> ${CACHE_DIR}${CACHE_FILE} done < ${RES_FILE} :> ${RES_FILE} exit 0
index.php
主な機能:Baseから渡された日時の文字列に対応するキャッシュファイルがあったらそれを表示する。なかったらtarget_datetimeに日時を書き込んで、キャッシュファイルが生成されるのを待つ。
※Baseに戻るときはブラウザの戻るボタンを使用する。
<?php #// キャッシュディレクトリ $cache_dir = '/var/www/base/find_log/cache/'; #// grep対象の日時を書き込むファイル $target_dt = '/var/www/base/find_log/target_datetime'; #// このファイルのURL $base_url = 'https://EXAMPLE.EXA/base/find_log/index.php'; /************************************************* * キャッシュファイルの存在チェック *************************************************/ function existCacheFile ($timestamp = "", &$cache = "") { global $cache_dir; $cache = $cache_dir.strtr($timestamp, ' ', '_'); return file_exists($cache); } /************************************************* * Baseのタイムスタンプフォーマットかどうか *************************************************/ function isTimestamp ($ts = '', &$matches = array('')) { return preg_match('/^\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}$/', $ts, $matches); } /************************************************* * ipアドレスのフォーマットかどうか *************************************************/ function isIpformat ($ip = '', &$matches = array('')) { return preg_match('/^\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}$/', $ip, $matches); } if (isTimestamp(htmlentities($_GET['timestamp'], ENT_QUOTES), $ts)) { $timestamp = $ts[0]; if (!existCacheFile($timestamp)) { #// timestampがセットされていてキャッシュがなかったらtarget_datetimeファイルに書き込む isIpformat(htmlentities($_GET['sip'], ENT_QUOTES), $sip); isIpformat(htmlentities($_GET['dip'], ENT_QUOTES), $dip); if (!file_put_contents($target_dt, "$timestamp"." $sip[0]"." $dip[0]")) { echo "書き込みできませんでした"; } } } else { #// timestampがセットされていなかったらリフレッシュしてr_timestampに日時がセットされているはず if(!isTimestamp(htmlentities($_GET['r_timestamp'], ENT_QUOTES), $r_ts)) exit(); $timestamp = $r_ts[0]; } #// キャッシュファイルがまだ生成されていなかったら2秒後にリフレッシュする if (!existCacheFile($timestamp)) { header("refresh:2;url=$base_url?r_timestamp=$timestamp"); } ?> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script type="text/javascript" src="jquery-2.0.2.min.js"></script> <style type="text/css"> table.iptbl { border: solid 1px #CCC; border-collapse: collapse; } table.iptbl tr { border: solid 1px #CCC; } table.iptbl .title { background: #CCC; } table.iptbl td { padding: 3px; } span.sip { background: #7fffd4; } span.dip { background: #fed0e0; } dl { width: 100%; } dt { font-size: 120%; } dd { width: 100%; } </style> </head> <body> <?php echo "<h1>Log finder</h1>"; echo "<dl>"; if (existCacheFile($timestamp, $cf)) { echo file_get_contents($cf); } else { echo "ファイルを作成中"; } echo "</dl>"; ?> </body> <script type="text/javascript"> var dt_list = $('dt'), dlen = dt_list.length, dt_txt = ''; for (i=0; i<dlen; i+=1) { if (dt_txt !== (dt_txt = $(dt_list[i]).text())) { $(dt_list[i]).css({'background':'#ccc', 'margin-top':'20px', 'font-weight':'bolder', 'color':'#00f'}); } else { $(dt_list[i]).css({'font-size':'5px', 'background':'#f0f0f0', 'color':'#fff'}); } } </script> </html>
侵入検知ソフトSnortと周辺ツールをインストールする
Webサービスとは直接関係しないシステムの構築の中で、Snortが一番面倒くさかったので、記憶が薄れないうちにに復習を兼ねて備忘録として記します。
構築環境:さくらVPS CentOS6.4(64bit)
インストールする主なソフト:Snort2.9.4.5, Barnyard2, Pulledpork, Base
インフラ構築のプロではないのでツッコミどころ満載かと思いますが、不備な点などあったらご指摘頂ければうれしいです。ただコメント(認証制)頂いても最近は反応が鈍いことが多いのであしからず。
※尚、Barnyard2がWarningを頻繁に出します。状況と対処法(暫定的)はBarnyard2のインストールで記しています。
Snortのインストール
本体をインストールする前にlibdnet-debuginfo-1.12-6.choon.centos6.x86_64.rpmがどこかにあると思うのでググってダウンロードしてインストールしておきます。
# rpm -ivh libdnet-debuginfo-1.12-6.choon.centos6.x86_64.rpm場合によっては
libdnet-devel-1.12-6.el6.x86_64.rpm、
libpcap-devel-1.0.0-6.20091201git117cb5.el6.x86_64.rpmが必要になるかもしれないので、適宜インストール。
http://www.snort.org/からSnort本体とdaqを/usr/local/src/などにダウンロード。
daqのインストール
Snortのインストール
# tar -zxvf daq-2.0.0.tar.gz
# cd daq-2.0.0
# ./configure
# make
# make install
# cd /usr/local/lib
# ldconfig –v /usr/local/lib
Snortルールと設定ファイルのインストール
# tar -zxvf snort-2.9.4.5.tar.gz
# cd snort-2.9.4.5
# ./configure --enable-sourcefire
# make
# make install
# cd /usr/local/lib
# ldconfig –v /usr/local/lib
Snortユーザーの追加
# wget []http://www.snort.org/reg-rules/snortrules-snapshot-2945.tar.gz/[]-O snortrules-snapshot-2945.tar.gz
# cd /etc
# mkdir snort
# cd ./snort
# tar -zvxf /usr/local/src/snortrules-snapshot-2945.tar.gz
# cp ./etc/* .
# touch ./rules/white_list.rules ./rules/black_list.rules
ファイル・ディレクトリの所有者の変更
# groupadd -g 40000 snort
# useradd snort -u 40000 -d /var/log/snort -s /sbin/nologin -c SNORT_IDS –g snort
/etc/snort/snort.confの編集 青字部分が修正箇所 左側の数字は行数
# cd /etc/snort
# chown -R snort:snort *
# chown -R snort:snort /var/log/snort
daqとSnortのディレクトリのパーミッションを変更する
44 # Setup the network addresses you are protecting
45 ipvar HOME_NET XXX.XXX.XXX.XXX/24
46
47 # Set up the external network addresses. Leave as "any" in most situations
48 ipvar EXTERNAL_NET !$HOME_NET
・
・
・
101 # Path to your rules files (this can be a relative path)
102 # Note for Windows users: You are advised to make this an absolute path,
103 # such as: c:\snort\rules
104 var RULE_PATH /etc/snort/rules
105 var SO_RULE_PATH /etc/snort/so_rules
106 var PREPROC_RULE_PATH /etc/snort/preproc_rules
107
108 # If you are using reputation preprocessor set these
109 # Currently there is a bug with relative paths, they are relative to where snort is
110 # not relative to snort.conf like the above variables
111 # This is completely inconsistent with how other vars work, BUG 89986
112 # Set the absolute path appropriately
113 var WHITE_LIST_PATH /etc/snort/rules
114 var BLACK_LIST_PATH /etc/snort/rules
初期化スクリプトをセットする
# cd /usr/local/src
# chown -R snort:snort daq-2.0.0
# chmod -R 700 daq-2.0.0
# chown -R snort:snort snort-2.9.4.5
# chmod -R 700 snort-2.9.4.5
# chown -R snort:snort snort_dynamicsrc
# chmod -R 700 snort_dynamicsrc
Snortサイトから環境に合った初期化スクリプトをダウンロードする
最初の`----- CUT HERE -----`の間をコピーしてファイル名snortで/etc/init.d/に置く
wget []http://s3.amazonaws.com/snort-org/www/assets/208/snort-centos-6x.sh[]
#!/bin/bash
#
# snort Start up the SNORT Intrusion Detection System daemon
#
# chkconfig: 2345 55 25
# description: SNORT is a Open Source Intrusion Detection System
# This service starts up the snort daemon.
・
・(略)
・
echo $"Usage: $0 {start|stop|restart|status}"
RETVAL=2
esac
exit $RETVAL
次の`----- CUT HERE -----`の間をコピーしてファイル名snortで/etc/sysconfig/に置く
# chown snort:snort /etc/init.d/snort
# chmod 700 /etc/init.d/snort
# /etc/sysconfig/snort
# $Id: snort.sysconfig,v 1.8 2003/09/19 05:18:12 dwittenb Exp $#### General Configuration
・
・(略)
・
DUMP_APP=1
BINARY_LOG=1
NO_PACKET_LOG=0
PRINT_INTERFACE=0
シンボリックリンクの作成
# chown snort:snort /etc/sysconfig/snort
# chmod 700 /etc/sysconfig/snort
各ファイル・ディレクトリのパーミッションの設定
# cd /usr/sbin
# ln -s /usr/local/bin/snort snort
テストコマンドを打ってみる
# cd /var/log
# mkdir snort
# chmod 700 snort
# chown -R snort:snort snort
# cd /usr/local/lib
# chown -R snort:snort snort*
# chown -R snort:snort snort_dynamic*
# chown -R snort:snort pkgconfig
# chmod -R 700 snort*
# chmod -R 700 pkgconfig
# cd /usr/local/bin
# chown snort:snort daq-modules-config
# chown snort:snort u2*
# chmod 700 daq-modules-config
# chmod 700 u2*
# cd /etc
# chown -R snort:snort snort
# chmod -R 700 snort
以下のメッセージが表示されればOK
# cd /usr/local/bin
# ./snort -T -i eth0 -u snort -g snort -c /etc/snort/snort.conf
しかし
・
・(略)
・
Snort successfully validated the configuration!
Snort exiting
が表示された。
ERROR: snort.conf(253) Could not stat dynamic module path
"/usr/local/lib/snort_dynamicrules": No such file or directory.
Fatal Error, Quitting.
対処法
chkconfigに登録
# mkdir -p /usr/local/lib/snort_dynamicrules
# chown -R snort:snort /usr/local/lib/snort_dynamicrules
# chmod -R 700 /usr/local/lib/snort_dynamicrules
手動で実行するには
# chkconfig --add snort
# /usr/local/bin/snort -A fast -b -d -D -i eth0 -u snort -g snort -c /etc/snort/snort.conf -l /var/log/snort
DBとの連携 barnyard2のインストール
barnyard2をダウンロードとインストール
MySQLにDBを作成する 赤字の部分はそれぞれのパスワードを入力する
# cd /usr/local/src
# git clone []https://github.com/firnsy/barnyard2.git[]
# cd barnyard2
# ./autogen.sh
# ./configure --with-mysql --with-mysql-libraries=/usr/lib64/mysql/
# make
# make install
# cp etc/barnyard2.conf /etc/snort
# mkdir /var/log/barnyard2
# chmod 666 /var/log/barnyard2
# touch /var/log/snort/barnyard2.waldo
テーブル作成 解凍したbarnyard2のスクリプトを使って作成する
# mysql -u root -p root_password
mysql> CREATE DATABASE snort;
mysql> CREATE USER snort@localhost;
mysql> SET PASSWORD for snort@localhost=PASSWORD('snor_password');
mysql> GRANT INSERT, SELECT on root.* to snort@localhost;
mysql> GRANT CREATE, INSERT, SELECT, DELETE, UPDATE on snort.* to snort@localhost;
上記操作でテーブルが作成されているか確認する
# mysql -D snort -u root -p root_password < /usr/src/barnyard2/schemas/create_mysql
コンフィグレーション
27〜30行あたりに記述されているファイルが確実にあるか確認する。青字は変更した箇所
Snortのログ出力を止める
# vi /etc/snort/barnyard2.conf
25 # set the appropriate paths to the file(s) your Snort process is using.
26 #
27 config reference_file: /etc/snort/reference.config
28 config classification_file: /etc/snort/classification.config
29 config gen_file: /etc/snort/gen-msg.map
30 config sid_file: /etc/snort/sid-msg.map※54行目あたり
#config logdir: /tmp
↓
config logdir: /var/log/barnyard2※70行目あたり
#config hostname: thor
#config interface: eth0
↓
config hostname: localhost
config interface: eth0※141行目あたり
#config waldo_file: /tmp/waldo
↓
config waldo_file: /var/log/snort/barnyard2.waldo※最後に以下の行を追記
output database: log, mysql, user=snort password=dbname=snort host=localhost
動作テスト
# vi /etc/sysconfig/snort
※14〜19行目をすべてコメントにする
14 #LOGDIR=/var/log/snort
15 #ALERTMODE=fast
16 #DUMP_APP=1
17 #BINARY_LOG=1
18 #NO_PACKET_LOG=0
19 #PRINT_INTERFACE=0
barnyard2をシステムに登録する
※/etc/snort/rules/local.rulesに以下のテスト用alertを記述しておく
alert icmp any any -> any any (msg:"ICMP Testing Rule"; sid:1000001; rev:1;)※barnyard2を起動する
# cd /usr/local/bin
# ./barnyard2 -c /etc/snort/barnyard2.conf -d /var/log/snort -f merged.log -w /var/log/snort/barnyard2.waldo※もうひとつのターミナルウィンドウを立ち上げて当該サーバにpingコマンドを打つ。
barnyard2を開いているターミナルにリアルタイムにalertが表示されればOK。
nmapでポートスキャンもしてみてalertが表示さるかも確認。
以下のようなWarningを頻繁に出します。
# cp /usr/local/src/barnyard2/rpm/barnyard2 /etc/init.d/
# chmod +x /etc/init.d/barnyard2
# cp /usr/local/src/barnyard2/rpm/barnyard2.config /etc/sysconfig/barnyard2
# chkconfig --add barnyard2
いくつかWARNINGを確認してみたのですが、DBには記録されているようです。問題は一日で多いときで5回ほど落ちること。解決方法や原因を御教授いただけるとありがたいです。現在以下のようにして暫定的に対処しています。
Jul 5 05:38:55 XXXXXXXXXX barnyard2[25974]: WARNING database: [Database()] Failed transaction with current query transaction #012
Jul 5 05:38:55 XXXXXXXXXX barnyard2[25974]: WARNING database: Failed Query Position [1] Failed Query Body [INSERT INTO event (sid,cid,signature,timestamp) VALUES (1, 6735, 479, '2013-07-05 05:38:50');]
・
・
Jul 5 06:40:41 XXXXXXXXXX barnyard2[25974]: WARNING database [Database()]: End of failed transaction block
Jul 5 06:40:41 XXXXXXXXXX barnyard2[25974]: [RollbackTransaction(): Call failed, we reached the maximum number of transaction error [10]
Jul 5 06:40:41 XXXXXXXXXX barnyard2[25974]: FATAL ERROR: database Unable to rollback transaction in [Database()]
Jul 5 06:40:41 XXXXXXXXXX barnyard2[25974]: Barnyard2 exiting
※以下スクリプトを適当な名前をつけてcron.hourlyで監視させている
#!/bin/bashAT_WORK=`ps ax | grep barnyard2 | sed -n '/:[0-9][0-9] barnyard2 -D -c/ p' | wc -l`
if [ ${AT_WORK} -ne 1 ]; then
service barnyard2 start > /dev/null
echo 'Restart Barnyard2!' | mail -s 'Barnyard2 failuer!' root
fi
Baseのインストール (Snortのアラートをwebで見られるようにする)
※Webサーバの設定やアクセス制限については、http://centossrv.com/apache.shtmlやhttp://htaccess.pasoa.com/などを参考にしてください。
※適当なディレクトリにダウンロード
# wget []http://sourceforge.net/projects/secureideas/files/BASE/base-1.4.5/base-1.4.5.tar.gz[]
# wget []http://sourceforge.net/projects/adodb/files/adodb-php5-only/adodb-518-for-php5/adodb518a.tgz[]
# tar -xzvf base-1.4.5.tar.gz
# tar -xzvf adodb518a.tgz
# cp -r adodb5 /var/www
# mkdir /var/www/base
# cp -r base-1.4.5/* /var/www/base/
# cd /var/www/base
※base_conf.phpにリネームする
# mv base_conf.php.dist base_conf.php
# vi base_conf.php
・
・
50 $BASE_urlpath = '/base';
・
・
80 $DBlib_path = '/var/www/adodb5';
・
・
102 $alert_dbname = 'snort';
103 $alert_host = 'localhost';
104 $alert_port = '3306';
105 $alert_user = 'snort';
106 $alert_password = '実際のパスワード';
/var/www/base(https://zzzz.zz/base/とか)をブラウザーでアクセスして以下の作業をする。
/var/www/baseはbasic認証をかけて特定IPのみのアクセス制限をかけてSSLでブラウズしている。
base_main.php を開く
↓
“The underlying database snort@localhost appears to be incomplete/invalid.” のメッセージがある
↓
“Setup page” をクリック
↓
“Create BASE AG”ボタンをクリック
↓
メインページを開く
その後グラフ表示もできるようにしてみたが、ほとんど使わないのでここでは端折ります。
Snort ルールファイル自動アップデート Pulledporkのインストール
前準備…
perl-Net-SSLeay,
perl-libwww-perl,
perl-Archive-Tar
がインストールされていなかったら必ずインストール。ちなみにこの時点でインストール済みだったので私はなにもしなかった。
snort.confを修正する
# cd /usr/local/src/
# wget []https://pulledpork.googlecode.com/files/pulledpork-0.6.1.tar.gz[]
# tar zxvf /usr/local/src/snort/pulledpork-0.6.1.tar.gz
# mv pulledpork-0.6.1 pulledpork ※←リネームした
# vi /usr/local/src/pulledpork/etc/pulledpork.conf
・
・
20 rule_url=[]https://www.snort.org/reg-rules/[]|snortrules-snapshot.tar.gz|
21 # get the rule docs!
22 #rule_url=[]https://www.snort.org/reg-rules/[]|opensource.gz|
23 #rule_url=[]https://rules.emergingthreats.net/[]|emerging.rules.tar.gz|open
24 # THE FOLLOWING URL is for etpro downloads, note the tarball name change!
25 # and the et oinkcode requirement!
26 #rule_url=[]https://rules.emergingthreats.net/[]|etpro.rules.tar.gz|
・
・
71 rule_path=/etc/snort/rules/snort.rules
・
・
86 local_rules=/etc/snort/rules/local.rules
・
・
89 sid_msg=/etc/snort/sid-msg.map
・
・
108 snort_path=/usr/local/bin/snort
・
・
112 config_path=/etc/snort/snort.conf
・
・
116 sostub_path=/etc/snort/rules/so_rules.rules
・
・
124 distro=RHEL-6-0
・
・
159 pid_path=/var/run/snort_eth0.pid
pulledpork実行
# sed -i '/^include $RULE_PATH/d' /etc/snort/snort.conf
# echo "include \$RULE_PATH/snort.rules" >> /etc/snort/snort.conf
# echo "include \$RULE_PATH/local.rules" >> /etc/snort/snort.conf
# echo "include \$RULE_PATH/so_rules.rules" >> /etc/snort/snort.conf
SSLeay.pmを探す
/usr/local/src/pulledpork/pulledpork.pl -c /usr/local/src/pulledpork/etc/pulledpork.conf
※以下のようなエラーが!SSLeay.pm が見つからないらしい
Can't locate Crypt/SSLeay.pm in @INC・・・
/usr/lib64/perl5/Net/SSLeay.pmにあるのでpulledpork.plファイルの冒頭の部分を修正する
# find `perl -e 'print "@INC"'` -name 'SSLeay.pm' -print
find: `/usr/local/lib64/perl5': そのようなファイルやディレクトリはありません
find: `/usr/local/share/perl5': そのようなファイルやディレクトリはありません
/usr/lib64/perl5/Net/SSLeay.pm
再度実行したら以下のようなメッセージが表示されればOK。
# vi /usr/local/src/pulledpork/pulledpork.pl
…
use strict;
use warnings;
use File::Copy;
use LWP::UserAgent;
use HTTP::Request::Common;
use HTTP::Status qw (is_success);
use Crypt::SSLeay;
…
↓下のように変更
…
use strict;
use warnings;
BEGIN{
push(@INC, '/usr/lib64/perl5/Net');
}
use File::Copy;
use LWP::UserAgent;
use HTTP::Request::Common;
use HTTP::Status qw (is_success);
#use Crypt::SSLeay;
use Net::SSLeay;
…
[]http://code.google.com/p/pulledpork/[]
_____ ____
`----,\ )
`--==\\ / PulledPork v0.6.1 the Smoking Pig ///~ `--==\\/ .-~~~~-.Y|\\_ Copyright (C) 2009-2011 JJ Cummings @_/ / 66\_ cummingsj@gmail.com | \ \ _(") \ /-| ||'--' Rules give me wings! \_\ \_\\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checking latest MD5 for snortrules-snapshot-2945.tar.gz.... They Match Done! Prepping rules from snortrules-snapshot-2945.tar.gz for work.... 以下略
crontabに登録して毎日実行
0 0 * * * root /usr/local/src/pulledpork/pulledpork.pl -c /usr/local/src/pulledpork/etc/pulledpork.conf
参考サイト
- http://www.snort.org/docs
- http://polaris.umuc.edu/~sgantz/Install.html
- http://nachum234.no-ip.org/security/snort/104-configure-snort-automatic-rules-updating-with-pulledpork/
privateやprotectedメソッドをテストするのにつまずきました
で、こんなふうにしてみた…
HogeHelperのprotectedメソッド_taiGet()をテストするとします。
で、テストではこんなふうに
public $HogeRenderer = null;
public function setUp () {
$Controller = new Controller();
$View = new View($Controller);
$this->HogeRenderer = new HogeHelper($View);
以下略
と、しているわけですが、もっとなにかスマートな方法はないでしょうかね。
public function test_taiGet () {
$ref = new ReflectionMethod('HogeHelper', '_taiGet');
$ref->setAccessible(true);$this->assertEqual(
'tai',
$ref->invoke($this->HogeRenderer, 'ebi'))
);
以下略
それから…privateやpublicに関係なくpreg_replace_callbackを使っているメソッドを複数回実行すると一回目は成功するが二回目以後が Fatal error になるのはなぜだろう?
JSLintでボロボロの結果に…
ずいぶん前にチェックしたソースを再びチェックしたらエラー出まくりのボロボロの結果になってしまった。どうやらオプションのチェック項目が増えているような?以前のソースをローカルに落としていなかったので何が増えているのかよくわからない。
で、古いソースを修正したり追記した場合、とりあえず以前のチェックパターンというか差しさわり無い程度にチェックしたいとき、だいたいこんな感じなのかなというのが以下のパターン。"古い"とか"以前"というのがワタクシ的な定義ですのでご参考までに。
Tolerate dangling _ in identifiers:プライベート変数or関数のために先頭にアンダースコアを入れているソースではエラー表示される。プライベート用の名前空間をつくってそこに放り込んでおくのがいいんでしょうね。my.member = value; みたいに。
Tolerate misordered definitions:document やwindowなどソース外のオブジェクトを記述していたりするとエラー表示される。Predefinedのテキストボックスにカンマで区切って記述すればいいので、できれば無効にしないほうが良いですね。
Tolerate missing 'use strict' pragma:新しくコーディングするときはstrictモードで記述すべきでしょう。ただし'use strict;'を記述するとこのチェックを無効にしてもstrictモードとしてちゃんとチェックはするようだ。
Tolerate many var statements per function:あちこちにvar var 書いてあると、Problem at line 254 character 23: Combine this with the previous 'var' statement. のようなメッセージ(varの宣言を一か所にまとめろ)が出まくることになる。あわてて古いソースをやみくもに修正するとかえってバグの元になるので要注意。
Tolerate messy white space:タブとスペースの混在やインデントのミスを(口やかましくww)教えてくれます。現状で見やすいんだからいいじゃん…で済む場合は無効にしておきましょ。
JREが原因だったとは…
以前EclipseにERMasterをインストールしたとき、テストデータ作成画面のコンテキストメニューやらなにやらが、あちこちが字化けしてしまって使い物にならなかった。プルダウンメニューなんかも不正な表示をしてたのでCentOSの環境では使用をあきらめERMasterだけWindowsで使っていた。
で、今度はドキュメント作成のためのXMLmindをインストールしたら、入力する日本語が字化けする。文字が四角で表示されてERMasterと症状が似ているので、検索したらJRE(Java実行環境)の日本語フォントの設定が悪かったみたい。いずれのソフトも日本語化しないで使用してたので全く見当もつかなかった。
/usr/lib/jvm/jre/lib/にはfontconfig.ほにゃららがたくさんある。その中で一番基本的なネーミングのfontconfig.properties.srcファイルを開く。いろいろごにょごにょ記述してある。例えば dialog.plain.japanese-x0208=Sazanami Gothic のように日本語向け設定のような箇所にSazanami Gothicがある。で、ずっと下の方を見ると filename.Sazanami_Gothic=/usr/share/fonts/japanese/TrueType/sazanami-gothic.ttf のパスの指定が…。
CentOS6自体にsazanamiフォントが無いようだし、/usr/share/fonts/をみてもどこに日本語フォントがあるのかわからない。なのでIPAフォントをダウンロードした。
/usr/share/fonts/にjapanese/TrueType/ ディレクトリを作ってIPAフォントのipag.ttfとipam.ttfをコピーした。JREのfontconfigファイルはいちいち全部修正するのが面倒くさいのでfilenameを指定しているsazanami-gothicやsazanami-minchoの部分をそれぞれipag.ttf、ipam.ttfに置き換えた。下記
.srcの拡張子を削除してfontconfig.propertiesにして、他のfontconfigファイルはすべて削除(するのはちょっと怖いのでhomeディレクトリに移動しておいた)する。これでばっちりXMLmindで日本語が入力できるようになりました。めでたし!ついでにERMasterもちゃんと使えるようになった。
#filename.Sazanami_Gothic=/usr/share/fonts/japanese/TrueType/sazanami-gothic.ttf
filename.Sazanami_Gothic=/usr/share/fonts/japanese/TrueType/ipag.ttf
#filename.Sazanami_Mincho=/usr/share/fonts/japanese/TrueType/sazanami-mincho.ttf
filename.Sazanami_Mincho=/usr/share/fonts/japanese/TrueType/ipam.ttf
ちなみにJREのlibにfonts/fallbackディレクトリを作って日本語フォントのシンボリックリンクを置くという方法をあちこちで見たのですがうまくいきませんでした。
参考サイト:http://java.sun.com/javase/ja/6/docs/ja/technotes/guides/intl/fontconfig.html