ゲーム業界エンジニアの独り言

クライアント、サーバ、インフラなどなど興味あることなんでも紹介

CentOSでサーバー公開するためのセキュリティ設定メモ

セキュリティ設定メモ

全パッケージのアップデート

# yum –y update

root アカウントにメールアドレス設定

# vi /etc/aliases

root:           メールアドレス

設定更新

newaliases

テスト送信

echo test|mail root

ssh 設定

リモートからの root ログインを無効

# vi /etc/ssh/sshd_config

PermitRootLogin no
PermitEmptyPasswords no

root になれるユーザーを限定

root になれるユーザーは wheel グループのみ。

# usermod -G wheel ggc
# visudo

%wheel ALL=(ALL) ALL

ポート番号を変更

# vi /etc/ssh/sshd_config

Port 10022

ssh 再起動。

/etc/init.d/sshd restart

iptables 設定

INPUT, FORWARD, OUTPUTを一旦全て閉じる。 使用するIPのポートのみ空ける。 今回は アクセス許可IPの https(443) とローカルのみ。

# vi /etc/sysconfig/iptables

# Generated by iptables-save v1.4.7 on Thu May  1 20:30:59 2014
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -s 200.000.000.000 -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -s 192.168.36.0/24 -j ACCEPT
COMMIT
# Completed on Thu May  1 20:30:59 2014

再起動

# /etc/init.d/iptables restart

ログ監視設定

ログ監視ツールとして logwatch をインストールする。 1日一回ログの内容を整形して root にメールを送ってくれる。

# yum  install logwatch

ウィルス対策ソフト設定

保険的な対策も含めて導入。 オープンソースのウィルス対策ソフトである Clam AntiVirus を導入する。

EPEL リポジトリ導入

# rpm -Uvh  http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

Clam AntiVirus 導入

# yum –y --enablerepo=epel install clamd

root 権限で動作するように変更。

# vi /etc/clamd.conf

#User clamav

起動と自動起動設定。

# /etc/rc.d/init.d/clamd start
# chkconfig clamd on

ウィルス定義ファイル最新化。 ウィルス定義ファイル更新機能の有効化。

# vi /etc/freshclam.conf

#Example

ウィルススキャンテスト。

# clamscan --infected --remove --recursive

デイリーでのチェック設定

結果を root のメールアドレスに送信。 /etc/cron.daily に実行スクリプトを配置すると 毎日、AM 3:00 ごろに実行される。

# vi /etc/cron.daily/virusscan 
#!/bin/bash

PATH=/usr/bin:/bin

# clamd update
yum -y update clamd > /dev/null 2>&1

# excludeopt setup
excludelist=/root/clamscan.exclude
if [ -s $excludelist ]; then
    for i in `cat $excludelist`
    do
        if [ $(echo "$i"|grep \/$) ]; then
            i=`echo $i|sed -e 's/^\([^ ]*\)\/$/\1/p' -e d`
            excludeopt="${excludeopt} --exclude-dir=^$i" 
        else
            excludeopt="${excludeopt} --exclude=^$i" 
        fi
    done
fi

# virus scan
CLAMSCANTMP=`mktemp`
clamscan --recursive --remove ${excludeopt} / > $CLAMSCANTMP 2>&1
[ ! -z "$(grep FOUND$ $CLAMSCANTMP)" ] && \

# report mail send
grep FOUND$ $CLAMSCANTMP | mail -s "Virus Found in `hostname`" root
rm -f $CLAMSCANTMP

実行権限付加。

# chmod +x virusscan

rootkit 検知ツールを導入

chkrootkit というrootkit 検知ツールを導入。 rootkitLinuxサーバーにインストールされてしまっていないかチェック。

rootkit とは クラッカーが遠隔地のコンピュータに不正に侵入した後に利用するソフトウェアをまとめたパッケージ。

chkrootkit インストール

# yum --enablerepo=epel install chkrootkit

chkrootkit 存在を確認

# chkrootkit | grep INFECTED

上記chkrootkit実行結果として"INFECTED"という行が表示されなければ問題なし

デイリーでのチェック設定

結果を root のメールアドレスに送信。 /etc/cron.daily に実行スクリプトを配置すると 毎日、AM 3:00 ごろに実行される。

# vi /etc/cron.daily/chkrootkit 
#!/bin/bash

PATH=/usr/bin:/bin

TMPLOG=`mktemp`

# chkrootkit実行
chkrootkit > $TMPLOG

# ログ出力
cat $TMPLOG | logger -t chkrootkit

