iptablesの設定

ホームへ戻る

      合計:
昨日:
今日:
更新日:2012/12/31
 
エラー対処

このページは、下記の方々からの情報をもとに記してあります。

DOS攻撃を理解している必要がありますので、関連するサイトも下記に記します。

DoS攻撃
連載記事 「ゼロから始めるLinuxセキュリティ」

◆仕組み <<TOP

iptablesには初めから3つのfilter、nat、mangleテーブルが用意されています。

テーブル名 チェイン名 チェインの説明
filter INPUT 受信したパケットに対するチェイン
OUTPUT 送信したパケットに対するチェイン
FORWARD  
nat OUTPUT  
PREROUTING 受信時にパケットのアドレスを変換するチェイン
POSTROURING 送信時にパケットのアドレスを変換するチェイン
mangle OUTPUT  
PREROUTING  

チェインの位置

◆設定例 <<TOP
 

#iptable -L   チェインのルールを一覧表示するコマンドです。

1.ポリシーを決める。

#iptables -P INPUT ACCEPT   受信パケットは一旦すべて許可

#iptables -P FORWARD DROP  転送(FORWARD)は使わないのでDROP(破棄)

#iptables -P OUTPUT ACCEPT 送信パケットはすべて許可

2.ルールを全てクリア

/etc/init.d/iptables stop       ルールのクリア

3.ルールをキー入力する。

icmp(ping)と自端末からの入力を許可

# iptables -A INPUT -p icmp -j ACCEPT
# iptables -A INPUT -i lo -j ACCEPT

Web、FTP、POP、smtp による接続を許可

# iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# iptables -A INPUT -p tcp --dport 110 -j ACCEPT POP
# iptables -A INPUT -p tcp --dport 25 -j ACCEPT

DNSサーバの運用があるなら次の2行を追加

# iptables -A INPUT -p tcp --dport 53 -j ACCEPT
# iptables -A INPUT -p udp --dport 53 -j ACCEPT

ssh による接続を許可

# iptables -A INPUT -p tcp --dport 22 -j ACCEPT

1000番(Webmin)を特定のIPアドレスのみ許可
# iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 10000 -j ACCEPT
# iptables -A INPUT -s 192.168.1.0/24 -p tcp --sport 10000 -j ACCEPT

TCPの接続開始と応答、FTPデータなどを許可
# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

#----------------------------------------------------#
# 外部からの137,138番ポート(samba)へのアクセスを許可     #
#----------------------------------------------------#
iptables -A INPUT -p udp --dport 137:138 -j ACCEPT
iptables -A INPUT -p tcp --dport 139 -j ACCEPT

ルールは、これでは、まだ不十分です。セキュリティが甘い状態です。
それで、ルールについては、別途、追加する必要があります。

他の接続はすべて破棄(ポリシーの再設定)
# iptables -P INPUT DROP

4.設定をセーブする

ここまでキー入力したルールは、サーバを再起動すると消えてしまいます。
よって、ルールをセーブし、次回の起動時にも適用されるようにします。

ルールをセーブする
# /etc/init.d/iptables save

5.iptables を再起動する。

iptables の再起動
# service iptables restart

上記のことを、コマンドラインで入力していくこともできるが、シェルスクリプトを用いて、これらの入力を、自動化する。

 
◆シェルスクリプトによるiptablesの設定 <<TOP
iptablesの設定をシェルスクリプトを使用して行うこととする。再起動のたびに設定する手間を省くとともに他のサーバーに移行することも 簡単に行えるため、CentOSで自宅サーバー構築様のiptableの設定を参考にしております。

@iptablesの設定

[root@server ~]# vi iptables.sh  ← ファイアウォール設定スクリプト作成 
#!/bin/bash

#---------------------------------------#
# 設定開始                              #
#---------------------------------------#

# インタフェース名定義
LAN=eth0

#---------------------------------------#
# 設定終了                              #
#---------------------------------------#

