サーバーのセキュリティを守るためには、不正アクセスの防止策が必要不可欠です。
今回は、Psionic Technologies Inc.が公開しているPortSentryという不正アクセス検知ソフト(もちろん、フリーソフトです)を利用し、これとNetSaintを連動させる仕組みを紹介しましょう。
(1)PortSentryのインストール
それではPortSentryをダウンロードし、いつもの手順で展開します。
# tar xvzf portsentry-2.0b1.tar.gz
# cd portsentry-2.0b1
|
ところで、このPortsentryは pcap.h というPacket Capture libraryのヘッダーファイルを使うのですが、RedHat Linux(今回使ったのは7.3のバージョンです)の場合、tarボールからインストールしたpcap.hと違う場所にインストールされているようなので
Makefile の修正が必要となります。
そこで、適当なエディタで /portsentry-2.0b1/Makefile を開き、最初のほうにあるCFLAGS
として定義されているディレクトリを修正する必要があります。
Makefileの先頭から、今回修正する箇所までを以下に示します。
# Makefile for PortSentry package.
#
# Send problems/code hacks to sentrysupport@psionic.com
#
#
# $Id: Makefile,v 1.78 2002/04/08 17:42:33 crowland Exp crowland $
#
# Generic compiler (usually linked to gcc on most platforms)
CC = cc
# GNU..
#CC = gcc
# Normal systems flags
CFLAGS = -O -Wall ⇒ CFLAGS = -O -Wall -I/usr/include/pcap に変更する。
|
修正が済んだら、コンパイルして、インストールです。
# make
# make linux
# make install
|
いつものインストールと違うところは、2番目の make linux です。
この make linux で次のようなメッセージが表示されますが、気にしないで進めてください。(~_~;)
SYSTYPE=linux
Making
cc -O -Wall -I/usr/include/pcap -D_BSD_SOURCE -o ./portsentry ./portsentry.c
\
./portsentry_io.c ./portsentry_util.c -lpcap
./portsentry.c:595:8: warning: extra tokens at end of #endif directive
./portsentry.c:710:8: warning: extra tokens at end of #endif directive |
以上により、/usr/local/psionic/portsentry2/ というディレクトリが作成され、次の3つのファイルがインストールされます。
@ portsentry ・・・ 実行ファイル
A portsentry.conf ・・・ 設定ファイル
B portsentry.ignore ・・・ チェックの対象外とするIPアドレスを登録する
|
Aのportsentry.conf で様々な設定を行うのですが、その設定内容を以下に示します。
オリジナルのportsentry.conf に記載されているコメントをほとんど削除し、修正した箇所を赤字で示すとともに説明を加えています。
# PortSentry Configuration
###########################
# Interface Configurations#
###########################
# PortSentryが監視するインターフェースを定義します。
# ここは"auto"のままでもいいようですが、"eth0"を定義しました。
#INTERFACE="auto"
INTERFACE="eth0"
# 上の「INTERFACE」に割り当てられているIPアドレスを定義します。(必須です。)
#INTERFACE_ADDRESS="XXX.XXX.XXX.XXX"
INTERFACE_ADDRESS="192.168.0.11"
#######################
# Port Configurations #
#######################
# 監視対象とするポート番号を列挙します。
# 必要に応じて追加・削除しましょう。
# Use these if you just want to be aware (default):
TCP_PORTS="1,11,15,79,111,119,143,515,540,635,666,1080,1524,2000,6667,12345,
12346,20034,27374,27665,31337,32771,32772,32773,32774,40421,49724,54320,54321"
UDP_PORTS="1,7,9,69,161,162,513,635,2049,27444,32770,32771,32772,32773,32774,
31337,54321"
######################
# Configuration Files#
######################
# 監視対象外とするIPアドレスを登録するファイルです。
IGNORE_FILE="/usr/local/psionic/portsentry2/portsentry.ignore"
# 不正アクセスの履歴ファイルです。
# 一番最初の起動時に作成され、以後はそれに記録を追加して行きます。
HISTORY_FILE="/usr/local/psionic/portsentry2/portsentry.history"
# アクセスをブロックした記録ファイルです。
# 再起動した場合、常に新しく作り直されます。
BLOCKED_FILE="/usr/local/psionic/portsentry2/portsentry.blocked"
##############################
# Misc. Configuration Options#
##############################
# 不正アクセスがあったIPアドレスからドメイン名を調べる場合には「1」にします。
RESOLVE_HOST = "0"
###################
# Response Options#
###################
# 不正アクセス先へ送るメッセージを定義するところです。(特に定義は不要です。)
##################
# Ignore Options #
##################
# 不正アクセスがあった場合の処理方法です。
# 最初は「2」で始めて、様子を見てから「1」にしましょう。
# 0 = Do not block UDP/TCP scans.
# 1 = Block UDP/TCP scans.
# 2 = Run external command only (KILL_RUN_CMD)
#BLOCK_UDP="1"
#BLOCK_TCP="1"
BLOCK_UDP="2"
BLOCK_TCP="2"
###################
# Dropping Routes:#
###################
# BLOCK_UDP、BLOCK_TCPが「1」の場合、不正アクセスが行われたIPアドレスを
# フィルタリングします。
# オリジナルのportsentry.confにはいろいろなパターンが例示されています。
# 自分のサーバーに適したものを選択しましょう。(パスも確認しましょう。)
# iptables support for Linux
#KILL_ROUTE="/usr/local/bin/iptables -I INPUT -s $TARGET$ -j DROP"
KILL_ROUTE="/sbin/iptables -I INPUT -s $TARGET$ -j DROP"
###############
# TCP Wrappers#
###############
# BLOCK_UDP、BLOCK_TCPが「1」の場合、/etc/hosts.deny に以下の内容を追加します。
($TARGET$=不正アクセスが行われたIPアドレス)
KILL_HOSTS_DENY="ALL: $TARGET$"
###################
# External Command#
###################
# 不正アクセスを行ったIPアドレスをブロックする処理と、次に定義する「KILL_RUN_CMD」
# の実行する順序を定義します。
# 「KILL_RUN_CMD」を先に実行する場合は「1」にします。
#KILL_RUN_CMD_FIRST = "0"
KILL_RUN_CMD_FIRST = "1"
#
# 不正アクセスを検知した場合に実行するスクリプトを定義します。
# このスクリプトの内容は、後で説明します。
#KILL_RUN_CMD="/some/path/here/script $TARGET$ $PORT$ $MODE$"
KILL_RUN_CMD="/usr/local/netsaint/libexec/eventhandlers/submit_portsentry_result
'ms1' 'Port Scans' 2 'Port scan from host $TARGET$ on port $PORT$. Host
has been firewalled.'"
#####################
# Scan trigger value#
#####################
# 不正アクセスとみなすまでのアクセス許容回数です。
# 「0」は、直ちに不正アクセスとみなします。
SCAN_TRIGGER="0" |
Bの portsentry.ignore は次のように定義されています。
# PortSentry can support full netmasks for networks as well. Format is:
#
# <IP Address>/<Netmask>
#
# Example:
#
# 192.168.2.0/24
# 192.168.0.0/16
# 192.168.2.1/32
# Etc.
#
# If you don't supply a netmask it is assumed to be 32 bits.
#
127.0.0.0/8
0.0.0.0 |
監視対象外とするIPアドレスを登録するのですが、Aのportsentry.conf のBLOCK_UDP、BLOCK_TCPを「2」として暫く稼動させてから、必要に応じて修正するようにしましょう。
以上で、PortSentry のインストール及び設定ができました。
なお、NetSaintと連動させずに、PortSentryを単独で稼動させる場合、「KILL_RUN_CMD_FIRST=0」とし、「KILL_RUN_CMD 」をコメントアウトのままにしておきます。
(2)NetSaintの設定
NetSaint側の設定は、次の3点です。
@ Passive Service Checksが使えるように設定する。
A /usr/local/netsaint/etc/hosts.cfgでPortSentryが稼動するホストに対し、
「Port Scans」というサービスを定義し、そのサービスの<max_attempts>を「1」、
<check_period>を「none」と定義する。
A /usr/local/netsaint/libexec/eventhandlers/submit_portsentry_result という
スクリプトを定義する。 |
@については、NetASaintのデフォルトのインストールで設定されていますので、特に処理は不要です。
(基本編の「Main Configuration File」及び応用編の「アクティブサービスチェックとパッシブサービスチェック」を参照してください。)
Aについては、以下の内容を/usr/local/netsaint/etc/hosts.cfg に追加します。
(ホスト名を「ms1」とします。)
service[ms1]=Port Scans;0;none;1;5;1;admins;120;24x7;1;1;1;;check_ping
|
<check_command>に何も定義しておかないとNetSaintが起動しませんので、一番ポピュラーな「check_ping」を定義しています。
(とりあえず、実際にチェックを行った場合に「OK」が返ってくるコマンドにしておきましょう。)
< 余 談 1 >
ところで、今回の原文はNetSaintの「Volatile Services」のページです。
ですから、Port Scansのサービスで<volatile>の項目を「1」に設定するものと思っていたのですが、どうやら効果がないようです。
となると、この<volatile>という項目は、どういうときに設定するのでしょう。(ーー;)
どなたかご存知であれば教えていただけませんでしょうか。<(_ _)>
さて、Bの /usr/local/netsaint/libexec/eventhandlers/submit_portsentry_result は次のようなシェルスクリプトです。
#!/bin/sh
# Write a command to the NetSaint command file to cause
# it to process a service check result
echocmd="/bin/echo"
CommandFile="/usr/local/netsaint/var/rw/netsaint.cmd"
# get the current date/time in seconds since UNIX epoch
datetime=`date +%s`
# create the command line to add to the command file
cmdline="[$datetime] PROCESS_SERVICE_CHECK_RESULT;$1;$2;$3;$4"
# append the command to the end of the command file
`$echocmd $cmdline >> $CommandFile`
|
このスクリプトの$1、$2、$3、$4には、以下の値が入ります。
$1:ms1
$2:Port Scans
$3:2
$4:Port scan from host $TARGET$ on port $PORT$. Host has been firewalled. |
$3の「2」は「CRITICAL」という意味です。
また、$TARGET$ には不正アクセスを行ったIPアドレス、$PORT$ には目標とされたポート番号が入ります。
以上でNetSaintの準備ができましたので、(再)起動させてください。
なお、「/usr/local/netsaint/libexec/eventhandlers/submit_portsentry_result」のスクリプトが実行されたときに、「/usr/local/netsaint/var/rw/netsaint.cmd」に書き込めるようにしておく必要があります。
(応用編「エクスターナルコマンド」を参照してください。)
(3)不正アクセス監視スタート
NetSaintの準備もできたので、いよいよPortSentryを実行しましょう。
実行する方法は、次のとおりいたって簡単です。
(サーバー再起動時にPortSentryも自動的に立ち上がるよう /etc/rc.d/rc.local に追記しておきましょう。)
# /usr/local/psionic/portsentry2/portsentry
|
実行後、すぐにログ(/var/log/messages)を見ると、次のように表示されているはずです。
Oct 30 23:24:59 ms1 portsentry[6200]: adminalert: Monitoring interface eth0 and
address: 192.168.0.11
Oct 30 23:24:59 ms1 portsentry[6200]: adminalert: Initializing PortSentry
BPF filters.
Oct 30 23:24:59 ms1 portsentry[6200]: adminalert: Monitoring TCP ports:
1,11,15,79,111,119,
143,515,540,635,666,1080,1524,2000,6667,12345,12346,20034,27374,27665,31337,32771,32772,
32773,32774,40421,49724,54320,54321
Oct 30 23:24:59 ms1 portsentry[6200]: adminalert: Monitoring UDP ports:1,7,9,69,161,162,513,
635,2049,27444,32770,32771,32772,32773,32774,31337,54321 |
そして、不正アクセス防止対象としたポートに対し外部からアクセスがあった場合、次のようなログが残されます。
Oct 30 23:30:06 ms1 portsentry[6200]: attackalert: External command run for host
: 12.34.56.78 using command: "/usr/local/netsaint/libexec/eventhandlers/submit_portsentry_result
'ms1' 'Port Scans' 2 'Port scan from host 12.34.56.78 on port 2000. Host
has been firewalled.'"
Oct 30 23:30:06 ms1 portsentry[6200]: attackalert: Unknown/Illegal scan
type: TCP Packet Flags: FIN 0 SYN: 0 RST: 0 PUSH: 0 ACK: 1 URG: 0 UNUSED1:
0 UNUSED2: 0 scan from host 12.34.56.78/12.34.56.78 to TCP port: 2000
from TCP port: 80 |
このログでは、「12.34.56.78」のIPアドレスからTCPの「2000」番のポートにアクセスがあったことを示しています。
最初のログが「KILL_RUN_CMD」を実行したことを示し、次のログはブロッキングした内容を示しています。
今回は、「KILL_RUN_CMD」を実行するだけの設定にしていますが、ブロッキングするように設定した場合、
「iptables」に次のルールが設定されるとともに、
| -A INPUT -s 12.34.56.78 -j DROP |
「/etc/hosts.deny」に次の内容が追加され、このIPアドレスからのあらゆるアクセスをブロックします。
一方、NetSaintの方では「KILL_RUN_CMD」により
「/usr/local/netsaint/libexec/eventhandlers/submit_portsentry_result」のシェルスクリプトが実行され、「/usr/local/netsaint/var/rw/netsaint.cmd」に
[1035988264] PROCESS_SERVICE_CHECK_RESULT: ms1;Port Scans;2;Port scan from
host
12.34.56.78 on port 2000. Host has been firewalled. |
という内容が書き込まれます。
NetSaintはパッシブサービスチェックとしてこれを処理し、Webブラウザから状態を確認できるようにするとともに、警告メールを発信し、次のようなログ(/usr/local/netsaint/var/netsaint.log)を残します。
[1035988264] SERVICE ALERT: ms1;Port Scans;CRITICAL;HARD;1;Port scan from
host
12.34.56.78 on port 2000. Host has been firewalled.
[1035988264] SERVICE NOTIFICATION: admin;ms1;Port Scans;CRITICAL;notify-by-email
;Port scan from host 12.34.56.78 on port 2000. Host has been firewalled. |
(4)Port Scans サービスの状態(Status)の修正
ところで、不正アクセスがあった場合、Port Scansのサービスの状態がいつまでも「CRITICAL」となったままですので、これをWebブラウザから「OK」の状態に戻す方法を説明しましょう。
まず、WebブラウザでStatus Detail CGI (見本)にアクセスします。
そして、HOST「ms1」のService「Port Scans」をクリックし、「Information For Service Port Scans On HOST ms1」の画面を開きます。
そして、この「Information For Service Port Scans On HOST ms1」の右下にある「Service Commands」(右図参照)の上から8つめのコマンド「Submit passive check result for this service」をクリックします。

そうすると、「External Command Interface 」が開きますので、その画面の「Command Optinons」(左図参照)の「Check Output」欄に適当なコメントを書いて、「Commit」ボタンをクリックします。
既にお気づきかと思いますが、パッシブサービスチェックを利用してNetSaintの「Port
Scans」の状態を「OK」に戻すわけです。
< 余 談 2 >
Port Scansのサービス定義で<volatile>を「1」にしておけば、この処理が不要のような気がするのですが、どうもちがうようです。
|