ファイアウォールiptablesを簡単解説~初心者でもよくわかる!VPSによるWebサーバー運用講座(4)

VPSによるWebサーバー運用講座の連載4回目です。
今回は、iptablesを使ってサーバーのファイアウォールの設定を行います。
サーバーOSはCentOS 6.7です。(CentOS 7系ではファイアウォールの仕組みが違うのでこの設定は使えませんので注意してください。)

まず、ファイアウォールの基本を学ぼう

VPSをセットアップしてWebサーバーを公開したら、Webコンテンツを全世界に発信できるようになりますが、同時に悪意ある第三者の攻撃にさらされる宿命を負います。
ファイアウォールは和訳すると「防火壁」です。サーバーが提供するサービス以外の不要な侵入口を塞ぐことで、最低限のセキュリティを確保します。
Webサーバーを公開するならばぜひともファイアウォールは設定しておきたいところです。

ファイアウォールを設定するにあたって、基本的な考え方は、
使っているサービスの口はオープンにして、使ってないサービスの口は閉じる」ということです。
あなたが管理しているサーバーでは、どんなサービスを使っているでしょうか? 使っているサービスの通信は許可して、使っていないサービスの通信は遮断するのがファイアウォールです。

HTTPサーバーなどのサービスはそれぞれ固有の「ポート番号」を使用しています。
また、使用する通信プロトコルとしてTCPUDPがあり、それぞれにポート番号の概念があります。「TCPのポート番号80」と「UDPのポート番号80」は別物ですので注意してください。
代表的なサービスのプロトコルとポート番号は以下のようになっています。

サービス名 プロトコルとポート番号
httpサーバー(HTTP) TCP 80
httpサーバー(SSL) TCP 443
メールサーバー(POP3) TCP 110
メールサーバー(IMAP) TCP 143
メールサーバー(SMTP) TCP 25
メールサーバー(submission port) TCP 587
FTP TCP 20, 21
SSH、SFTP TCP 22

Webサーバーだけの機能を持つサーバーの場合、以下のようにSSH(SFTP)、HTTP、HTTPSのポートを許可して、他の通信は拒否する設定にします。

よく使われるサービスのポート番号は、ウェルノウンポート番号(WELL KNOWN PORT NUMBERS)といって 0〜1023までのポート番号のどこかに割り当てられています。
詳しくは、以下のページをご覧ください。
TCPやUDPにおけるポート番号の一覧 - Wikipedia

あなたのサーバーについて、どのポートを許可すべきかをあらかじめ調べておきましょう。

ファイアウォールiptablesの設定を行う

それでは実際にiptablesの設定を行います。
はじめに、iptablesがインストールされていることを確認しましょう。

# which iptables
/sbin/iptables

whichコマンドで、iptablesがインストールされているパス /sbin/iptables が返ってくる場合は、すでにiptablesはインストールされています。

逆に、以下のようなメッセージが表示された場合はiptablesがインストールされていません。

/usr/bin/which: no iptables in (/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin)

この場合は、yumコマンドでインストールしてください。

# yum install iptables

iptablesの基本的な考え方

iptablesには、INPUTOUTPUTFORWORDという3つのポリシーがあります。それぞれの通信の基本ポリシーを”DROP”(拒否)、”ACCEPT”(許可)のどちらかに設定できます。
INPUTは、サーバーに入ってくる通信のポリシーです。ここでは基本ポリシーを”DROP”にして、あとで個別のポートに対して許可する設定にします。
OUTPUTは、サーバーから出て行く通信のポリシーです。基本ポリシーは"ACCEPT"にします。
FORWARDは、受信したデータを他のサーバーへ転送する際に適用される設定です。ここでは、特に転送するサーバーは無いので”DROP”にします。

実際の設定事例と解説

ポリシーを決めたあとに、個別のポートを許可する設定を行います。
事例を見てもらった方が早いと思いますので、実際のiptablesの設定ファイル内容を以下に紹介します。(2行以上に渡っている行は、実際には1行です)

# (1) ポリシーの設定 OUTPUTのみACCEPTにする
*filter
:INPUT   DROP   [0:0]
:FORWARD DROP   [0:0]
:OUTPUT  ACCEPT [0:0]

# (2) ループバック(自分自身からの通信)を許可する
-A INPUT -i lo -j ACCEPT

# (3) データを持たないパケットの接続を破棄する
-A INPUT -p tcp --tcp-flags ALL NONE -j DROP

# (4) SYNflood攻撃と思われる接続を破棄する
-A INPUT -p tcp ! --syn -m state --state NEW -j DROP

# (5) ステルススキャンと思われる接続を破棄する
-A INPUT -p tcp --tcp-flags ALL ALL -j DROP

# (6) icmp(ping)の設定
# hashlimitを使う
# -m hashlimit                   hashlimitモジュールを使用する
# —hashlimit-name t_icmp  記録するファイル名
# —hashlimit 1/m               リミット時には1分間に1パケットを上限とする
# —hashlimit-burst 10        規定時間内に10パケット受信すればリミットを有効にする
# —hashlimit-mode srcip    ソースIPを元にアクセスを制限する
# —hashlimit-htable-expire 120000   リミットの有効期間。単位はms
-A INPUT -p icmp --icmp-type echo-request -m hashlimit --hashlimit-name t_icmp --hashlimit 1/m --hashlimit-burst 10 --hashlimit-mode srcip --hashlimit-htable-expire 120000 -j ACCEPT

# (7) 確立済みの通信は、ポート番号に関係なく許可する
-A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT

# (8) 任意へのDNSアクセスの戻りパケットを受け付ける
-A INPUT -p udp --sport 53 -j ACCEPT

