iptablesの設定

概要:ファイアウォール(iptables)を構築する。Linuxのパケットフィルタリング機能であるiptablesを使用して、Web等外部に公開するサービス以外のポートへのアクセスをブロックするようにする。

1. iptables設定スクリプト作成

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

##################
### INITIALIZE ###
##################
# インタフェース名定義
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

#####################
### IPTABLES STOP ###
#####################
# すべてのルールをクリア
/etc/rc.d/init.d/iptables stop

####################
### Default Rule ###
####################
# 未設定のポートに適用されるデフォルトルールの設定
iptables -P INPUT   DROP   # 受信はすべて破棄
iptables -P OUTPUT  ACCEPT # 送信はすべて許可
iptables -P FORWARD DROP   # 通過はすべて破棄

####################
### LOCAL ACCEPT ###
####################
# 自ホストからのアクセスをすべて許可
iptables -A INPUT -i lo -j ACCEPT
# 内部からのアクセスをすべて許可
iptables -A INPUT -s $LOCALNET -j ACCEPT
# 内部から行ったアクセスに対する外部からの返答アクセスを許可
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
 
#######################
### TCP SYN Cookies ###
#######################
# TCP SYN Flood攻撃対策としてSYN Cookiesを有効にする
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

#############################
### BROADCAST PING IGNORE ###
#############################
# Smurf攻撃対策としてブロードキャストアドレス宛pingには応答しない
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 ###
#####################
# 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 ###
##################### 
# 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

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

####################
### NetBIOS 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

##########################
### PING OF DEATH DROP ###
##########################
# PING OF DEATH 攻撃対策として1秒間に4回を超えるpingはログを記録して破棄
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

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

################
### 113IDENT ###
################
# メールサーバ等のレスポンス低下防止のため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を指定する

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

##################################################
### 各種サービスを公開する場合の設定(ここから) ###
##################################################
# ACCEPT_COUNTRY : 日本からのみ許可

##############
### SSH 22 ###
##############
# ※SSHサーバーを公開する場合のみ
iptables -A INPUT -p tcp --dport 22 -j ACCEPT_COUNTRY

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

#################
### HTTPS 443 ###
#################
# ※Webサーバーを公開する場合のみ
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

##############
### FTP 21 ###
##############
# FTPサーバーを公開する場合のみ
iptables -A INPUT -p tcp --dport 21 -j ACCEPT_COUNTRY

############################
### FTP PASV 60000:60030 ###
############################
# FTPサーバーを公開する場合のみ
# PASV用ポート60000:60030は設定例
iptables -A INPUT -p tcp --dport 60000:60030 -j ACCEPT_COUNTRY

###############
### SMTP 25 ###
###############
# SMTPサーバーを公開する場合のみ
iptables -A INPUT -p tcp --dport 25 -j ACCEPT

#################
### SMTPS 465 ###
#################
# SMTPSサーバーを公開する場合のみ
iptables -A INPUT -p tcp --dport 465 -j ACCEPT_COUNTRY

################
### POP3 110 ###
################
# POP3サーバーを公開する場合のみ
iptables -A INPUT -p tcp --dport 110 -j ACCEPT_COUNTRY

#################
### POP3S 995 ###
#################
# POP3Sサーバーを公開する場合のみ
iptables -A INPUT -p tcp --dport 995 -j ACCEPT_COUNTRY

################
### IMAP 143 ###
################
# IMAPサーバーを公開する場合のみ
iptables -A INPUT -p tcp --dport 143 -j ACCEPT_COUNTRY

#################
### IMAPS 993 ###
#################
# IMAPSサーバーを公開する場合のみ
iptables -A INPUT -p tcp --dport 993 -j ACCEPT_COUNTRY

####################
### OpenVPN 1194 ###
####################
# OpenVPNサーバーを公開する場合のみ
iptables -A INPUT -p udp --dport 1194 -j ACCEPT_COUNTRY

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

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

# 拒否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

###############
### logging ###
###############
# 上記のルールにマッチしなかったアクセスはログを記録して破棄
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/sysconfig/iptablesに保存される
# ファイアウォール起動
/etc/rc.d/init.d/iptables start
# chmod 700 iptables.sh ← ファイアウォール設定スクリプトへ実行権限付加

2. スクリプト外部関数作成

# vi iptables_functions ← ファイアウォール設定スクリプト外部関数作成
# IPアドレスリスト取得関数定義
IPLISTGET(){
    # http://nami.jp/ipv4bycc/から最新版IPアドレスリストを取得する
    wget -q http://nami.jp/ipv4bycc/cidr.txt
    # 最新版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
            exit 1
        else
            # バックアップがない場合はその旨をroot宛にメール通知して処理を打ち切る
            echo cidr.txt not found!|mail -s $0 root
            exit 1
        fi
    fi
    # 最新版IPアドレスリストを /tmpへバックアップする
    /bin/mv cidr.txt /tmp/cidr.txt
}

3. IPアドレスリスト自動更新チェック設定(CRONによる起動)
IPアドレスリストは頻繁に更新されるので、毎日自動でIPアドレスリストの更新有無をチェックし、更新がある場合はファイアウォール設定スクリプトを再起動するようにする。~

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

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

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

# 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

# IPアドレスリスト更新チェック
diff -q /tmp/IPLIST IPLIST.new > /dev/null 2>&1
if [ $? -ne 0 ]; then
    /bin/mv IPLIST.new /tmp/IPLIST
    $IPTABLES > /dev/null
else
    rm -f IPLIST.new
fi
# chmod +x /etc/cron.daily/iplist_check.sh
 ← IPアドレスリストチェックスクリプトに実行権限付加

4. iptablesの適用と自動起動設定

# ./iptables.sh ← ファイアウォール設定スクリプト実行
ファイアウォールルールを適用中:                            [  OK  ]
チェインポリシーを ACCEPT に設定中filter                   [  OK  ]
iptables モジュールを取り外し中                            [  OK  ]
ファイアウォールのルールを /etc/sysconfig/iptables に保存中[  OK  ]
ファイアウォールルールを適用中:                            [  OK  ]
チェインポリシーを ACCEPT に設定中filter                   [  OK  ]
iptables モジュールを取り外し中                            [  OK  ]
iptables ファイアウォールルールを適用中:                   [  OK  ]
iptables モジュールを読み込み中ip_conntrack_netbios_ns     [  OK  ]
注:マシンスペックにより「iptables ファイアウォールルールを適用」に時間がかかる。

# chkconfig iptables on ← iptables自動起動設定
# chkconfig --list iptables ← iptables自動起動設定確認
iptables        0:off   1:off   2:on    3:on    4:on    5:on    6:off
 ← ランレベル2~5のonを確認

最終更新のRSS
Last-modified: 2014-03-11 (火) 01:59:57 (3693d)