AC-5

某SEの雑記帳

ファイアウォール設定(iptables)

      2015/10/02

不要なポートが開いている状態だとセキュリティリスクが高い為、Web等外部に公開するサービス以外のポートへのアクセスをブロックするように、インストール後の早い段階で不要なポートは閉じておく。
ここでは、Linuxのパケットフィルタリング機能であるiptablesを利用する。

※クラウドサーバー等でファイアウォールの設定がされている場合で、iptablesの設定を変更した場合は、クラウドのコンソール側でも必要に応じてポートの開閉を行う必要がある。

iptablesの設定

設定方法には色々とあるが、一般的な設定方法はルールを一つずつ設定していく方法になります。
ただ、その方法だと「設定」→「確認」の手間がかかり、どこまで設定したか等見失う事がある為、
ここではシェルスクリプトを利用した設定手順を行います。

シェルスクリプトを利用して設定を行うようにすると、
・何の設定をしているのかをコメントで残せるので明示的になり更新等が楽になる。
・ファイルを保存しておけば、別のサーバーでも同様の設定を行う場合に楽に設定が行える。
ここでは、ユーザディレクトリの中にシェルスクリプト格納用のshというディレクトリを作成し、そこにシェルスクリプトを格納します。

[testuser@test /]$ yum list installed | grep 'iptables'←iptablesがインストールされているかチェック
iptables.x86_64      1.4.7-14.el6←こんな感じで表示されていればインストールされている(インストールされていなければ何も表示されない)
インストールされていない場合はrootになってインストールを行う
[root@test]# yum -y install iptables←iptablesインストール
[testuser@test ~]$ mkdir sh←ホームディレクトリに「sh」ディレクトリ作成
[testuser@test ~]$ cd sh←shディレクトリに移動
[testuser@test sh]$ vi iptables.sh←iptablesシェルスクリプトファイル作成
#!/bin/bash

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

# 内部ネットワークアドレス定義
LOCALNET=自サーバのIPアドレス/32

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

# ファイアウォール停止(すべてのルールをクリア)
if [ -f /usr/libexec/iptables/iptables.init ]; then
    /usr/libexec/iptables/iptables.init stop
else
    /etc/rc.d/init.d/iptables stop
fi

# デフォルトルール(以降のルールにマッチしなかった場合に適用するルール)設定
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
# 113番ポート(IDENT)へのアクセスには拒否応答
# ※メールサーバ等のレスポンス低下防止
iptables -A INPUT -p tcp --dport 113 -j REJECT --reject-with tcp-reset



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

# 外部からのTCP22番ポート(SSH)へのアクセスを許可
# ※SSHサーバーを公開する場合のみ
iptables -A INPUT -p tcp --dport 22 -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


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

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

# サーバー再起動時にも上記設定が有効となるようにルールを保存
if [ -f /usr/libexec/iptables/iptables.init ]; then
    /usr/libexec/iptables/iptables.init save
else
    /etc/rc.d/init.d/iptables save
fi

# ファイアウォール起動
if [ -f /usr/bin/systemctl ]; then
    systemctl start iptables
else
    /etc/rc.d/init.d/iptables start
fi

iptables起動

ROOTになって実行します。

[root@test]# sh /home/testuser/sh/iptables.sh←ファイアウォール設定スクリプト実行
[root@test]# chkconfig iptables on←iptables自動起動設定

 - Linux