# SMTPSのbindshell誤検知対応
if [ ! -z "$(grep 465 $TMPLOG)" ] && \
   [ -z $(/usr/sbin/lsof -i:465|grep bindshell) ]; then
        sed -i '/465/d' $TMPLOG
fi

# upstartパッケージ更新時のSuckit誤検知対応
if [ ! -z "$(grep Suckit $TMPLOG)" ] && \
   [ -z $(rpm -V `rpm -qf /sbin/init`) ]; then
        sed -i '/Suckit/d' $TMPLOG
fi

# rootkit検知時のみroot宛メール送信
[ ! -z "$(grep INFECTED $TMPLOG)" ] && \
grep INFECTED $TMPLOG | mail -s "chkrootkit report in `hostname`" root

rm -f $TMPLOG

実行権限付加。

# chmod +x virusscan

改ざん監視ソフト設定

AIDE オープンソースのホスト型侵入検知システム(HIDS)。 これを使うことで、ファイルの改ざん監視を行える。

AIDE のインストール

# yum install aide

設定ファイルの編集

必要のある場合は修正。

# vi /etc/aide.conf

データベースファイルの作成

# aide --init
# cp /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz

改ざんチェック

# aide --update

改ざんが検知されると以下のような結果が出力される。

AIDE found differences between database and filesystem!!
Start timestamp: 2009-11-30 14:39:45
Summary:
Total number of files=11247,added files=0,removed files=0,changed files=1
Changed files:
changed:/bin/ls
Detailed information about changes:
File: /bin/ls
Mtime : 2009-11-30 14:26:18 , 2009-11-30 14:39:39
Ctime : 2009-11-30 14:26:18 , 2009-11-30 14:39:39

データベースファイルの更新

# cp /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz

監視ポリシー(aide.conf)

監視ポリシーは、インストール時の標準のものでも、例えば/etcや/bin配下などの広範囲にチェックを行う。 ただし、標準では、/var/logや/root配下もチェックするので ユーザーのログイン、rootがコマンドを実行しただけで、改ざんとして通知される。 こうした検知が煩わしい、もしくは独自ファイルの監視を行いたい場合、カスタマイズが必要。

例えば、以下の例の場合、全てのファイルに関して、 パーミッション、ユーザー、グループに変更があった場合、改ざんとして検知されます。

/ p+u+g

デイリーでのチェック設定

結果を root のメールアドレスに送信。 /etc/cron.daily に実行スクリプトを配置すると 毎日、AM 3:00 ごろに実行される。

# vi /etc/cron.daily/aide
#!/bin/bash

# These settings are mainly for the wrapper scripts around aide,
# such as aideinit and /etc/cron.daily/aide

# This is the email address reports get mailed to

MAILTO=root

# Set this to suppress mailings when there's nothing to report

#QUIETREPORTS=1

# This parameter defines which aide command to run from the cron script.
# Sensible values are "update" and "check".
# Default is "check", ensuring backwards compatibility.
# Since "update" does not take any longer, it is recommended to use "update",
# so that a new database is created every day. The new database needs to be
# manually copied over the current one, though.

COMMAND=update

# This parameter defines how many lines to return per e-mail. Output longer
# than this value will be truncated in the e-mail sent out.

LINES=1000

# This parameter gives a grep regular expression. If given, all output lines
# that _don't_ match the regexp are listed first in the script's output. This
# allows to easily remove noise from the aide report.

NOISE="" 

# This parameter defines which options are given to aide in the daily
# cron job. The default is "-V4".

AIDEARGS="" 

PATH="/sbin:/usr/sbin:/bin:/usr/bin" 
LOGDIR="/var/log/aide" 
LOGFILE="aide.log" 
CONFFILE="/etc/aide.conf" 
ERRORLOG="error.log" 
ERRORTMP=`mktemp -t "$ERRORLOG".XXXXXXXXXX`

[ -f /usr/sbin/aide ] || exit 0

AIDEARGS="-V4" 

if [ -f /etc/default/aide ]; then
        . /etc/default/aide
fi

FQDN=`hostname -f`
DATE=`date +"at %Y-%m-%d %H:%M"`

# default values

MAILTO="${MAILTO:-root}" 
DATABASE="${DATABASE:-/var/lib/aide/aide.db.gz}" 
LINES="${LINES:-1000}" 
COMMAND="${COMMAND:-check}" 

if [ ! -f $DATABASE ]; then
        (
        echo "Fatal error: The AIDE database does not exist!" 
        echo "This may mean you haven't created it, or it may mean that someone has removed it." 
        ) | /usr/bin/mail -s "Daily AIDE report for $FQDN" $MAILTO
        exit 0
fi

aide $AIDEARGS --$COMMAND >"$LOGDIR/$LOGFILE" 2>"$ERRORTMP" 
RETVAL=$?

