Linuxコマンド iptables

Linuxに実装されているパケットフィルタです。

標準で搭載されているファイアウォールのことです。

書式

iptables [-t テーブル] コマンド [マッチ] [ターゲット/ジャンプ]

•iptablesではパケットを、4つのテーブルに分けて、それぞれのタイミングで制御します。
•テーブルには「filterテーブル」「natテーブル」「mangleテーブル」「rawテーブル」があります。

filterテーブル

filterテーブルではパケットの通過や遮断といった制御をします。

通常ほとんどの設定はこのテーブルに記述します。

下の例にあるように、設定ファイルを直接編集する際は、行頭に「*(アスタリスク)」を付けて、最後は「COMMIT」で指定。その間に書かれた設定がfilterテーブルのルールとなります。

/etc/sysconfig/iptables

*filter
#ここにfilter関係の記述
COMMIT

 

iptables -t filter -p tcp –dport 80 -j -DROP

コマンドでfilterテーブルにポート80のパケットを破棄するルールを追加する

 

iptables -p tcp –dport 80 -j -DROP

filterテーブルはデフォルトのため省略可能

natテーブル

NAT(ネットワークアドレス変換機能)を担当します。

送信先や送信元といったパケットの中身を書き換える際に利用します。

各通信をローカルネットワーク上のサーバへ振り分けるルーターとして機能させることができます。

/etc/sysconfig/iptables

*nat
#ここにnat関係の記述
COMMIT

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUERADE

IPマスカレードの指定

mangleテーブル

TOS(Type Of Service)フィールド等の値を書き換えます。

TOSはパケット処理の優先度付けを行い、通信品質を制御する際に利用されます。

また特定の通信マークを置き換える事もできます。

/etc/sysconfig/iptables

*mangle
#ここにmangle関係の記述
COMMIT

iptables -t mangle -A PREROUTING -p tcp –dport 80 -j TOS –set-tos Maximize-Throughput

ポート80の通信のTOSを高スループットのものへ書き換え

Rawテーブル

特殊なテーブルとしてRawテーブルというものも存在します。

用途はmangleテーブルのように特定のパケットにマークを付けることですが、Rawテーブルでは追跡を除外するようマークを付けます。

つまり、特定の通信をファイアウォールで処理せずに他の機材へ通したりといった経路制御する場合に利用します。

例えば通信が1秒間に数千といった高負荷の場合、全ての通信を1台のサーバで扱うことが難しくなります。

高負荷の原因がDNSサーバへの問い合わせだったと仮定します。

負荷分散のために「DNSのパケットに関しては、別サーバで処理させたい」そのような際に、ポート53の通信にNOTRACKマークを付けます。

するとiptablesはNOTRACKマークの付いたパケットを、記録したり処理をせずに、別のサーバへ通します。そうすることで、DNSの問い合わせを行うサーバと、それ以外の通信を処理するサーバに分けることができます。

/etc/sysconfig/iptables

*raw
#ここにraw関係の記述
COMMIT

iptables -t raw -I PREROUTING -p udp –dport 53 -j NOTRACK

iptables -t raw -I OUTPUT -p udp –dport 53 -j NOTRACK

ポート53のUDPを通ったパケットの受信時と送信時にNOTRACKマークを付ける

/sbin/iptables -I INPUT -s $bb/16 -p tcp –dport ! 80 -j REJECT

80番以外は侵入させない

チェインについて

チェインの種類

種類説明
INPUT入力(受信)に対するチェイン
OUTPUT出力(送信)に対するチェイン
FORWARDフォワード(転送)に対するチェイン
PREROUTING受信時に宛先アドレスを変換するチェイン。
タイミングとしてはfilterで適用されるルールより手前。
POSTROUTING送信時に送信元アドレスを変換するチェイン。
これもfilterの後でパケットが送信される直前。

テーブルとチェインの対応表

