田舎のパパが日常で感じた気になる話を発信するブログです。

気になるボックス

VPS

iptables 設定シェルスクリプトの付箋メモ

投稿日:

CentOSで自宅サーバー構築」というサイトはご存知でしょうか?おそらく多くの方が一度はお世話になっていると思います。そのサイトで紹介されている 「iptables 設定シェルスクリプト」を初心者なりに解析した際の付箋メモを残します。

スポンサーリンク

解析スクリプト

ファイアウォール構築(iptables) - CentOSで自宅サーバー構築

iptables 設定シェルスクリプト本体の解析

#!/bin/bash

/bin/bashを使って実行するように明示。


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

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

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

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

eth0 の ifconfig の結果より、サブネットマスク部分を抜き出して取得する。このコマンドの連携は、サブネットマスクやIP抜き出しでよく利用されるようです。

コマンド説明

参考URL



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

ネットワーク値を取得して、先に取得したネットマスクとで内部ネットワークアドレスを取得する(IP/MASK)。さくらVPSの場合は、サブネットマスクが 255.255.254.0 なので一つのサブネットに512台接続可能。

コマンド説明



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

ルールをすべてリセットし、ポリシーをすべて ACCEPT にします。


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

設定が無い受信と転送をすべて拒否します。これ以降で必要に応じて許可していきます。送信はすべて許可します。INPUT と FORWARD に関してはスクリプトの終盤で破棄設定をしている箇所があるので不要と思われる。


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

ローカルループバックからの受信はすべて許可する。平たく言うとコメントの通りで自分自身からのアクセスを許可します。

用語説明



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

同一サブネット上(内部ネットワーク)からのアクセスをすべて許可する。VPSの場合は、これは必要ないと思われる。アクセスし放題…?


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

外部からのアクセスは、パケットの状態を確認して接続済み通信のパケットに限り受信を許可します。

ステータス 説明
NEW 新コネクションを開始するパケット
ESTABLISHED 通常の応答パケットあるいは確立中コネクションの応答
RELATED ICMPエラー、FTPデータコネクションなどのパケット
INVALID 無効なパケット



# 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

SYN Flood攻撃 を SYN Cookiesを有効にすることで回避する。SYN Cookies を有効にするにはカーネル設定の変更が必要です。sysctrl を利用することで再起動なしで即座に設定を反映させます。再起動しても設定を有効にしておきたいので、/etc/sysctl.conf の設定も行います。(sed で旧設定を削除、echo で新設定を出力)

用語説明

参考URL



# ブロードキャストアドレス宛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

ブロードキャスト宛pingには応答しないように設定して踏み台にならないようにする。この設定も「SYN Cookies」と同様の手順でカーネルに対して行う。

用語説明



# 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

ICMP Redirect ではルータの存在やネットワークの存在を知らせてしまうことから拒否に設定することが多いようです。この設定は、各インターフェース(lo、eth0、…)、all、default に対してそれぞれ必要となります。

用語説明

参考URL



# 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

IPスプーフィングに悪用させる危険性もあることから、ソース・ルーティングのついたパケットを拒否に設定することが多いようです。この設定もSmurf攻撃対策と同様に各インターフェースに対してそれぞれ必要となります。カーネルレベルに対しての設定となります。

用語説明

参考URL



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

フラグメント化したパケットの最後の部分だけを送信して受信側に準備をさせリソースを無駄に使用させるなどの攻撃を防ぐため設定することがあるようです。ログの先頭に「[IPTABLES FRAGMENT] :」をつけて出力します。ログに出力してから破棄します。

参考URL



# 外部との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

最後に設定した条件に一致しなかった場合はログを出力する設定がある。NetBIOS のパケットログは無数に飛び交っていてログ取得はキリがないため破棄するために設定する。VPSの場合は、内部ネットワークで設定すると同一サブネット上から自由にアクセス出来てしまうので注意が必要。必要がなければすべて拒否で。

用語説明

参考URL



# 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

大量の Ping コマンドに対する対策です。攻撃を受けた場合には、ログの先頭に「[IPTABLESPINGDEATH] :」をつけて出力します。ログに出力してから破棄します。ここでは、Ping of Death 用のチェインを新規作成して設定しています。他も新規チェインを作成して設定したほうが整理できてよさそうですね。