if [ -n "$QUIETREPORTS" ] && [ $QUIETREPORTS -a \! -s $LOGDIR/$LOGFILE -a \! -s $ERRORTMP ]; then
        # Bail now because there was no output and QUIETREPORTS is set
        exit 0
fi

(cat << EOF;
This is an automated report generated by the Advanced Intrusion Detection
Environment on $FQDN ${DATE}.

EOF

# include error log in daily report e-mail

if [ "$RETVAL" != "0" ]; then
        cat > "$LOGDIR/$ERRORLOG" << EOF;

*****************************************************************************
*                    aide returned a non-zero exit value                    *
*****************************************************************************

EOF
        echo "exit value is: $RETVAL" >> "$LOGDIR/$ERRORLOG" 
else
        touch "$LOGDIR/$ERRORLOG" 
fi
< "$ERRORTMP" cat >> "$LOGDIR/$ERRORLOG" 
rm -f "$ERRORTMP" 

if [ -s "$LOGDIR/$ERRORLOG" ]; then
        errorlines=`wc -l "$LOGDIR/$ERRORLOG" | awk '{ print $1 }'`
        if [ ${errorlines:=0} -gt $LINES ]; then
                cat << EOF;

****************************************************************************
*                      aide has returned many errors.                      *
*           the error log output has been truncated in this mail           *
****************************************************************************

EOF
                echo "Error output is $errorlines lines, truncated to $LINES." 
                head -$LINES "$LOGDIR/$ERRORLOG" 
                echo "The full output can be found in $LOGDIR/$ERRORLOG." 
        else
                echo "Errors produced  ($errorlines lines):" 
                cat "$LOGDIR/$ERRORLOG" 
        fi
else
        echo "AIDE produced no errors." 
fi

# include de-noised log

if [ -n "$NOISE" ]; then
        NOISTEMP=`mktemp -t aidenoise.XXXXXXXXXX`
        NOISTEMP2=`mktemp -t aidenoise.XXXXXXXXXX`
        sed -n '1,/^Detailed information about changes:/p' "$LOGDIR/$LOGFILE" | \
        grep '^\(changed\|removed\|added\):' | \
        grep -v "^added: THERE WERE ALSO [0-9]\+ FILES ADDED UNDER THIS DIRECTORY" > $NOISETMP2

        if [ -n "$NOISE" ]; then
                < $NOISETMP2 grep -v "^\(changed\|removed\|added\):$NOISE" > $NOISETMP
                rm -f $NOISETMP2
                echo "De-Noised output removes everything matching $NOISE." 
        else
                mv $NOISETMP2 $NOISETMP
                echo "No noise expression was given." 
        fi

        if [ -s "$NOISETMP" ]; then
                loglines=`< $NOISETMP wc -l | awk '{ print $1 }'`
                if [ ${loglines:=0} -gt $LINES ]; then
                        cat << EOF;

****************************************************************************
*   aide has returned long output which has been truncated in this mail    *
****************************************************************************

EOF
                        echo "De-Noised output is $loglines lines, truncated to $LINES." 
                        < $NOISETMP head -$LINES
                        echo "The full output can be found in $LOGDIR/$LOGFILE." 
                else
                        echo "De-Noised output of the daily AIDE run ($loglines lines):" 
                        cat $NOISETMP
                fi
        else
                echo "AIDE detected no changes after removing noise." 
        fi
        rm -f $NOISETMP
        echo "============================================================================" 
fi

# include non-de-noised log

if [ -s "$LOGDIR/$LOGFILE" ]; then
        loglines=`wc -l "$LOGDIR/$LOGFILE" | awk '{ print $1 }'`
        if [ ${loglines:=0} -gt $LINES ]; then
                cat << EOF;

****************************************************************************
*   aide has returned long output which has been truncated in this mail    *
****************************************************************************

EOF
                echo "Output is $loglines lines, truncated to $LINES." 
                head -$LINES "$LOGDIR/$LOGFILE" 
                echo "The full output can be found in $LOGDIR/$LOGFILE." 
        else
                echo "Output of the daily AIDE run ($loglines lines):" 
                cat "$LOGDIR/$LOGFILE" 
        fi
else
        echo "AIDE detected no changes." 
fi
) | /bin/mail -s "Daily AIDE report for $FQDN" $MAILTO

prelink を無効化

以下の警告が発生

/usr/sbin/prelink: /usr/sbin/luserdel: at least one of file's dependencies has changed since prelinking

prelink 無効化

vi /etc/sysconfig/prelink

PRELINKING=no
/usr/sbin/prelink -ua