テーブル対応するチェイン
filterテーブルINPUT、OUTPUT、FORWARD
natテーブルPOSTROUTING、PREROUTING、OUTPUT
mangleテーブルPOSTROUTING、PREROUTING、INPUT、OUTPUT、FORWARD
RawテーブルPREROUTING、OUTPUT

コマンドについて

よく使うコマンド

指定方法内容
-A(–append)指定チェインに1つ以上の新しいルールを追加
-D(–delete)指定チェインから1つ以上のルールを削除
-P(–policy)指定チェインのポリシーを指定したターゲットに設定
-N(–new-chain)新しいユーザー定義チェインを作成
-X(–delete-chain)指定ユーザー定義チェインを削除
-I(–insert)指定したチェーンにルール番号を指定してルールを挿入する。
(ルール番号を省略した際にはルール番号は1に設定され、チェーンの先頭に挿入される。)

パラメータについて

よく使うパラメータ

指定方法内容
-s (–source)パケットの送信元を指定。特定のIP(192.168.0.1)や範囲(192.168.0.0/24)を指定する。
-d (–destination)パケットの宛先を指定。指定方法は-sと同じ。
-p (–protocol)チェックされるパケットのプロトコル。 指定できるプロトコルは、 tcp、udp、icmp、allのいずれか1つか、数値。
-i (–in-interface)パケットを受信することになるインターフェース名。eth0、eth1など。
-o (–out-interface)送信先インターフェース名を指定。
-j (–jump)ターゲット(ACCEPT、DROP、REJECT)を指定

「-j」で指定するターゲットについて

ターゲットの一覧

指定方法内容
ACCEPTパケットの通過を許可
DROPパケットを破棄。応答を返さない。
REJECTパケットを拒否し、ICMPメッセージを返信
REDIRECT特定ポートにリダイレクト
LOGマッチしたパケットのログを記録

拡張パラメータについて

「-p」オプションによって(暗示的に)呼び出されるタイプ

指定方法内容
–sportSource Port。送信側(クライアント側)のポート番号を指定。-p tcp か -p udp の後に指定します。
–dportDestination Port。受信側(サーバ側)のポート番号を指定-p tcp か -p udp の後に指定します。
–tcp-flagsTCP のときだけ指定することができる。
第1引数に評価されるTCPフラグを指定し、第2引数に設定されていなければならないフラグを指定します。
指定可能なフラグは、SYN、ACK、FIN、RST、URG、PSH、ALL、NONE です。
複数指定する場合はカンマで区切り、引数の間は半角スペースで区切ります。
(–tcp-flags SYN,RST,ACK SYN)
–synTCP のときだけ指定することができる。SYNビットがセットされた、
いわゆるTCPの接続確立時に、正規のスリーハンドシェイク手順を踏んだ通信を指定します。
上記のSYN,RST,ACK SYNの省略形。
–icmp-typeICMP のタイプを指定。pingに限定した指定をする際などに指定します。

iptables -A INPUT -p tcp –dport 80 -j DROP

ポート80で受信したTCPの受信パケットを破棄

iptables -A INPUT -p –tcp-flags SYN,RST,ACK SYN –dport 80 -j ACCEPT

ポート80で受信したTCPかつ、SYN、RST、ACKのうちSYNフラグだけを持った受信パケットを許可

「-m」オプションを付けることで(明示的に)呼び出されるタイプ

リミット拡張モジュール

指定方法内容
limitリミット拡張モジュールを読み込み。
–limit時間あたりに何パケットまで許可するかを指定する。
second(秒)、minute(分)、hour(時)、day(日)を指定することができます。
–limit の初期値は 3/hour
–limit-burst上記のリミットが有効になる通信の回数を指定。
「○回受信したら1時間に1回に制限」という際の「○回」の部分を指定する。
初期値は5。

iptables -A INPUT -p tcp –dport 80 -m hashlimit –hashlimit-burst 5 –hashlimit 1/m –hashlimit-mode srcip -j ACCEPT

