目 次
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」オプションによって(暗示的に)呼び出されるタイプ
指定方法 | 内容 |
---|---|
–sport | Source Port。送信側(クライアント側)のポート番号を指定。-p tcp か -p udp の後に指定します。 |
–dport | Destination Port。受信側(サーバ側)のポート番号を指定-p tcp か -p udp の後に指定します。 |
–tcp-flags | TCP のときだけ指定することができる。 第1引数に評価されるTCPフラグを指定し、第2引数に設定されていなければならないフラグを指定します。 指定可能なフラグは、SYN、ACK、FIN、RST、URG、PSH、ALL、NONE です。 複数指定する場合はカンマで区切り、引数の間は半角スペースで区切ります。 (–tcp-flags SYN,RST,ACK SYN) |
–syn | TCP のときだけ指定することができる。SYNビットがセットされた、 いわゆるTCPの接続確立時に、正規のスリーハンドシェイク手順を踏んだ通信を指定します。 上記のSYN,RST,ACK SYNの省略形。 |
–icmp-type | ICMP のタイプを指定。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拡張モジュール
指定方法 | 内容 |
---|---|
length | length拡張モジュールを読み込み。パケットのサイズをフラグとしてマッチさせることができる。 |
–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拡張モジュール
指定方法 | 内容 |
---|---|
state | state拡張モジュールを読み込み。 パケットを追跡することでステートフル・パケットインスペクションが可能になります。 |
–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