12.4. iptablesのデバグ

iptables のデバグはなかなか骨が折れる。というのも iptables がいつも分かりやすいエラーメッセージばかり出すとは限らないからだ。そこで、 iptables でよくあるエラーメッセージと、それが出る理由をおさらいしておこう。

まず最初が "Unknown arg" エラー。出る原因はいろいろとある。例えば下のようなメッセージだ。

work3:~# iptables -A INPUT --dport 67 -j ACCEPT
iptables v1.2.9: Unknown arg `--dport'
Try `iptables -h' or 'iptables --help' for more information.
      

この例なら、使用している引数がひとつだけなので解決はあまりにも容易い。このエラーメッセージにお目にかかるのは、普通、長い長いコマンドを使った時だ。上のケースでの問題は、 --protocol マッチを入れ忘れていること。そのために、 --dport マッチが利用可能になっていないのだ。 --protocol マッチを加えればこのマッチの問題は解決する。或るマッチを使うには前提条件として特定の別マッチが必要な場合があり、それを指定し忘れていないか、よく確認しておく必要がある。

また、命令の中でダッシュ (-) が足りないためのエラーというのもよくある。下の例だ。解決策の正解はダッシュを足すだけ。それでコマンドはうまくいく。

work3:~# iptables -A INPUT --protocol tcp -dport 67 -j ACCEPT
Bad argument `67'
Try `iptables -h' or 'iptables --help' for more information.
      

もうひとつが、単純なミススペリングで、これもよくある。下記の例だ。お気づきのように、表示されるエラーメッセージの内容は、前提マッチを忘れた場合と全く同じなので、注意して見ないと分からない。

work3:~# iptables -A INPUT --protocol tcp --destination-ports 67 -j ACCEPT
iptables v1.2.9: Unknown arg `--destination-ports'
Try `iptables -h' or 'iptables --help' for more information.
      

上に述べた "Unknown arg" エラーメッセージの出る原因がもうひとつある。引数に問題が無く、前提条件のミスも考えられないという時には、ターゲット、マッチ、テーブルのいずれかがカーネルにコンパイルされていない可能性がある。例えば filter テーブルのサポートをカーネルにコンパイルし損ねた場合のメッセージは、このようなものになるだろう:

work3:~# iptables -A INPUT -j ACCEPT
iptables v1.2.9: can't initialize iptables table `filter': Table does not exist 
(do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
      

通常、カーネルに内蔵済みでないモジュールがあると iptables は自動的に modprobe する能力を持っているので、こうしたエラーの出た原因はふた通り考えられる。カーネルをコンパイルしなおしてから depmod を適切に行わなかったか、あなたがそのモジュールのことをはなから忘れていたかのどちらかだ。ところが一方、問題のモジュールがマッチに関するものだった場合、エラーメッセージはもっと暗号じみて、理解が困難となる。例としてこのエラーメッセージを見ていただこう。

work3:~# iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
iptables: No chain/target/match by that name
      

この場合、我々はステートモジュールをコンパイルし忘れているのだが、エラーメッセージは理解しやすい親切なものとは言い難い。とはいえ、少なくとも、問題のヒントは与えてくれる。最後にもうひとつ、同じエラーメッセージを示そう。しかし今回欠如していたのはターゲットだ。ご覧の通り、ことは混迷を極める。 (不足しているのがマッチなのかターゲットなのか両方なのか不明の) 全く同一のエラーメッセージとなるからだ。

work3:~# iptables -A INPUT -m state --state ESTABLISHED -j REJECT
iptables: No chain/target/match by that name
      

depmod のし忘れなのかモジュールそのものが欠如しているのかを知る一番手っ取り早い方法は、モジュールが存在するはずのディレクトリを確認してみることだ。その場所は /lib/modules/2.6.4/kernel/net/ipv4/netfilter ディレクトリ。 ipt_* ファイルのうち、大文字で記されているのはターゲット、小文字で書かれているのがマッチとなる。例えば ipt_REJECT.ko はターゲット、 ipt_state.ko はマッチだ。

Note

2.4 以前のカーネルではカーネルモジュールの拡張子は .o だったが、 2.6 からは .ko に変わった。

他に、 iptables 自体に助けを求める方法もある。ひとつのチェーンを丸ごとコメントアウトしてみて、問題が解消するかどうか試す方法だ。これは最終兵器とも言うべきもので、いったいどのチェーンが問題を起こしているのかも分からない時に威力を発揮する。或るチェーンを取り除いて、デフォルトポリシーも ACCEPT に設定し、試してみる。それで改善すれば原因はそのチェーンにある。改善しない場合は、次のチェーン、次のチェーンと試し、問題箇所を絞り込んでいけばいい。