# 内部ネットワークのネットマスク取得
LOCALNET_MASK=`ifconfig $LAN|sed -e 's/^.*Mask:\([^ ]*\)$/\1/p' -e d`

# 内部ネットワークアドレス取得
LOCALNET_ADDR=`netstat -rn|grep $LAN|grep $LOCALNET_MASK|cut -f1 -d' '`
LOCALNET=$LOCALNET_ADDR/$LOCALNET_MASK


# ファイアウォール停止(すべてのルールをクリア)
/etc/rc.d/init.d/iptables stop

# デフォルトルール(以降のルールにマッチしなかった場合に適用するルール)設定
iptables -P INPUT   DROP   # 受信はすべて破棄
iptables -P OUTPUT  ACCEPT # 送信はすべて許可
iptables -P FORWARD DROP   # 通過はすべて破棄

# 自ホストからのアクセスをすべて許可
iptables -A INPUT -i lo -j ACCEPT

# 内部からのアクセスをすべて許可
iptables -A INPUT -s $LOCALNET -j ACCEPT

# 内部から行ったアクセスに対する外部からの返答アクセスを許可
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# SYN Cookiesを有効にする
# ※TCP SYN Flood攻撃対策
sysctl -w net.ipv4.tcp_syncookies=1 > /dev/null
sed -i '/net.ipv4.tcp_syncookies/d' /etc/sysctl.conf
echo "net.ipv4.tcp_syncookies=1" >> /etc/sysctl.conf

# ブロードキャストアドレス宛pingには応答しない
# ※Smurf攻撃対策
sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1 > /dev/null
sed -i '/net.ipv4.icmp_echo_ignore_broadcasts/d' /etc/sysctl.conf
echo "net.ipv4.icmp_echo_ignore_broadcasts=1" >> /etc/sysctl.conf

# ICMP Redirectパケットは拒否
sed -i '/net.ipv4.conf.*.accept_redirects/d' /etc/sysctl.conf
for dev in `ls /proc/sys/net/ipv4/conf/`
do
    sysctl -w net.ipv4.conf.$dev.accept_redirects=0 > /dev/null
    echo "net.ipv4.conf.$dev.accept_redirects=0" >> /etc/sysctl.conf
done

# Source Routedパケットは拒否
sed -i '/net.ipv4.conf.*.accept_source_route/d' /etc/sysctl.conf
for dev in `ls /proc/sys/net/ipv4/conf/`
do
    sysctl -w net.ipv4.conf.$dev.accept_source_route=0 > /dev/null
    echo "net.ipv4.conf.$dev.accept_source_route=0" >> /etc/sysctl.conf
done

# フラグメント化されたパケットはログを記録して破棄
iptables -A INPUT -f -j LOG --log-prefix '[IPTABLES FRAGMENT] : '
iptables -A INPUT -f -j DROP

# 外部とのNetBIOS関連のアクセスはログを記録せずに破棄
# ※不要ログ記録防止
iptables -A INPUT ! -s $LOCALNET -p tcp -m multiport --dports 135,137,138,139,445 -j DROP
iptables -A INPUT ! -s $LOCALNET -p udp -m multiport --dports 135,137,138,139,445 -j DROP
iptables -A OUTPUT ! -d $LOCALNET -p tcp -m multiport --sports 135,137,138,139,445 -j DROP
iptables -A OUTPUT ! -d $LOCALNET -p udp -m multiport --sports 135,137,138,139,445 -j DROP

# 1秒間に4回を超えるpingはログを記録して破棄
# ※Ping of Death攻撃対策
iptables -N LOG_PINGDEATH
iptables -A LOG_PINGDEATH -m limit --limit 1/s --limit-burst 4 -j ACCEPT
iptables -A LOG_PINGDEATH -j LOG --log-prefix '[IPTABLES PINGDEATH] : '
iptables -A LOG_PINGDEATH -j DROP
iptables -A INPUT -p icmp --icmp-type echo-request -j LOG_PINGDEATH

