iptablesを利用したファイアウォール構築
iptablesを利用したファイアウォールの構築をします。
<!--more-->
●ファイアウォールの定義作成 |
# vi /root/firewall.sh#!/bin/sh
#外部I/Fのネットワーク情報 EXTIF="eth0" EXTIP=$(ifconfig $EXTIF | grep inet | cut -d ":" -f 2 | cut -d " " -f 1) #EXTIP=xxx.xxx.xxx.xxx #heartbeatで管理する為IPアドレスを明示的に設定 # 内部I/Fのネットワーク情報 INTIF="eth1" INTIP=$(ifconfig $INTIF | grep inet | cut -d ":" -f 2 | cut -d " " -f 1) INTMASK=$(ifconfig $INTIF | grep Mask | cut -d ":" -f 4) INTLAN=$INTIP'/'$INTMASK # 非特権ポート UNPRIVPORTS="1024:65535" # パラメータ LOGLIMIT="2/s" # ログマッチ許可 2回/秒 LOGBURST="5″ # ログマッチ最大値 5回 SYNLIMIT="5/s" # SYN-Flood許可 5回/秒 SYNBURST="10″ # SYN-Flood最大値 10回 PINGLIMIT="5/s" # PING-Flood許可 5回/秒 PINGBURST="10″ # PING-Flood最大値 10回 # 全チェインを空にする iptables -F iptables -t nat -F iptables -t mangle -F # 全ユーザー定義チェインを削除する iptables -X iptables -t nat -X iptables -t mangle -X # 全チェインのカウンタをクリアする iptables -Z iptables -t nat -Z iptables -t mangle -Z # デフォルトポリシーをDROPに設定する iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP # — (ロギング用ユーザーチェインの定義) — # DROPパケット iptables -N LOG-DROP iptables -A LOG-DROP -p all \ -m limit –limit $LOGLIMIT –limit-burst $LOGBURST \ -j LOG –log-prefix "iptables DROP " iptables -A LOG-DROP -f \ -m limit –limit $LOGLIMIT –limit-burst $LOGBURST \ -j LOG –log-prefix "iptables FRAGMENT DROP " iptables -A LOG-DROP -j DROP # REJECTパケット iptables -N LOG-REJECT iptables -A LOG-REJECT -p all \ -m limit –limit $LOGLIMIT –limit-burst $LOGBURST \ -j LOG –log-prefix "iptables REJECT " iptables -A LOG-REJECT -f \ -m limit –limit $LOGLIMIT –limit-burst $LOGBURST \ -j LOG –log-prefix "iptables FRAGMENT REJECT " iptables -A LOG-REJECT -p tcp -j REJECT –reject-with tcp-reset iptables -A LOG-REJECT -p udp -j REJECT –reject-with icmp-port-unreachable iptables -A LOG-REJECT -j REJECT # 不正なフラグを持つパケットを破棄 iptables -N LOG-BADFLAG iptables -A LOG-BADFLAG -m limit –limit $LOGLIMIT –limit-burst $LOGBURST \ -j LOG –log-prefix "iptables BADFLAG DROP " iptables -A LOG-BADFLAG -j DROP # 既存の接続に結び付けられていないパケットを破棄 iptables -N LOG-INVALID iptables -A LOG-INVALID -m limit –limit $LOGLIMIT –limit-burst $LOGBURST \ -j LOG –log-prefix "iptables INVALID DROP " iptables -A LOG-INVALID -j DROP # SYN-Floodパケットを破棄 iptables -N LOG-SYNFLOOD iptables -A LOG-SYNFLOOD -m limit –limit $LOGLIMIT –limit-burst $LOGBURST \ -j LOG –log-prefix "iptables SYNFLOOD DROP " iptables -A LOG-SYNFLOOD -j DROP # PING-Floodパケットを破棄 iptables -N LOG-PINGFLOOD iptables -A LOG-PINGFLOOD -m limit –limit $LOGLIMIT –limit-burst $LOGBURST \ -j LOG –log-prefix "iptables PINGFLOOD DROP " iptables -A LOG-PINGFLOOD -j DROP # 接続拒否国からのパケットを破棄 iptables -N LOG-DENY-COUNTRY iptables -A LOG-DENY-COUNTRY -m limit –limit $LOGLIMIT –limit-burst $LOGBURST \ -j LOG –log-prefix "iptables DENY-COUNTRY DROP " iptables -A LOG-DENY-COUNTRY -j DROP # — (ユーザ定義チェイン) — # SYN-Floodをチェック iptables -N CHK-SYNFLOOD iptables -A CHK-SYNFLOOD -p tcp –syn \ -m limit –limit $SYNLIMIT –limit-burst $SYNBURST -j ACCEPT iptables -A CHK-SYNFLOOD -p tcp –syn -j LOG-SYNFLOOD iptables -A CHK-SYNFLOOD -p tcp ! –syn -j ACCEPT # 不正なフラグを持つパケットをチェック iptables -N CHK-BADFLAG iptables -A CHK-BADFLAG -p tcp –tcp-flags SYN,RST SYN,RST -j LOG-BADFLAG iptables -A CHK-BADFLAG -p tcp –tcp-flags SYN,FIN SYN,FIN -j LOG-BADFLAG iptables -A CHK-BADFLAG -p tcp –tcp-flags ACK,FIN FIN -j LOG-BADFLAG iptables -A CHK-BADFLAG -p tcp –tcp-flags ACK,PSH PSH -j LOG-BADFLAG iptables -A CHK-BADFLAG -p tcp –tcp-flags ACK,URG URG -j LOG-BADFLAG iptables -A CHK-BADFLAG -p tcp –tcp-flags FIN,RST FIN,RST -j LOG-BADFLAG iptables -A CHK-BADFLAG -p tcp –tcp-flags ALL ALL -j LOG-BADFLAG iptables -A CHK-BADFLAG -p tcp –tcp-flags ALL NONE -j LOG-BADFLAG iptables -A CHK-BADFLAG -p tcp –tcp-flags ALL FIN,URG,PSH -j LOG-BADFLAG iptables -A CHK-BADFLAG -p tcp –tcp-flags ALL SYN,FIN,URG,PSH -j LOG-BADFLAG iptables -A CHK-BADFLAG -p tcp –tcp-flags ALL SYN,RST,ACK,FIN,URG -j LOG-BADFLAG iptables -A CHK-BADFLAG -p tcp –tcp-option 64 -j LOG-BADFLAG iptables -A CHK-BADFLAG -p tcp –tcp-option 128 -j LOG-BADFLAG # 既存の接続に結び付けられていないパケットをチェック iptables -N CHK-INVALID iptables -A CHK-INVALID -p tcp –dport 80 -j RETURN # WindowsXP IE 対応 iptables -A CHK-INVALID -p all -m state –state INVALID -j LOG-INVALID # 国別のアクセス制限をチェック iptables -N CHK-COUNTRY # チェイン内容は別のスクリプトで作成します # INPUT ICMPパケットをチェック iptables -N CHK-IN-ICMP # Ping Flood対策 iptables -A CHK-IN-ICMP -p icmp –icmp-type echo-request \ -m limit –limit $PINGLIMIT –limit-burst $PINGBURST -j ACCEPT iptables -A CHK-IN-ICMP -p icmp –icmp-type echo-request -j LOG-PINGFLOOD # ICMP-Redirectsを破棄 iptables -A CHK-IN-ICMP -p icmp –icmp-type redirect -j LOG-DROP # ICMP-Timestampを破棄 iptables -A CHK-IN-ICMP -p icmp –icmp-type timestamp-request -j LOG-DROP iptables -A CHK-IN-ICMP -p icmp –icmp-type timestamp-reply -j LOG-DROP # ICMP-address-maskを破棄 iptables -A CHK-IN-ICMP -p icmp –icmp-type address-mask-request -j LOG-DROP iptables -A CHK-IN-ICMP -p icmp –icmp-type address-mask-reply -j LOG-DROP # チェックOKなら許可 iptables -A CHK-IN-ICMP -p icmp -j ACCEPT # OUTPUT ICMPパケットをチェック iptables -N CHK-OUT-ICMP # ICMP-Redirectsを破棄 iptables -A CHK-OUT-ICMP -p icmp –icmp-type redirect -j LOG-DROP # ICMP-TTL-Expiredを破棄 iptables -A CHK-OUT-ICMP -p icmp –icmp-type ttl-zero-during-transit -j LOG-DROP iptables -A CHK-OUT-ICMP -p icmp –icmp-type ttl-zero-during-reassembly -j LOG-DROP # ICMP-Parameter-Problemを破棄 iptables -A CHK-OUT-ICMP -p icmp –icmp-type parameter-problem -j LOG-DROP # ICMP-Timestampを破棄 iptables -A CHK-OUT-ICMP -p icmp –icmp-type timestamp-request -j LOG-DROP iptables -A CHK-OUT-ICMP -p icmp –icmp-type timestamp-reply -j LOG-DROP # ICMP-address-maskを破棄 iptables -A CHK-OUT-ICMP -p icmp –icmp-type address-mask-request -j LOG-DROP iptables -A CHK-OUT-ICMP -p icmp –icmp-type address-mask-reply -j LOG-DROP # チェックOKなら許可 iptables -A CHK-OUT-ICMP -p icmp -j ACCEPT # SMBパケットをチェック iptables -N CHK-SMB iptables -A CHK-SMB -p tcp –dport 137:139 -j DROP iptables -A CHK-SMB -p tcp –dport 445 -j DROP iptables -A CHK-SMB -p udp –dport 137:139 -j DROP iptables -A CHK-SMB -p udp –dport 445 -j DROP iptables -A CHK-SMB -p tcp –sport 137:139 -j DROP iptables -A CHK-SMB -p tcp –sport 445 -j DROP iptables -A CHK-SMB -p udp –sport 137:139 -j DROP iptables -A CHK-SMB -p udp –sport 445 -j DROP # — (INPUTチェイン) — # ローカルからのパケットを許可 iptables -A INPUT -i lo -j ACCEPT # 内部LANからのパケットを許可 iptables -A INPUT -i $INTIF -s $INTLAN -j ACCEPT # 内部I/FのDHCP Broadcastを許可 iptables -A INPUT -i $INTIF -p udp –sport 68 –dport 67 -j ACCEPT # 内部LANを騙る偽パケットを破棄 iptables -A INPUT -s $INTLAN -j LOG-DROP # IDENTパケットを拒否 iptables -A INPUT -i $EXTIF -p tcp –dport 113 -j REJECT –reject-with tcp-reset # ローカルアドレス宛のパケットを拒否 iptables -A INPUT -d 127.0.0.0/8 -j LOG-REJECT # 不正なフラグを持つパケットをチェック iptables -A INPUT -p tcp -j CHK-BADFLAG # 既存の接続に結び付けられていないパケットをチェック iptables -A INPUT -i $EXTIF -j CHK-INVALID # INPUT ICMPパケットをチェック iptables -A INPUT -i $EXTIF -p icmp -j CHK-IN-ICMP # 外部I/FのSMBパケットをチェック iptables -A INPUT -i $EXTIF -j CHK-SMB # 各サービスのルールをここに入れます # SSH接続を許可 iptables -A INPUT -i $EXTIF -p tcp –dport 22 -j CHK-SYNFLOOD # FTP接続を許可 iptables -A INPUT -i $EXTIF -p tcp –dport 21 -j CHK-SYNFLOOD # HTTP/HTTPS接続を許可 iptables -A INPUT -i $EXTIF -p tcp –dport 80 -j CHK-SYNFLOOD iptables -A INPUT -i $EXTIF -p tcp –dport 443 -j CHK-SYNFLOOD # SMTP/SMTPS接続を許可 iptables -A INPUT -i $EXTIF -p tcp –dport 25 -j CHK-SYNFLOOD iptables -A INPUT -i $EXTIF -p tcp –dport 465 -j CHK-SYNFLOOD iptables -A INPUT -i $EXTIF -p tcp –dport 587 -j CHK-SYNFLOOD # POP3/POP3S接続を許可 iptables -A INPUT -i $EXTIF -p tcp –dport 110 -j CHK-SYNFLOOD iptables -A INPUT -i $EXTIF -p tcp –dport 995 -j CHK-SYNFLOOD # IMAP/IMAPS接続を許可 iptables -A INPUT -i $EXTIF -p tcp –dport 143 -j CHK-SYNFLOOD iptables -A INPUT -i $EXTIF -p tcp –dport 993 -j CHK-SYNFLOOD # ESTABLISHED/RELATED接続を許可 iptables -A INPUT -i $EXTIF -m state –state ESTABLISHED -j ACCEPT iptables -A INPUT -i $EXTIF -p tcp –dport $UNPRIVPORTS \ -m state –state RELATED -j CHK-SYNFLOOD iptables -A INPUT -i $EXTIF -p udp –dport $UNPRIVPORTS -m state –state RELATED -j ACCEPT # 上記の何れにもマッチしなかったINPUTパケットを廃棄 iptables -A INPUT -j LOG-DROP # — (OUTPUTチェイン) — # ローカルのパケットを許可する iptables -A OUTPUT -o lo -j ACCEPT # 内部LANへのパケットを許可 iptables -A OUTPUT -o $INTIF -d $INTLAN -j ACCEPT # UDPによるtracerouteコマンドを許可 iptables -A OUTPUT -o $EXTIF -p udp –dport 33434:33523 -m state –state NEW -j ACCEPT # OUPUT ICMPパケットをチェック iptables -A OUTPUT -o $EXTIF -p icmp -j CHK-OUT-ICMP # 外部I/FのSMBパケットをチェック iptables -A OUTPUT -o $EXTIF -j CHK-SMB # 非特権ポートからのTCP/UDPパケットを許可 iptables -A OUTPUT -o $EXTIF -s $EXTIP -p tcp –sport $UNPRIVPORTS -j ACCEPT iptables -A OUTPUT -o $EXTIF -s $EXTIP -p udp –sport $UNPRIVPORTS -j ACCEPT # NTP接続を許可 iptables -A OUTPUT -o $EXTIF -s $EXTIP -p udp –sport 123 -j ACCEPT # SSH接続を許可 iptables -A OUTPUT -o $EXTIF -p tcp –sport 22 -m state –state ESTABLISHED -j ACCEPT # FTP接続を許可 iptables -A OUTPUT -o $EXTIF -p tcp –sport 21 -m state –state ESTABLISHED,RELATED -j ACC EPT # HTTP/HTTPS接続を許可 iptables -A OUTPUT -o $EXTIF -p tcp –sport 80 -j ACCEPT iptables -A OUTPUT -o $EXTIF -p tcp –sport 443 -m state –state ESTABLISHED -j ACCEPT # SMTP/SMTPS接続を許可 iptables -A OUTPUT -o $EXTIF -p tcp –sport 25 -j ACCEPT iptables -A OUTPUT -o $EXTIF -p tcp –sport 465 -m state –state ESTABLISHED -j ACCEPT iptables -A OUTPUT -o $EXTIF -p tcp –sport 587 -m state –state ESTABLISHED -j ACCEPT # POP3/POP3S接続を許可 iptables -A OUTPUT -o $EXTIF -p tcp –sport 110 -m state –state ESTABLISHED -j ACCEPT iptables -A OUTPUT -o $EXTIF -p tcp –sport 995 -m state –state ESTABLISHED -j ACCEPT # IMAP/IMAPS接続を許可 iptables -A OUTPUT -o $EXTIF -p tcp –sport 143 -m state –state ESTABLISHED -j ACCEPT iptables -A OUTPUT -o $EXTIF -p tcp –sport 993 -m state –state ESTABLISHED -j ACCEPT # 上記の何れにもマッチしなかったOUTPUTパケットを廃棄 iptables -A OUTPUT -j LOG-DROP # — (FORWARDチェイン) — # 既存の接続に結び付けられていないパケットを破棄 iptables -A FORWARD -i $EXTIF -m state –state INVALID -j LOG-INVALID # 不正なフラグを持つパケットをチェック iptables -A FORWARD -p tcp -j CHK-BADFLAG # 外部I/FのSMBパケットをチェック iptables -A FORWARD -o $EXTIF -j CHK-SMB # 各サービスのルールをここに入れます # 内部LANの非特権ポートから外部への転送を許可 iptables -A FORWARD -i $INTIF -o $EXTIF -s $INTLAN -p tcp –sport $UNPRIVPORTS -j ACCEPT iptables -A FORWARD -i $INTIF -o $EXTIF -s $INTLAN -p udp –sport $UNPRIVPORTS -j ACCEPT iptables -A FORWARD -i $INTIF -o $EXTIF -s $INTLAN -p icmp -j ACCEPT # 外部から内部LANの非特権ポートへの転送を許可 iptables -A FORWARD -i $EXTIF -m state –state ESTABLISHED -j ACCEPT iptables -A FORWARD -i $EXTIF -p tcp –dport $UNPRIVPORTS -m state –state RELATED -j CHK-SYNFLOOD iptables -A FORWARD -i $EXTIF -p udp –dport $UNPRIVPORTS -m state –state RELATED -j ACCEPT iptables -A FORWARD -i $EXTIF -p icmp -m state –state RELATED -j ACCEPT # 上記の何れにもマッチしなかったFORWARDパケットを廃棄 iptables -A FORWARD -j LOG-DROP # — (POSTROUTING) — iptables -A POSTROUTING -t nat -o $EXTIF -j MASQUERADE # — (ルールを保存する) — service iptables save # chmod 700 firewall.sh # ./firewall.sh ファイアウォールのルールを /etc/sysconfig/iptables に保存中[ OK ] |
●ファイアウォールの設定 |
# mkdir /usr/local/sbin/firewall# cd /usr/local/sbin/firewall
# vi white_ip_a.sh #!/bin/sh for IP_ADDR in $(dig a $1 | grep "^$1″ | sed "s/[[:blank:]]\+/ /g" | cut -d " " -f 5); do iptables -A CHK-COUNTRY -s $IP_ADDR -j RETURN done # chmod 700 white_ip_a.sh # vi white_ip_spf.sh #!/bin/sh # DNS の MX レコードからファイアウォールの White IP 設定を行う関数 function mx_record { for MX_NAME in $(dig mx $1 | grep "^$1″ | sed "s/[[:blank:]]\+/ /g" | cut -d " " -f 6); do ./white_ip_a.sh $MX_NAME done } for SPF_TEXT in $(dig txt $1 | grep v=spf1 | sed "s/^.*\"\(.*\)\".*$/\1/"); do KEYWORD=$(echo $SPF_TEXT | cut -d ":" -f 1 -s) case $KEYWORD in include) INCLUDE_SPF=$(echo $SPF_TEXT | cut -d ":" -f 2) ./white_ip_spf.sh $INCLUDE_SPF ;; ip4) IP_ADDR=$(echo $SPF_TEXT | cut -d ":" -f 2) iptables -A CHK-COUNTRY -s $IP_ADDR -j RETURN ;; a) INCLUDE_A=$(echo $SPF_TEXT | cut -d ":" -f 2) ./white_ip_a.sh $INCLUDE_A ;; mx) INCLUDE_MX=$(echo $SPF_TEXT | cut -d ":" -f 2) mx_record $INCLUDE_MX ;; esac done # chmod 700 white_ip_spf.sh # vi country_check.sh #!/bin/sh cd /usr/local/sbin/firewall # 国別IPアドレスリストを取得する wget -q http://nami.jp/ipv4bycc/cidr.txt.gz if [ ! -f cidr.txt.gz ]; then echo "Could not get the cidr.txt.gz from http://nami.jp/" \ | mail -s "iptables CHK-COUNTRY Chain Rule Setup Script" root exit 1 fi gzip -df cidr.txt.gz # CHK-COUNTRYルールを初期化する iptables -F CHK-COUNTRY # WHITE_IPをルールに追加する(以下、空白行までは適宜、追加・削除してください) ./white_ip_spf.sh microsoft.com # Microsoft ./white_ip_spf.sh google.com # Google ./white_ip_spf.sh amazon.com # Amazon ./white_ip_spf.sh dmx1.bfi0.com # Dell ./white_ip_spf.sh notify-customer.com # DigiRock ./white_ip_spf.sh worldcommunitygrid.org # BOINC(WCG) ./white_ip_a.sh www.boincstats.com # BOINC(stats/BAM!) ./white_ip_a.sh verifier.port25.com # SPF/Sender ID/DomainKeys Check if [ -s white_ip_list ]; then for IP_ADDR in $(cat white_ip_list | sed -e "/^#/d" -e "s/^\([^[:blank:]]*\).*/\1/"); do iptables -A CHK-COUNTRY -s $IP_ADDR -j RETURN done fi # 国別アクセスルールをiptablesのルールに追加する if [ -s rule_list ]; then for RULE in $(cat rule_list | sed -e "/^#/d" -e "s/^\([^[:blank:]]*\).*/\1/"); do CONTRY=$(echo $RULE | cut -d "|" -f 1) TARGET=$(echo $RULE | cut -d "|" -f 2) if [ "$TARGET" = "RETURN" ]; then TARGET="-j $TARGET" else TARGET="-p tcp -m state –state NEW -j $TARGET" fi if [ "$CONTRY" != "**" ]; then for IP in $(cat cidr.txt | grep "^$CONTRY" | sed "s/$CONTRY[^0-9]*\(.*\)/\1/"); do iptables -A CHK-COUNTRY -s $IP $TARGET done else iptables -A CHK-COUNTRY $TARGET fi done fi # ルールを保存する service iptables save # chmod 700 country_check.sh # vi rule_list CN|DROP KR|DROP TW|DROP # vi /etc/crontab : # firewall 02 5 * * 0 root /usr/local/sbin/firewall/country_check.sh > /dev/null 2>&1 |