uzullaがブログ

uzullaがブログです。

Nginxによる不正なproxy設定と、OSXとそれ以外での謎挙動の話

DISCLAIMER

本テキストは事実を元にした創作です

さよなら、papix

先日、Yancha(ウェブチャット、http://yancha.hachiojipm.org/)のサーバにはいっている*1nginxのコンフィグを色々書き換え、再起動し、一通り手元でチェックし、問題ないな!と安心して床についた。*2


すると、翌日になって「Yanchaにつながらない」と__papix__君がレポートをくれた。
しかし私の環境では全く問題なくつながったし、実際他のメンツも普通につながっているようにみえたので、「多分君の環境ではないかな?」とレスをした。


しかし、その後依然として接続できないパピックス君は疑心暗鬼にとらわれる。彼は猛烈な講義を開始した。
「これは陰謀だ!!!おいだされた!!!迫害だ!!!おいだされた!!弾圧だ!!FA宣言する!!uzulla死すべし!匕力㋷工倒壊!!」
みたいな(あくまで、みたいなことであり、比喩であり、要約である)ことを騒がれ、しかたなく状況調査を開始した。

再現しない

上述もしたが、手元のMac、iPhoneではまったく再現せず、また、参加している面々はしっかりオンラインになっている。
本当にpapix君だけがバンされているように見える。
10人くらい接続していて、1人つながらない、手元のPCもつながる。


そして彼は先日CUDAの計算結果とPerlの計算結果と手計算があわない!と言っていたが、実際には手計算が間違っている事に気付き、その後コードも間違っていて面白かった。

「手元で再現しません」

まあ、ウェブエンジニアなら何回か言った事があるであろう「それはあなたの環境がわるいのでは?」案件である。


「もしかして君の所属組織ネットワークでバンしたのでは?」と問いかけるも、モバイルルータでもダメとのこと*3


同窓のbool_fool君からは(nginx再起動後の)朝も発言できた*4という証言をもらい、さらに混迷を極める。

信じるのはコード?それとも?

YanchaはGithubでホスティングされているのだが(https://github.com/uzulla/yancha
)、papixに日頃から陥れられているmoznionが、あの伝説の「最高の機能(https://github.com/uzulla/yancha/commit/f7c4138dc7326bacf134eb474803f77de0d1e298)」を再度実装してプルリクしていたのでは?とふと思いつく。


最近忙しさを理由にして「みどりのボタン押すのたのし〜〜!!」という緑のボタン*5連打症になりつつある自分が原因ではないかと悩み始める。


しかしGitのコミットログはおそらく嘘をつかないし、昨日はデプロイしていない。
そんなに複雑な、時限式の隠蔽にすぐれたロジックを入れられたのだろうか?まさか。

状況、判明

いや、こういうときは現状把握からだ、そう、冷静沈着にいこう。
幸い騒いでいるのはpapixくんだけだ、しかも彼のFacebookでだ(https://www.facebook.com/takayuki.fukumoto.92/posts/541194565957156
)。


「みなさん、接続している環境を教えてください」となげると、
5〜6人ばかりが報告を上げてくれたとき、一覧して、その時私に電流走る。


「80番ポートで接続できているのは、Macばかりだ!!」

Macは80につながる

ひっくりかえすと、WindowsとUbuntuは3000番ポートにしかつないでいない
(Yanchaは3000番ポートでうごいているが、一部の不自由なネットワークの対応のために80番ポートにnginxでProxyしている)


WinとLinuxの諸氏に80への接続テストを依頼すると、はたして接続はできなかった!


現象はこれだ!
自分も手元のVMのWindowsでの接続が確認できなかった。ついに問題をみつけた、papix君の容疑が晴れた瞬間である。


そして、これが疑いが我が身に降りかかった瞬間でもある。

なにが違うのか?

とにかく、3000番で直接つないでいるのはOKで、80がダメ、つまりnginxに問題がある。
さらに前日私はnginxの設定をかえていたので、これはもうまちがいない。


そもそも、なにがどうおかしいのか通信をみてみると、HTML自体はロードできているが、jqueryなど一部のJSがロードできていないことにきづく、JSのエラーがでている。


そのJSは延々とロードをしようと粘っており、終了しない。


一部のライブラリファイルだけが転送不良におちいっているようだった。*6


「これは…なんだ?」

ここで私は泥縄的にkeepaliveをオフにしたり、gzip転送をオフにしたり、ワーカの数を数をかえたり、怪しそうなものを色々とかえてみた、しかし一向に改善しない。


原因がわからない。こうしている間にも哀れなpapix君のFacebookのコメントは伸びていく…、まったくもってどうでもいいが。


おちついて昨日の修正を思い出す、昨日やった修正は何だ…?
…そうだ、nginxの動作ユーザーを変えた!

nobody knows

nginxはデフォルトでnobody権限で動作するのだが、同居しているあるウェブアプリのためにnginxを一般ユーザーに権限変更したのだ!


しかしrootから一般ならまだしも、nobodyから一般ユーザーに変えただけで極端に動作がかわるとは思えない、しかし一縷の望みを託し、書き換え、HUPしてみた。


そして、その修正をpapix君に伝える前に、Yanchaに響き渡った。


「削除芸の時間だァ!!!!!!!!!!!!!!!!!!!!!!!!!」
http://yancha.hachiojipm.org/quot?id=170617


彼の歓喜の声であった。*7


私は安堵し、すぐにでもおめでとうと伝えたかったが、それよりも本当の原因か究明するために、再度ユーザーを戻した。ふたたび静かになった。


けっして「ウザっ!」と思ったわけではない、原因を早く知りたかったのだ*8

アイエエエ!?ナンデ!?コワイ!」

とりあえずその設定を入れ換えるだけでpapix君がBan。いや、Mac以外が接続できなくなるのが確認できた。まったくもって理由がよくわからないが、兎に角そうなった。


なんでやねんとつぶやきつつ、ツイッターにつぶやくと、最強のインフラエンジニアことfujiwara氏が即レスをくれた



「(意訳)中間ファイルが保存されるproxy_tempの権限では?」


そうか!nginxはproxyとして動作するときにファイルでバッファを持つ。
そのproxy_tempというディレクトリを確認したらnobodyユーザー以外の書き込み権限はなかった。


いまさらのようにエラーログを確認すると

2013/10/31 04:04:54 [crit] 32288#0: *12566 open() "/usr/local/nginx/proxy_temp/2/14/0000000142" failed (13: Permission denied) while reading upstream, client: xxx.xxx.xxx.xxx, server: yancha.hachiojipm.org, request: "GET /static/js/jquery.js HTTP/1.1", upstream: "http://127.0.0.1:3000/static/js/jquery.js", host: "yancha.hachiojipm.org"

*9


などというエラーがバッチシでていた。一発である、汗顔しきりである。


ちなみに、proxy_store_accessパラメタを変更した上で、proxy_tempのパーミッションを正せば、これは直る、ドキュメントはこちら http://wiki.nginx.org/HttpProxyModule

そしてYanchaに平和がおとずれた

今日も元気にpapix君は削除芸を繰り返す、苦虫をかみつぶしたような顔のmoznionを尻目に…。*10


めでたしめでたしである。

しかし、謎は残った。

なぜ、Macでは、接続できるのか?追試でも同様の結果だった。
Macが最高に優れたOSであるから、と言い切るのは最近MBP13を買った*11マカーからすれば容易い事だが、多分そういう話ではない。


なんとなく、RWINとかまあそういうアレな気もするのだが、ここはどうやって試験すべきかイマイチおもいつかない。


ちなみに、OSXのRWINはめちゃデカイ。524280である。Windowsとかは65535だったと思う。


ここらへんがあやしいと思って居ても、まあ直ったし、無駄にこのエントリも長くなったからいきなりここで終わりとする。

まとめ

・まずはエラーログをみろ
・状況は正確に把握しよう
・自分を疑え
・問題を潰すには、一度全部もどせ
・コンフィグは世代管理せよ
・fujiwaraさんすごい

*1:3000番でうごいているYancha本体を、80番にProxyしている

*2:今思えば、一部の転送に引っかかりを感じていたのだが

*3:と、ここでいいつつ、彼が80だけをチェックして、yanchaの代替ポートである3000をためしていなかったのは罪深い

*4:これはかなりのトリックである、原因は後述

*5:マージボタン

*6:これがBool_fool君が朝問題なかった理由であり、このJSが一旦ロードされていれば、Websocket通信は問題なかったようだ

*7:削除芸とは、彼がしばしばYanchaでおこなう不規則発言を、即時削除し、なかったことにせしめる卑劣な行為である。Yanchaの思想である「ログは全部保存しておくと便利!」から真っ向にぶつかる行為である。ちなみに、彼はしばしばなにかを倒壊させたりした後、削除したりしている

*8:バーティカルフロント

*9:これは後日の追試である

*10:どうでもいいが、某氏に「あんまり不穏な事いうな」といわれたモズニオンが「ボクじゃないですよ!パピックスさんですよ!」と反論し、納得されたという話をきき、本当にクソ笑ったことをここに記す

*11:軽い!最高!!!