j3iiifn’s blog

ネットワーク、インフラ、プログラミングについての備忘録

Netfilterルールを保存したりリストアしたりする方法はいろいろある

Netfilter自体には、ルールを保存したりリストアしたりする機能は用意されていない。 せっかく慣れないiptablesコマンドを勉強しながら頑張って設定しても、OS再起動後は全部消えてしまっているのである。 したがって、ルールの保存・リストアを行う仕組みが別途必要である。

その仕組みの実現方法にはいくつかの流派がある。保存とリストアのそれぞれに何種類かの方法があり、それらの組み合わせで実現する。すべての方法を網羅できているとは思わないが、私が知っているやり方を紹介する。

まず保存の観点で分類すると、以下の2通りある。

  1. シェルスクリプト派】iptablesコマンドを並べたシェルスクリプトを用意する。そのスクリプトを実行するとNetfilterルールがひととおり適用される。
  2. iptables-save派】iptables-saveコマンドの出力形式でルールファイルを用意する。iptablesコマンドでひととおり設定した後にiptables-saveコマンドを実行するか、もしくは直接ルールファイルを編集する。iptables-restoreコマンドの標準入力にルールファイルを与えると、Netfilterルールが一通り適用される。iptables-save/iptables-restoreについてはiptablesチュートリアルの第8章<原文><和訳>Stray Penguin - Linux Memo (iptables-2)が詳しい。

次にリストアの観点で分類すると、以下の4通りある。

  1. 【cron派】crontabに @reboot を先頭につけてリストアのためのコマンドを記述する。
  2. 【rc.local派】/etc/rc.local にリストアのためのコマンドを追記する。
  3. 【if-pre-up.d派】/etc/network/if-pre-up.d/ にリストアのためのシェルスクリプトを設置する。
  4. 【systemd派】systemdでサービス化する。ユニットファイルを自作するか、もしくは既成のパッケージを利用する。

私は長らく保存:1/リストア:3の方法を採用していた。 しかし、複数のインタフェースを持つマシンの場合、各インタフェースがupするたびにシェルスクリプトが実行されてしまう。 それでシェルスクリプトが複数回同時に実行され、互いにロックを奪い合い、最終的に途中までしかNetfilterルールが適用されない問題が発生して悩んだことがあった。

その後、systemdのユニットファイルを自作したこともあったが、最近 iptables-persistent / netfilter-persistent というパッケージで手軽に自動リストアできることを知った。 このパッケージは保存:2/リストア:4の方法を採用している。 次回の記事では iptables-persistent / netfilter-persistent の内部挙動について調査した内容をまとめる。