# 全ホスト(ブロードキャストアドレス、マルチキャストアドレス)宛パケットはログを記録せずに破棄
# ※不要ログ記録防止
iptables -A INPUT -d 255.255.255.255 -j DROP
iptables -A INPUT -d 224.0.0.1 -j DROP

# 113番ポート(IDENT)へのアクセスには拒否応答
# ※メールサーバ等のレスポンス低下防止
iptables -A INPUT -p tcp --dport 113 -j REJECT --reject-with tcp-reset

# ACCEPT_COUNTRY_MAKE関数定義
# 指定された国のIPアドレスからのアクセスを許可するユーザ定義チェイン作成
ACCEPT_COUNTRY_MAKE(){
    for addr in `cat /tmp/cidr.txt|grep ^$1|awk '{print $2}'`
    do
        iptables -A ACCEPT_COUNTRY -s $addr -j ACCEPT
    done
}

# DROP_COUNTRY_MAKE関数定義
# 指定された国のIPアドレスからのアクセスを破棄するユーザ定義チェイン作成
DROP_COUNTRY_MAKE(){
    for addr in `cat /tmp/cidr.txt|grep ^$1|awk '{print $2}'`
    do
        iptables -A DROP_COUNTRY -s $addr -m limit --limit 1/s -j LOG --log-prefix '[IPTABLES DENY_COUNTRY] : '
        iptables -A DROP_COUNTRY -s $addr -j DROP
    done
}

# IPアドレスリスト取得(外部関数 別途作成)
. /root/iptables_functions
IPLISTGET

# 日本からのアクセスを許可するユーザ定義チェインACCEPT_COUNTRY作成
iptables -N ACCEPT_COUNTRY
ACCEPT_COUNTRY_MAKE JP
# 以降,日本からのみアクセスを許可したい場合はACCEPTのかわりにACCEPT_COUNTRYを指定する

# 中国・台湾・ロシア※からのアクセスをログを記録して破棄
# ※全国警察施設への攻撃元上位3カ国(日本・アメリカを除く)
# http://www.cyberpolice.go.jp/detect/observation.htmlより
iptables -N DROP_COUNTRY
DROP_COUNTRY_MAKE CN
DROP_COUNTRY_MAKE TW
DROP_COUNTRY_MAKE RU
iptables -A INPUT -j DROP_COUNTRY

#----------------------------------------------------------#
# 各種サービスを公開する場合の設定(ここから)               #
#----------------------------------------------------------#

# 外部からのTCP22番ポート(SSH)へのアクセスを日本からのみ許可
# ※SSHサーバーを公開する場合のみ
iptables -A INPUT -p tcp --dport 22 -j ACCEPT_COUNTRY

# 外部からのTCP/UDP53番ポート(DNS)へのアクセスを許可
# ※外部向けDNSサーバーを運用する場合のみ
iptables -A INPUT -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp --dport 53 -j ACCEPT

# 外部からのTCP80番ポート(HTTP)へのアクセスを許可
# ※Webサーバーを公開する場合のみ
iptables -A INPUT -p tcp --dport 80 -j ACCEPT

# 外部からのTCP443番ポート(HTTPS)へのアクセスを許可
# ※Webサーバーを公開する場合のみ
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# 外部からのTCP21番ポート(FTP)へのアクセスを日本からのみ許可
# ※FTPサーバーを公開する場合のみ
iptables -A INPUT -p tcp --dport 21 -j ACCEPT_COUNTRY

# 外部からのPASV用ポート(FTP-DATA)へのアクセスを日本からのみ許可
# ※FTPサーバーを公開する場合のみ
# ※PASV用ポート60000:60030は当サイトの設定例
iptables -A INPUT -p tcp --dport 60000:60030 -j ACCEPT_COUNTRY

# 外部からのTCP25番ポート(SMTP)へのアクセスを許可
# ※SMTPサーバーを公開する場合のみ
iptables -A INPUT -p tcp --dport 25 -j ACCEPT

