連載第88回
2014年7月23日
WP HTTP Error の原因は iptables の INPUT の UDP だった

 前回のSVGフォーマット画像の置き換えの件から、またあのHTTP errorの件に戻ります。要点をまとめてシンプルにサクッと記事化するのもいいのですが、結論に至るまでのドタバタ劇も可能な限り掲載してしまうのが当サイトの作風なので、またいつものように長くなりますがお付き合いください。
 以前の試行では、「OUTPUT」と「FORWARD」を両方とも基本ポリシーとして「ACCEPT許可」に変更してみたのですが、症状は改善されませんでした。そこで今回はまず、OUTPUTに追加していた幾つかのルールも影響しているかも知れないと思い、全て削除してみました。が、

状況変わらず。

受信パケット(INPUT)だったのか!

 転送パケット(FORWARD)も発信パケット(OUTPUT)も完全に「ACCEPT許可」にしてもダメ。というワケで、半ば投げやりな気分で、これまで全く試していなかった受信パケット(INPUT)の「デフォルトのアクション(基本ポリシー)」も「ACCEPT許可」にしてみました(↓)。念のためサーバー自身も再起動(普通はiptablesの再起動だけで設定が反映します)。すると…。

↓来やがった!!

↓プラグイン検索もきた!!

 喜びと愕然が混沌とした気分を味わいました。外部アクセス出来るようになったのは喜ばしい(ファイヤウォール全開だから当然だけどな…)、がしかし、それが「INPUT」パートで管理されているという事に全く気付け無かった事、全くの知識不足であることが悔しい。つまりパケットのやり取りの根本的な仕組みが理解出来ていないことが露呈。

 WordPressのダッシュボードにアクセスした際、WordPressが外の情報を取りに行くのはイメージとしてやはりどうしても「OUTPUT」が浮かんでくるんだけれど、現状から解釈すると、

WordPressが必要な情報を外部からサーバー内に「取り込む」動作なのだから「INPUT」

と考えれば、納得できるような気がします…気がしてきた(無理矢理)!

では一体、どのルール設定を修正すべきなのか?

 さて。現状では以前あれほど苦労して施した(初心者レベルの)セキュリティ設定が全開放されていて、どこからでも好きにサーバーを攻撃して構いませんよ状態。早く閉じたいのですが、閉じる手順を間違えると自分がアクセス出来なくなってしまいます。復習として、まず自分の過去メモにもう一度目を通しておく。

 それにしてもしかし、WordPressが取得してきたパケットを破棄しているのは一体どのルールが原因になっているのか?不具合に気付いた当初、WordPressが独自に使っている特定のポート番号を破棄してるのかしら?とか、DNS逆引が悪さ(ダッシュボードの動きがメチャ重かったので)しているのかしらん?等々と思ったのですが、しかしWordPressと言えども使っているポートは80か443なのではないか。だとしたら、それら2つのポートに設定している「ステートフル・パケットインスペクション」のルール設定に引っ掛かっているのかも…。

原因ルールの絞り込み

 INPUTのデフォルトのアクション(ポリシー)は「DROP」。でも特定の条件に適合したパケットだけは通過させるようにしています。同時に、特定の条件に合致したパケットは破棄しています。それらを登録してリストしているのがwebminのこの画面(↑)。
 全部で13のルールを追記していますが、この中で、さすがに今の不具合の原因ではなさそうな物としては「ssh」「MySQL」「webmin」の3つが通過するポートに施したルール。それとプロトコルがUDPとICMPに関するもの。さらにループバック「lo」。合計9個。

 それら9個のルール以外のもの、つまりポート番号「80」「443」の2つに関連する4つのルールの中の、パケットを「破棄」させている2つのルール設定どちらかに引っ掛かっているのではないかと推測しました。上の画像では計5つの破棄ルールが見えますが、その中のどれか1つを「許可」にしてダッシュボードが外部接続するのなら、それがトラブルの原因となっているルールとなります。

しかし…特定できず

 では再び「INPUT」のデフォルトアクションを「DROP」にして「設定を適用」をクリック。これでWordPressのダッシュボードは再び外部接続出来無くなりエラーを返すようになります。そして上で考えたように、今まで「破棄」させていたものを交互に「許可」にして挙動を試してみました。
 が、しかし!デフォルトアクションが基本的に「DROP」の状態だと、リストに掲げてあるルールを全て「許可」したところで、ダッシュボードの接続不具合は全く改善されなかったのです。例えば、基本DROPにセットした上で「ステートフル・パケットインスペクション」の細かい条件設定を省き、「宛先ポート番号80番を許可」というとてもシンプルで緩い条件にしてもダメ。思い付くリスト以外のポート番号を試したりしてみたけど当然ダメ。

 そして、またINPUT全体をACCEPTにすると不具合は起きない…セキュリティ面では若干後退することになるけれど、もう、INPUTの基本ポリシーを「許可(ACCEPT)」に変更し、部分的に破棄ルールを追記する仕様にしようかと思いました。ここに至るまで各ルールの挙動を総当たり戦で動作確認するのに6時間経過…。

