「さくらのVPS」導入解説 その10:iptablesの設定

この記事は「さくらのVPS導入解説 その9」の続きです。

今回はiptablesによるファイアウォールの設定を行います。これでVPSを利用する前提としてのセキュリティ設定が一通り完了します。

ファイアウォールとは

ファイアウォールとは、不正アクセスを防ぐための技術の総称です。
ファイアウォールにも幾つかの種類がありますが、もっとも一般的なのが、アクセス(パケット)の通信元・通信先や通信経路を調べ、それが怪しいものである場合に通信を遮断するものです。「パケットフィルタリング」とも呼ばれます。

iptablesとは

Linuxでは、このパケットフィルタリングを設定するために「iptables」というコマンドが用意されています。今回はこのiptablesを使って、パケットフィルタリング型ファイアウォールを設定します。

iptablesの設定

iptablesの設定は量が多くなるため、vi/vimの操作になれていない場合は、ローカルでテキストエディタで編集したあとに貼り付けするのが良いと思います。

以下が、iptablesの設定内容です。
さくらのVPS を使いはじめる 3 — iptables を設定する – アカベコマイリを参考にさせていただきました。

*filter
:INPUT   ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT  ACCEPT [0:0]
:RH-Firewall-1-INPUT - [0:0]

-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT
-A RH-Firewall-1-INPUT -p 50 -j ACCEPT
-A RH-Firewall-1-INPUT -p 51 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# SSH, HTTP, FTP1, FTP2, MySQL
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 10022 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80    -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 20    -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 21    -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 3306  -j ACCEPT

-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited

COMMIT

iptablesの内容について

とにかく設定するだけであれば上記を貼り付けですみますが、ここではiptablesによってどのようなパケットフィルタリングを行っているか理解するために少し解説します。
なおこの解説部分の作成にあたっては、iptablesの設定 – サーバの実験室を参考にさせていただきました。

*filter

iptablesでは、設定は一覧テーブル(表)にまとめられます。
iptablesでは3種のテーブルが用意されていますが、パケットフィルタリングを行うためのテーブルがこの「filter」です。つまり、ここではfilterテーブルの使用を宣言しています。(なお、この記述を省略した場合でも、デフォルトではfilterテーブルが利用されます)

:INPUT   ACCEPT [0:0]

INPUT(インプット)つまり、このホストに対して入ってくるパケットを通過させるか遮断させるかを設定します。ここでは「ACCEPT」を設定して、いったんすべてのパケットを許可しています。
また[0:0]は「パケットカウンタ:バイトカウンタ」を表しています。今回は[0:0]にすることで、カウンタをそれぞれ0に初期化しておきます。

:FORWARD ACCEPT [0:0]

INPUT同様に、FORWARDのパケットに対する設定です。
FORWARDでは、このホストを経由するパケットに対しての設定を行います。

:OUTPUT  ACCEPT [0:0]

OUTPUTでは、このホストから送られるパケットに対する設定を行います。
なお、これらINPUT、FORWARD、OUTPUTは正確には「チェイン」と呼ばれます。(INPUTチェイン、のように呼びます)

:RH-Firewall-1-INPUT - [0:0]

前述のINPUT、FORWARD、OUTPUTとは別に、ユーザー定義のチェインを定めます。
このユーザー定義チェインで、細かいパケットフィルタリングの設定を行います。

-A INPUT -j RH-Firewall-1-INPUT

「-A」は新しいルールの追加を表します。半角スペースに続けてチェイン名を入力することで、どのチェインにルールを追加するか示します。ここではINPUTチェインに対して、新しいルールを追加しています。

また「-j」はjumpの略で、あるチェインを別チェインにジャンプさせる場合に使います。
ここではINPUTチェインを、ユーザー定義チェインにジャンプさせています。これにより、INPUTチェインで入ってくるパケットが、ユーザー定義チェインでチェックされるようになります。

-A FORWARD -j RH-Firewall-1-INPUT

同様にしてFORWARDチェインも、ユーザー定義チェインにジャンプさせてチェックするように設定しています。