# 外部からのTCP465番ポート(SMTPS)へのアクセスを日本からのみ許可
# ※SMTPSサーバーを公開する場合のみ
iptables -A INPUT -p tcp --dport 465 -j ACCEPT_COUNTRY

# 外部からのTCP110番ポート(POP3)へのアクセスを日本からのみ許可
# ※POP3サーバーを公開する場合のみ
iptables -A INPUT -p tcp --dport 110 -j ACCEPT_COUNTRY

# 外部からのTCP995番ポート(POP3S)へのアクセスを日本からのみ許可
# ※POP3Sサーバーを公開する場合のみ
iptables -A INPUT -p tcp --dport 995 -j ACCEPT_COUNTRY

# 外部からのTCP143番ポート(IMAP)へのアクセスを日本からのみ許可
# ※IMAPサーバーを公開する場合のみ
iptables -A INPUT -p tcp --dport 143 -j ACCEPT_COUNTRY

# 外部からのTCP993番ポート(IMAPS)へのアクセスを日本からのみ許可
# ※IMAPSサーバーを公開する場合のみ
iptables -A INPUT -p tcp --dport 993 -j ACCEPT_COUNTRY

# 外部からのUDP1194番ポート(OpenVPN)へのアクセスを日本からのみ許可
# ※OpenVPNサーバーを公開する場合のみ
iptables -A INPUT -p udp --dport 1194 -j ACCEPT_COUNTRY

# VPNインタフェース用ファイアウォール設定
# ※OpenVPNサーバーを公開する場合のみ
[ -f /etc/openvpn/openvpn-startup ] && /etc/openvpn/openvpn-startup

# 外部からのTCP20000番ポート(Usermin)へのアクセスを日本からのみ許可
# ※Useminを公開する場合のみ
iptables -A INPUT -p tcp --dport 20000 -j ACCEPT_COUNTRY #----------------------------------------------------------# # 各種サービスを公開する場合の設定(ここまで) # #----------------------------------------------------------# # 拒否IPアドレスからのアクセスはログを記録せずに破棄 # ※拒否IPアドレスは/root/deny_ipに1行ごとに記述しておくこと # (/root/deny_ipがなければなにもしない) if [ -s /root/deny_ip ]; then for ip in `cat /root/deny_ip` do iptables -I INPUT -s $ip -j DROP done fi # 上記のルールにマッチしなかったアクセスはログを記録して破棄 iptables -A INPUT -m limit --limit 1/s -j LOG --log-prefix '[IPTABLES INPUT] : ' iptables -A INPUT -j DROP iptables -A FORWARD -m limit --limit 1/s -j LOG --log-prefix '[IPTABLES FORWARD] : ' iptables -A FORWARD -j DROP # サーバー再起動時にも上記設定が有効となるようにルールを保存 /etc/rc.d/init.d/iptables save # ファイアウォール起動 /etc/rc.d/init.d/iptables start [root@server ~]# chmod 700 iptables.sh 
← ファイアウォール設定スクリプトへ実行権限付加

A外部関数iptables_functionsの作成

[root@server ~]# vi iptables_functions
# IPアドレスリスト取得関数定義
IPLISTGET(){
    # http://nami.jp/ipv4bycc/から最新版IPアドレスリストを取得する
    wget -q http://nami.jp/ipv4bycc/cidr.txt.gz
    gunzip cidr.txt.gz
    # 最新版IPアドレスリストが取得できなかった場合
    if [ ! -f cidr.txt ]; then
        if [ -f /tmp/cidr.txt ]; then
            # バックアップがある場合はその旨をroot宛にメール通知して処理を打ち切る
            echo cidr.txt was read from the backup! | mail -s $0 root
            return
        else
            # バックアップがない場合はその旨をroot宛にメール通知して処理を打ち切る
            echo cidr.txt not found!|mail -s $0 root
            exit 1
        fi
    fi
    # 最新版IPアドレスリストを /tmpへバックアップする
    /bin/mv cidr.txt /tmp/cidr.txt
}

[root@server ~]# 

BIPアドレスリスト更新チェック