TCPのポート80宛の受信パケットを、ハッシュリミットで5回まで無条件で受け入れ、それ以上のパケットを1分間に1度だけ許可する

length拡張モジュール

指定方法内容
lengthlength拡張モジュールを読み込み。パケットのサイズをフラグとしてマッチさせることができる。
–length「○:○」という書式で「前半の○から、後半の○サイズまで」と指定する。
後半の指定を外せば○以上、前半の指定を外せば○以下という指定も可能。

iptables -A INPUT -p tcp –dport 80 -m length –length 85:65535

85から65535バイトまで一致

iptables -A INPUT -p tcp –dport 80 -m length –length :85

85バイト以下に一致

state拡張モジュール

指定方法内容
statestate拡張モジュールを読み込み。
パケットを追跡することでステートフル・パケットインスペクションが可能になります。
–state追跡しているパケットの状態を指定。新規か、既に許可をしたものか、などを指定する。

state拡張で指定可能なパラメータ

指定方法内容
NEW全くの新参の接続
ESTABLISHED既に許可された接続
RELATED新参ではあるが許可された接続
INVALIDパラメータの不明な無効な接続

iptables -A INPUT -p tcp -m state –state NEW -j DROP

filterテーブルの受信はすべて破棄。送信はすべて許可

ポリシーについて

ポリシーとはチェイン全体に適用されるルールのことです。
ポリシーの設定は「-P」オプションを使って記述します。

ポリシーでは2つのパターンが考えられる
1.全て拒否してから特定の通信だけ許可する場合。許可するポートが少ない場合に向いています。
2.全て許可してから特定の通信だけ拒否する場合。拒否するポートが少ない場合に向いています。

ほとんどの場合、INPUTチェインに関しては安全性を考えて1番の「拒否してから許可」で運用します。

iptables -t filter -P INPUT DROP

iptables -t filter -P OUTPUT ACCEPT

TCPの受信パケットの内、新規の接続に関しては破棄

ポリシーはその後のルールも適応されるため、後に記述するルールで上書きすることができます。

iptables -P INPUT DROP

iptables -A INPUT -m –dport 80 -j ACCEPT

ポリシーでINPUT全体を破棄した後に、ポート80を許可する

設定を確認する

指定方法内容
-L, –list [CHAIN]チェインCHAIN(省略した場合はすべて)のルールを一覧表示する

iptables -L

設定を消す

iptables -F

全ての設定を消す

 

iptables -F INPUT

Fは消去 INPUTはこの項目のみという意味

スクリプト及びルール

iptablesの設定

iptables設定用のスクリプトを作成する。

$ vi iptables.sh

次の内容を記載して保存する。

#!/bin/bash
#—-全般的設定—-#
# ローカルネットワークを定義する

LOCALNET=192.168.100.0/255.255.255.0

# ルールのクリア

iptables -F

# 原則となるルール(条件に適合しなかった場合に適用するルール)

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

#—-攻撃対策—-#
# 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

# 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パケットは拒否

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

# 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

# 全ホスト(ブロードキャストアドレス、マルチキャストアドレス)

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

#—-個別ポート(サービス)の設定—-#
# SSHサーバを公開する場合

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

# 外部向けDNSサーバを公開する場合

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

# Webサーバを公開する場合

iptables -A INPUT -p tcp –dport 80 -j ACCEPT iptables -A INPUT -p tcp –dport 443 -j ACCEPT

# FTPサーバを公開する場合

iptables -A INPUT -p tcp –dport 21 -j ACCEPT

iptables -A INPUT -p tcp –dport 60000:60030 -j ACCEPT  PASV用ポートは各自の環境にしたがって変更して下さい

# メールサーバを公開する場合

iptables -A INPUT -p tcp –dport 25 -j ACCEPT # SMTP

iptables -A INPUT -p tcp –dport 465 -j ACCEPT # SMTPs

