Ubuntu Linux

Linux/Ubuntuでファイアウォールを実現するための iptables の設定に関する覚え書きです。

 

 

iptables とは

iptables は Linux に実装されているパケットフィルタリング機能でこの iptables によって不要なパケットを拒否することでファイアウォールを実現します。

環境

Desktop (Ubuntu 16.04)

Raspberry Pi (Raspbian)

初期設定

iptables の Lオプションで iptables に設定されている規則の一覧が確認できます。

初期設定では何も設定されていません。

# ルールの確認
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination    

設定

1つずつコマンドとして実行して設定していくこともできますが、見やすさを優先してシェルスクリプトにまとめて記述します。

基本方針として受信するパケットを全て拒否し、後ろに個別で受信するパケットの規則を設定します。

ここではWebサーバ用のHTTP(80)とリモートログイン用のSSH、リモートデスクトップのvncを通すようにしています。

vncに関しては許可するIPアドレスを制限しています。

その他の通信を許可したい場合はHTTPなどと同じような書式でポートを指定して設定することができます。

$ vim ~/Documents/iptables.sh
#! /bin/sh

# 設定をクリア
iptables -F

# 基本方針[1]
# サーバーが受信するパケットを拒否
iptables -P INPUT DROP
# サーバーが経由させるパケットを拒否
iptables -P FORWARD DROP
# サーバーが送信するパケットを許可
iptables -P OUTPUT ACCEPT

# サーバ攻撃対策関連
# データを持たないパケットの接続を破棄
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
# SYNflood攻撃と追われる接続を破棄
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
# ステルススキャンと思われる接続を破棄
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP

# 許可するパケットを個別に追加
# SSHを許可 (OpenSSHでポート変更済み 22 => xxxx)[2]
iptables -A INPUT -p tcp -m tcp --dport xxxx -j ACCEPT
# HTTPを許可
iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
# HTTPS(SSL)を許可
iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
# PINGを許可
iptables -A INPUT -p icmp -j ACCEPT
# vnc (ポート変更済み=yyyy)
iptables -A INPUT -p tcp -m tcp --dport yyyy -s 192.168.3.3 -j ACCEPT

# その他
# ローカルループバックの接続を許可
iptables -A INPUT -i lo -j ACCEPT
# 確率済みの通信を許可
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# ログを出力
iptables -A INPUT -j LOG --log-prefix "drop_packet:"

このスクリプトファイルを実行すればファイアウォールの設定が反映されます。

iptables -L で確認するとスクリプトファイルで記述した設定が確認できます。

# スクリプトの実行
$ sudo sh ~/Documents/iptables.sh

# ルールの確認 (xxx=ssh, yyy=vnc)
$ sudo iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination         
DROP       tcp  --  anywhere             anywhere             tcp flags:FIN,SYN,RST,PSH,ACK,URG/NONE
DROP       tcp  --  anywhere             anywhere             tcp flags:!FIN,SYN,RST,ACK/SYN state NEW
DROP       tcp  --  anywhere             anywhere             tcp flags:FIN,SYN,RST,PSH,ACK,URG/FIN,SYN,RST,PSH,ACK,URG
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:xxx
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:https
ACCEPT     icmp --  anywhere             anywhere            
ACCEPT     tcp  --  192.168.3.3          anywhere             tcp dpt:yyy
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
LOG        all  --  anywhere             anywhere             LOG level warning prefix "drop_packet:"
 

Chain FORWARD (policy DROP)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

設定の自動読み込み

直打ちしたやスクリプトで指定した iptables の設定が有効なのはシャットダウンするまでの間でマシンを再起動すると設定は全て消えてしまいます。

毎回起動後にスクリプトファイルを手動で実行するのは大変なので、マシン起動時に自動で iptables の設定を読み込むように準備します。

設定のエクスポート

上で作成したスクリプトファイルを実行しルールの設定を行って、 iptables-save で現在の設定を書き出します。

sudo でリダイレクトをすると Permission denied のエラーメッセージが表示されるので sudo sh -c を使ってリダイレクトしています。

# フィルタリングルールの設定
$ sudo sh ~./iptables.sh

# 現在のルールの書き出し
$ sudo sh -c "iptables-save -c > /etc/iptables.rules"

起動時に設定を読み込むスクリプト

書きだした設定ファイル /etc/iptables.rules を読み込むシェルスクリプトを作成します。

このスクリプトファイルを /etc/network/if-pre-up.d/ 下に保存しておくとマシン起動時に自動でスクリプトを処理して iptables の設定を反映してくれます。

# マシン起動時に iptables の設定を読み込むスクリプトを作成
$ sudo vim /etc/network/if-pre-up.d/iptables_start
#!/bin/sh
/sbin/iptables-restore < /etc/iptables.rules
exit 0

# 実行権限付与
$ sudo chmod +x /etc/iptables.rules

確認

設定が完了したらマシンを再起動して iptables のルールが適用されているか確認します。

# 再起動
$ sudo reboot

# iptables の確認
$ sudo iptables -L

iptables -L の出力を確認して、実際に設定したとおりに通信が許可・拒否されているか確認します。

終わりに

iptables-save と iptables-restore を使って設定を読み込むようにしましたが、はじめに設定用のスクリプトファイルを自前で作成しているのでそのファイルを /etc/network/if-pre-up.d/ に配置するのでもいいと思います。

参考

iptablesの設定方法 – さくらのサポート情報

知らなきゃ損するiptablesのTips:iptablesテンプレート集 改訂版(8) – @IT

【Linux/Ubuntu】iptablesの設定とファイアウォール
Tagged on:     

コメントを残す