-A RH-Firewall-1-INPUT -i lo -j ACCEPT

「lo」は「ループバック」と呼ばれる、自分自身への通信(INPUTとFORWARDが同じ)を指します。ループバックの場合は「ACCEPT」にて通信を許可します。

-A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT

「icmp」とは通信にエラーが生じた際にエラーメッセージを送るプロトコルです。ICMPの場合は「ACCEPT」にて通信を許可します。

-A RH-Firewall-1-INPUT -p 50 -j ACCEPT
-A RH-Firewall-1-INPUT -p 51 -j ACCEPT

「-p」に続けて番号を入力することで、プロトコルを指定して通信を制御できます。
上記では50(ESP)と51(AH)を許可していますが、この二つはどちらもパケットが改ざんされていないかをチェックするためのプロトコルです。
参考:IPプロトコル番号一覧 – ネットワークエンジニアとして

-A RH-Firewall-1-INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT

ポート「5353」はマルチキャストDNSというプロセスです。これは専用のアドレス「224.0.0.251」にパケットを投げて応答をもらうことで、わざわざIPアドレスとホスト名の変換を行わなくてもマシンを認識できる仕組みです。

-A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT

ポート「631」は印刷データの送受信のためのプロトコルです。これも「ACCEPT」で許可しておきます。

-A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

「-m」はiptablesの拡張モジュールを使うための設定です。上記の例では「state」と続けて入力することで、stateモジュールの利用を可能にしています。

この「state」はパケットの状態を指定するためのモジュールです。今回は「ESTABLISHED(過去に接続されたことがある)」または「RELATED(既存の接続に関係している)」と見なされた場合に、接続を許可しています。
※なお、この一行がないと通信を行うことが出来なくなりますので注意してください。

-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 10022 -j ACCEPT

こちらも「state」を使ったルールです。
パケットの状態が「New」である場合でも、SSH接続にあたるポートであれば、接続を許可します。

※ここで「10022」を指定しているのは、前回の記事でSSHのポート番号を10022にしたためです。もしポート番号を変更していない場合は「22」、また任意で別の番号にした場合はその番号を入力してください。

また「-m tcp」でtcpモジュールを有効にした後に、「-p tcp」でプロトコルがtcpの場合に限定しています。

-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 20 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 25 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT

同様にして「80(HTTP)」「20・21(FTP)」「25(SMTP)」の接続を許可します。
ここまでで、許可したい接続のルールが終わりました。

-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited

すでに接続を許可したいパケットのルールは読み込まれているため、この行を読み込むのは、接続許可のルールに一致しなかったパケットになります。それらのパケットはすべて「REJECT(エラーパケット送信)」します。

「–reject–with」はエラーパケットの種類を指定するためのもので、今回は「icmp-host-prohibited(ホストによって禁止されました)」というメッセージを送るように指定しています。

COMMIT

最後にこれらのルールをコミット(登録)します。

iptablesを設定する

それでは作成したiptablesの設定をVPSに登録します。

  1. 以下のコマンドを入力し、iptablesの設定ファイルを開きます(作成します)。
    $ sudo vi /etc/sysconfig/iptables
    
    • Poderosaのステータスラインに[New File]と表示されていると思いますが、これはiptablesファイルは新規作成されるファイルのためです。
  2. テキストエディタからコピーしたiptablesの設定を貼り付けします。
    • Poderosaのメニューバー「編集」→「貼り付け」で貼り付けできます。
    • 行頭・行末に空白スペースが入ってはいけないので注意してください。また最終行での改行も行わないようにしてください。
  3. 「:wq」を入力して上書き保存と同時にviを終了します。
    :wq
    
  4. 以下のコマンドを入力し、iptablesを再起動します。
    $ sudo /etc/rc.d/init.d/iptables restart
    
  5. 「Applying iptables firewall rules: [ OK ]」と出たらOKです。
  6. 以下のコマンドを入力することで、現在のiptablesの状態を確認できます。
    $ sudo /sbin/iptables -L
    

以上でiptablesの設定は完了です。