用語説明

  • 「ping of death」とは:ITpro



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

ブロード、マルチキャスト宛のパケットは大量にあるせいか、ログには出力せずに破棄するようです。

用語説明

  • 「ブロードキャスト」とは:ITpro
  • 「マルチキャスト」とは:ITpro



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

113番ポートは、送信元が名乗ったホスト名が偽ってないかを確認する手順の中で使われているようです。このパケットをDROPするとレスポンスが悪化するため、拒否応答を返すように設定します。

参考URL

  • TCP/UDPポート情報集|OCNセキュリティポータル



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

送信元のIPアドレスが指定された国コード($1)の場合、アクセスを許可するユーザ定義チェインを作成します。国コードの判定には予め用意してあるIPアドレスリスト(cidr.txt)を利用します。チェイン「ACCEPT_COUNTRY 」は、本関数の呼び出し前に作成されています。

コマンド説明



# 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アドレスが指定された国コード($1)の場合、ログの先頭に「[IPTABLES DENY_COUNTRY] :」をつけて出力します。ログに出力してから破棄します。国コードの判定には予め用意してあるIPアドレスリスト(cidr.txt)を利用します。チェイン「ACCEPT_COUNTRY 」は、本関数の呼び出し前に作成されています。


# IPアドレスリスト取得
. /root/iptables_functions
IPLISTGET

外部ファイルにあるIPアドレスリストを作成する関数を呼び出します。この処理により、IPアドレスリスト(cidr.txt)が最新の状態で再作成されます。「IPLISTGET」関数は、最後に解説します。


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

日本からのアクセスを許可するチェイン「ACCEPT_COUNTRY」を作成します。チェインの定義は先程メモした「ACCEPT_COUNTRY_MAKE 」関数で行います。引数には、JP(日本の国コード)を渡します。ここでは作成するだけで、[各種サービスを公開する場合の設定]を定義する部分で使用します。


# 中国・韓国・台湾※からのアクセスをログを記録して破棄
# ※全国警察施設への攻撃元上位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

中国、韓国、台湾からのアクセスを破棄するユーザ定義チェイン「DROP_COUNTRY」を作成します。チェインの定義は先程メモした「DROP_COUNTRY_MAKE 」関数で行います。引数には、CN、KR、TW(中国、韓国、台湾の国コード)を渡します。ユーザ定義チェインが完成たら、すべての受信に対して「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
     ・
     ・(省略)
     ・
#----------------------------------------------------------#
# 各種サービスを公開する場合の設定(ここまで)               #
#----------------------------------------------------------#

公開したポートを定義する。日本からのアクセスのみ許可する場合は「ACCEPT_COUNTRY」、国による制限をしない場合は「ACCEPT」を使用します。


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

普段ログなどを監視していて気になるIPを /root/deny_ip に記述しておけば破棄できます。


# 上記のルールにマッチしなかったアクセスはログを記録して破棄
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

INPUT と FORWARD に関して、ここまでのルールにマッチしなかったアクセスはログ出力してパケットを破棄します。運用してみてログが大量に吐き出されるポート番などがある場合は、ここより先でログを出力せず破棄するルールを記述しておく。


# サーバー再起動時にも上記設定が有効となるようにルールを保存
/etc/rc.d/init.d/iptables save

# ファイアウォール起動
/etc/rc.d/init.d/iptables start

サーバが再起動しても設定が有効になるようにルールを保存して、ファイアウォールを起動します。iptables 設定シェルスクリプト本体はここまでです。

参考URL

外部関数「IPLISTGET」の解析

# 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

世界の国別 IPv4 アドレス割り当てリスト」にて国別IPアドレスリストが公開されています。このサイトからリストを取得します。このサイトが落ちていた場合などに備えて、取得した国別IPアドレスリストはバックアップしておきます。落ちていた場合は、前回取得したリストで代用します。

コマンド説明

-VPS
-,

Copyright© 気になるボックス , 2016 AllRights Reserved Powered by AFFINGER4.