iptables -A INPUT -p tcp –dport 110 -j ACCEPT # POP3

iptables -A INPUT -p tcp –dport 995 -j ACCEPT # POP3s

iptables -A INPUT -p tcp –dport 143 -j ACCEPT # IMAP

iptables -A INPUT -p tcp –dport 993 -j ACCEPT # IMAPs

# OpenVPNサーバーを公開する場合

iptables -A INPUT -p udp –dport 1194 -j ACCEPT [ -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

# 上記のルールにマッチしなかったアクセスはログを記録して破棄

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

# 上記で設定したルールを保存

iptables save


1.ポリシーを決める

構文:#iptables -P チェイン ターゲット;チェインのポリシーを変更する。

 まず INPUT については、一旦すべて ACCEPT(許可) します。FORWARD は使わないので DROP(破棄) します。OUTPUT は、すべて ACCEPT(許可) します。

# iptables -P INPUT ACCEPT
# iptables -P FORWARD DROP
# iptables -P OUTPUT ACCEPT

※FORWARD はルータとして動作させるときに設定します。

2.ルールをクリアする

# iptables -F

3.ルールをキー入力する構文:iptables -A チェイン ルール;チェインの最後にルールを追加する。

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

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

※-p:ルールで使われるプロトコル、またはチェックされるパケットのプロトコル。指定できるプロトコルは、 tcp, udp, icmp, all のいずれか 1 つか、数値。

※-i:パケットを受信することになるインターフェース名 (INPUT, FORWARD, PREROUTING チェインに入るパケットのみ)。

※-j:ルールのターゲット、つまり、パケットがマッチした場合にどうするかを指定する。

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

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

※ 拡張–dportは `–protocol tcp’ が指定され場合にロードされ、オプションが提供される。–dport(–destination-port)送信先ポートまたはポート範囲の指定。

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

ローカルの他端末からWebminでの接続を許可(Webminのポート:10000)

# iptables -A INPUT -s 192.168.0.0/24 -p tcp –dport 10000 -j ACCEPT

※送信元の指定。 address はホスト名 (DNS のようなリモートへの問い合わせで解決する名前を指定するのは非常に良くない) ・ネットワーク IP アドレス (/mask を指定する)・通常の IP アドレス、のいずれか。

TCPの接続開始と応答、FTPデータなどを許可

# iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT

※iptables は拡張されたパケットマッチングモジュールを使うことができる。これらのモジュールは 2 種類の方法でロードされる: モジュールは、 -p または –protocol で暗黙のうちに指定されるか、 -m または –match の後にモジュール名を続けて指定される。

※state は、マッチングを行うための、コンマで区切られた接続状態のリストである。指定可能な state は以下の通り。

INVALID: このパケットは既知の接続と関係していない。

ESTABLISHED: このパケットは、過去双方向にパケットがやり取りされた接続に属するパケットである。

NEW: このパケットが新しい接続を開始したか、双方向にはパケットがやり取りされていない接続に属するパケットである。

RELATED: このパケットが新しい接続を開始しているが、 FTP データ転送や ICMP エラーのように、既存の接続に関係している。

他の接続はすべて破棄(ポリシーの再設定)

# iptables -P INPUT DROP

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

# /etc/init.d/iptables save

5.iptables を再起動する。

# service iptables restart

現在のすべてのルールとユーザ定義チェインを初期化中:    [ OK ]

現在のすべてのルールとユーザ定義チェインを破棄:      [ OK ]

iptablesファイアウォールルールを適用中:          [ OK ]

                              [ OK ]

====================================

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

#!/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/script/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 KR
DROP_COUNTRY_MAKE TW
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


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

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

#!/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=10
[ $# -ne 0 ] && SABUN_CHK=${1}

# チェック国コード
COUNTRY_CODE='JP CN 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
[ ! -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 '<|>' | wc -l) -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
    $IPTABLES > /dev/null
else
    rm -f IPLIST.new
fi

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です