# (9) SSHを許可する設定
# hashlimitを使う
# -m hashlimit                   hashlimitモジュールを使用する
# —hashlimit-name t_sshd 記録するファイル名
# —hashlimit 1/m              リミット時には1分間に1パケットを上限とする
# —hashlimit-burst 10       規定時間内に10パケット受信すればリミットを有効にする
# —hashlimit-mode srcip   ソースIPを元にアクセスを制限する
# —hashlimit-htable-expire 120000   リミットの有効期間。単位はms
-A INPUT -p tcp -m state --syn --state NEW --dport 22 -m hashlimit --hashlimit-name t_sshd --hashlimit 1/m --hashlimit-burst 10 --hashlimit-mode srcip --hashlimit-htable-expire 120000 -j ACCEPT

# (10) 個別に許可するプロトコルとポートをここに書き込む。
# この例では、HTTP(TCP 80)とHTTPS(TCP 443)を許可している。
-A INPUT -p tcp --dport 80   -j ACCEPT
-A INPUT -p tcp --dport 443  -j ACCEPT

COMMIT

この設定内容を/etc/sysconfig/ の下にiptables というファイル名で保存します。
具体的には以下のコマンドになります。rootユーザーで作業してください。
vimコマンドでエディタを起動し、上記設定内容を貼り付けたあと、:wqで保存終了してください。

# cd /etc/sysconfig
# vim iptables

上記の設定内容について詳しく解説します。
(1) はポリシーの設定です。INPUT、OUTPUT、FORWARDそれぞれについてDROPまたはACCEPTの設定を指定します。

(2) 〜 (5) については、不正な接続の禁止などをする共通の設定です。このまま設定しておけば良いです。

(6) はpingの設定です。pingの応答を許可していますが、同一IPアドレスから繰り返しやってくるpingリクエストについては、外部からの攻撃とみなし拒否するようにしています。hashlimitオプションを使うことで、120秒の間に10回パケットを受信すれば、それ以降のリクエストには応答をしないように設定しています。

(7) は、確立済みの接続について通信を許可する設定です。これもよく使われる一般的な設定ですのでそのまま設定しておけば良いです。

(8) は、サーバーからのDNS問い合わせに対しての戻りパケット(UDP ポート53)を許可する設定です。これを許可しておくと、パソコンからサーバーへのSSH接続などで無駄に待たされることが無くなります。

(9) は、SSHを許可する設定です。ping設定のときと同じく、hashlimitオプションで接続回数による制限をかけています。
2分間の間に同一IPアドレスから10回接続要求があると不正な接続とみなし、それ以降の新しい接続要求を2分間拒否します。

(10) は、サービスごとに通信を許可する設定です。ここでは、TCPポート80のHTTPと、TCPポート443のHTTPS(SSL)を許可する設定をしています。
もし、他にも通信を許可したいサービスがある場合は、行を追加してください。以下の赤色の部分を通信許可したいサービスにあわせてカスタマイズすれば良いです。

-A INPUT -p tcp --dport 443    -j ACCEPT

もし、許可したいサービスのプロトコルがTCPなのかUDPなのか分からない場合は、いったんTCPとUDPのそれぞれの許可設定をしておいて(つまり2行の設定を書いておいて)、片方ずつ設定を無効にして本当に通信ができるかどうか試してみるなどして確認すれば良いと思います。または、本当に分からない場合はTCP、UDPともに通信許可をしておいても良いと思います。

設定が完了したあとは、iptablesを再起動します。
気をつけなればならないのは、SSHの設定です。SSHの通信を許可しておかないと、iptablesを有効にしたときに、新しくSSHの接続ができなくなります。
万が一、iptablesの設定に失敗してSSH通信ができなくなってしまった場合は、SSHターミナルからではなく、さくらVPSのコンソールパネルからVNCコンソール機能を使ってサーバーにログインし、iptablesの設定を正しく設定しなおしてください。

# service iptables restart

コマンド実行後[FAILD]と表示される場合は、設定ファイルに不備がありiptablesが有効になっていません。いま一度設定内容を確認してください。

設定が正しく行われたら、次のコマンドで設定状況を確認してみましょう。

# iptables -nL
Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
DROP       tcp  --  0.0.0.0/0            0.0.0.0/0           tcp flags:0x3F/0x00
DROP       tcp  --  0.0.0.0/0            0.0.0.0/0           tcp flags:!0x17/0x02 state NEW
DROP       tcp  --  0.0.0.0/0            0.0.0.0/0           tcp flags:0x3F/0x3F
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           icmp type 8 limit: up to 1/min burst 10 mode srcip htable-expire 120000
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0           udp spt:53
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:22 flags:0x17/0x02 limit: up to 1/min burst 5 mode srcip htable-expire 120000
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:443

Chain FORWARD (policy DROP)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain INPUTの項で、2280443のポートがACCEPTされていることが分かります。
以上でiptablesによるファイアウォールの設定ができました。

最後に、iptablesについて詳しく書かれたサイトを紹介します。
iptablesについて、より細かい設定を行いたい場合に参照してください。
CentOS iptablesによるパケットフィルタ
ファイアウォール(iptables)の設定

少しやり方は異なりますが、さくらインターネットの公式サポートサイトにもiptablesの設定方法について解説がありますので、こちらも合わせてご覧ください。
iptablesの設定方法|さくらインターネット公式サポートサイト

Webサーバー運用講座の第4回目は以上です。
次回はWebコンテンツのバックアップ/リストアの方法や、OSのセキュリティアップデートについて解説します。

おしらせ