iptablesで特定国からのアクセス拒否ルールを設定した場合、IPアドレス情報は頻繁に更新されるので、更新がある場合はiptables設定スクリプトを再起動するようにする。

[root@server ~]# vi /etc/cron.daily/iplist_check.sh ← IPアドレスリストチェックスクリプト作成
#!/bin/bash

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# 新旧IPLIST差分チェック件数(0を指定するとチェックしない)
# ※新旧IPLIST差分がSABUN_CHKで指定した件数を越える場合はiptables設定スクリプトを実行しない
# ※新旧IPLIST差分チェック理由はhttp://centossrv.com/bbshtml/webpatio/1592.shtmlを参照
SABUN_CHK=100
[ $# -ne 0 ] && SABUN_CHK=${1}

# チェック国コード
COUNTRY_CODE='JP CN TW RU'

# iptables設定スクリプトパス
IPTABLES=/root/iptables.sh

# iptables設定スクリプト外部関数取り込み
. /root/iptables_functions

# IPアドレスリスト最新化
rm -f IPLIST.new
IPLISTGET
for country in $COUNTRY_CODE
do
    if [ -f /tmp/cidr.txt ]; then
        grep ^$country /tmp/cidr.txt >> IPLIST.new
    else
        grep ^$country /tmp/IPLIST >> IPLIST.new
    fi
done
[ ! -f /tmp/IPLIST ] && cp IPLIST.new /tmp/IPLIST

# IPアドレスリスト更新チェック
diff -q /tmp/IPLIST IPLIST.new > /dev/null 2>&1
if [ $? -ne 0 ]; then
    if [ ${SABUN_CHK} -ne 0 ]; then
        if [ $(diff /tmp/IPLIST IPLIST.new | egrep -c '<|>') -gt ${SABUN_CHK} ]; then
            (
             diff /tmp/IPLIST IPLIST.new
             echo
             echo "$IPTABLES not executed."
            ) | mail -s 'IPLIST UPDATE' root
            rm -f IPLIST.new
            exit
        fi
    fi
    /bin/mv IPLIST.new /tmp/IPLIST
    sh $IPTABLES > /dev/null
else
    rm -f IPLIST.new
fi

[root@server ~]# chmod +x /etc/cron.daily/iplist_check.sh ← 実行権限付与

 

◆cron.dailyからのエラー対処
<<TOP
/root/iptables.sh not executed.という内容のメールが届いた場合

取得した最新のIPアドレスリストと、前回取得したIPアドレスリストとの差分が100件を超えたため、iptables設定スクリプトを
実行しなかったことを示す。下記のように対処。
[root@server ~]# /etc/cron.daily/iplist_check.sh 0 ← 強制的にiptables設定スクリプトを実行

[root@server ~]# 

 

 
◆iptablesの起動
<<TOP

iptablesスクリプトの実行

[root@server ~]# sh iptables.sh ← ファイアウォール設定スクリプト実行
ファイアウォールのルールを /etc/sysconfig/iptables に保存中[  OK  ]
ファイアウォールルールを適用中:                            [  OK  ]
チェインポリシーを ACCEPT に設定中filter                   [  OK  ]
iptables モジュールを取り外し中                            [  OK  ]
iptables ファイアウォールルールを適用中:                   [  OK  ]
iptables モジュールを読み込み中ip_conntrack_ftp            [  OK  ]
[root@server ~]# chkconfig iptables on   ← iptables自動起動設定
[root@server ~]# chkconfig --list iptables ← iptables自動起動設定確認
iptables        0:off   1:off   2:on    3:on    4:on    5:on    6:off ← ランレベル2〜5のonを確認
		  

 

◆iptablesの確認
<<TOP

Shields UP! - Internet Vulnerability Profilingにアクセスし、自サーバのポート開閉を確認

Proceedをクリック

続けるをクリック

All Service Portsをクリック

上記は、当サーバの例です。

 
 
◆広告等 <<TOP
TOPへ

Copyright(C) 2005-2012 arisonserver. All rights reserved.