途方に暮れて、再び投げやり気分で

 諦め気分でほぼ基本ポリシーをACCEPTに変更することに決めた時に、何でそう閃いたのか全く分からないのだけれど「発信元のポート番号80番のTCPも許可してみようか…」と思いました。
 これまでは特に考えもなく、以前参考にした記事に書かれている通り、INPUTに追加した各ルールのプロトコルの指定は「宛先」を選んでいたのですが、今回の件ではOUTPUTとINPUTを履き違えていた事もあって、宛先とは逆の「発信元」も追加してみようと考えたのでした。それがリスト最後にある「発信元ポート番号80のTCP」です。そしたら何と…。

↓人気のタグがきた!!

 びっくりした。まさか「発信元ポート80」が鍵を握っていたとは。つまりこの事態を解釈するなら「サーバーから外部に情報を取りに行く時は、出口の番号を指定しておきましょうね、ハイ80番」という事か。受信パケットのコーナーでそれはなかなか思い付かないよ…。

しかしまた新たなトラップが…

 すっかり日は落ちてしまったが、気分はメキ・メキと高揚してきました。早速テキトーなキーワードを入れてプラグイン検索を試してみたところ…。

 人気のタグ表示などどうでもいいから、検索できなきゃ意味がないだろー!とは叫びませんでしたが、まさに3歩進んで2歩下がる状況。しかし「思いもよらなかった場所に、探し物はある」というどこかの映画会社の宣伝さんが考えた下手なキャッチコピーのようなことを今回のトラブルで学びつつあった僕は、これまで考えもしなかったプロトコルの設定を積極的に変更してみることにしました(つまり根拠もアテも全くナシに)。作業を開始してから既に7時間が過ぎています。で、そのプロトコルとは…

「UDP」

 UDPプロトコルについてはこれまで、INPUTとOUTPUTに、DNS接続用に限定して「宛先ポート番号53」を許可していたのですが、それを発信元・宛先関係なく、さらにポート番号も無視する設定に緩めてみました。日本語に訳されたルール内容「もしプロトコルがUDPである」が微妙に変ですが、これを適用してみたところ…。

↓検索結果キター!

 遂に探し物を見つけました。まさかエラーの原因が「UDP」だとは一体誰が考えるでしょうか(いや、たぶん詳しい人なら直ぐ気付くのかも)。しかし目の前でちゃんと検索結果は返ってきている。まさに「思いもよらなかった場所に、探し物はある」。なにそれ。

まとめ

 もう8時間経過しましたが(しかも、それをこの無駄に冗長なブログ記事にまとめ上げるのに、そこからさらに3時間を要しました)、無事、INPUT・FORWARD・OUTPUTの基本ポリシーを全て「DROP」にしたまま、限定的に必要なパケットのみを通過させてプラグイン検索が出来るルール設定を施すことが出来ました。

 ただUDPに関しては、これまで53番ポートのみ通過させていたのを、全て通過させる設定に緩める必要がありました。というのもWordPressが使用しているポート番号が分からなかったからです(ちなみにUDPは0~65535番までのポートを使用可能です)。しかも不思議なのですが、UDPだけを通過させてもダメで、「TCPの発信元80番ポート」もセットでないとエラーを起こし、プラグイン検索結果が返ってこないのです。これは僕の詰めの甘さというか、完全に理解不足なのですが、誰か理由を知ってる人がいたら教えてください。

 これで、WPダッシュボード上でのエラーは起きなくなりました。1週間僕を悩ませてくれた、WordPressが外部接続出来ないというトラブルは「解決済み」の判を押すとします。でもアレですね、今回のような状況のトラブルに見舞われている人は何度ググっても他に居ませんでしたから、かなりレアケースというか…一般には有り難みの薄い記事のような気がします。だってWPプラグインのインストールは「webからzipをダウンロードして解凍してからサーバーにFTPアップロードしてね」という手順がどうも世間ではデフォルトのようだからです。

 しかしながら、もしこの記事が何かのお役に立つようでしたら幸い。これで主要な課題リスト、消えましたな。

 仮ロゴのジャギー原因解明の為にSVG画像に置き換えてテストしたい。
 というか、仮ロゴ自体のデザインをどうにかしたい。
 <footer>エリアの項目には自己紹介以外に何が必要か。
 タグを導入したい。
 WordPressのダッシュボードが外部と接続出来無い。

しかしまた別の、小さなトラブルは起こるのでした…つづく。