ITインフラで友人の誕生日を祝ってみた (*´∀`*)

Topotalメンバーの誕生日

birthday_005c

Topotal Project メンバーの誕生日はろくなことが起きないのは毎年恒例のこと。

今までは、サーバHackが主流でした。
SSHログインすると、事前に書き換えられた.bash_rcによりお祝いの文章が垂れ流さるケースなどなど。。。
 

reyさんの誕生日

2013/01/17 に Topotalのプログラマー(reyさん)が誕生日を迎えるということで
例によって今回も盛大に祝福することにしようと考えました。
 

お誕生日を祝うための作戦

MH900056099

考えた結果、今回はTopotalのデザイナーと一緒に、お祝いサイトを新設して祝福しようということに決めました。1/16 18:00くらいに決めました。sawa-zenさんにお願いしたら快く引き受けて、すぐにサイト作成に取り組んでくれました。

お祝いサイトをわざわざ、「あのー、お祝いサイト作ったんで見てもらえますか〜」と友人に言ってみてもらうのはなんかな~と思ったので、

無意識のうちにお祝いサイトを表示させて喜んでもらう (*'-'*)

ような仕掛けをしました。どのサイトよりも見てほしいので、どのサイトをみてもお祝いサイトが表示されるように仕掛けてみました。

具体例: reyさんがGoogleのサイト(http://googole.co.jp)(何のサイトでもいい)にアクセス -> ルータの設定に引っかかる -> 誕生日サイトが表示される。

Topotalのインフラ担当としての意地を見せるときがきたわけです。
 

無理やりお祝いサイトに飛ばす設定の流れ

  1. reyさんが送信したHTTPパケットをすべて自サーバ(筆者の)のあるIPへ引きずり込む(L4)
  2. ルータでWebサーバへ転送(L4)
  3. Webサーバにて、お祝いサイトへ転送(リダイレクト)する(L7)

 

設定する上で守ろうとしたポリシー的ななにか

  • Twitterは見せてあげる
  • reyさんのお姉様には迷惑をかけない(一緒のルータをつかってるので気をつける)
  • サーバ内の設定においても盛大にHappyBirthdayする
  • 設定中に気づかれないようにする

彼は誕生日だというのに、家でぐーすかぴー寝てました。その間、友達思いの筆者はしっかり計画を練ってました。
誕生日の特設サイトはデザイナー(最近はもはやプログラマー)のsawa-zenさんにおまかせしました。
最初はサイトを作る気まんまんだったのですが、この計画を立てたのでやめました。無理しない無理しない。

それでは、以下にインフラ側の設定手順を書きます。
 

作業上の注意

作業中にばれたらアウトなので、ターミナルの画面で watch -n1 w を垂れ流しておきます。

 

1. reyさんが送信したHTTP*1 パケットをすべて自サーバ(筆者の)へ引きずり込む(L4)

ここでは、reyさんの家のルーターをHackします。reyさんの家のルーターはLinuxサーバです。そのためiptablesの設定を書き換えることでサプライズ設定をしました。
 

reyさんちのルータのiptablesをいじる

 

インフラ担当ということで、root権限を付与されてます。ということでiptablesはいじり放題です。
引きずり込むには、「80番ポート宛のすべてのパケットを自サーバにNATすればよい」ので、

iptables -t nat -I PREROUTING 1 -p tcp -m tcp --dport 80 -j DNAT --to <自サーバのGIP>

とすれば大丈夫なように思いますが、これでは不十分。reyさんのブログを見に来た人にも影響が出てしまいます。
そのため、送信元制限をかけます。

iptables -t nat -I PREROUTING 1 -s 192.168.x.0/24 -p tcp -m tcp --dport 80 -j DNAT --to <自サーバのGIP>

としました。
しかし、これではルータにぶら下がっているホスト全体に影響がでるので、当然お姉様にも影響がでてしまいます。
そのため、reyさんのPCだけに適用するように設定を加えます。
 

reyさんの保有するPCのMACアドレスを調べる

 
reyさんのPCであるかを判定するために、MACアドレスを使いました。機器ごとにユニークなアドレスだからです。

どうやってMACアドレスを調べようか迷いました。少し考えて
そういえば、以前reyさんが我が家(YAKATA)に来た時にDHCPを利用してたことを思い出しました。
それを利用します。

/var/log/dhcpd.log を適当なホストネームで検索して探しました。

egrep "rey-mac|rrreeeyyy|rey" /var/log/dhcpd.log

すると以下のようなログが出てきました。

Jan  9 23:53:03 bonjour-01 dhcpd: DHCPACK on <IPアドレス> to <MACアドレス> (<reyさんのPCのホストネーム>) via br0

これでMACアドレスがわかりました*2 。iptablesに組み込みます。

iptables -t nat -I PREROUTING 1 -s 192.168.x.0/24 -m mac --mac-source <reyさんPCのMACアドレス> -p tcp -m tcp --dport 80 -j DNAT --to <自サーバのGIP>

ほんとうにこれでいいのでしょうか。ポリシーの3番目(サーバ内の設定においても盛大にHappyBirthdayする)を守れてないのでダメです。
それとTwitterもみれるようにしないと。
 

iptables の最終的な設定*3

 
ということで、ポリシーを守りながら設定をした結果、以下のようになりました。

mangleテーブル

  • PREROUTING チェイン
  • iptables -t mangle -I PREROUTING 1 -i br0 -m mac --mac-source <reyさんPCのMACアドレス> -s 192.168.x.0/24 -p tcp -m tcp --dport 80 -j MARK --set-xmark 20130117
    

     
    natテーブル

  • PREROUTING チェイン
  • iptables -t nat -I PREROUTING 1 -j HAPPY_BIRTHDAY
    
  • HAPPY_BIRTHDAY チェイン(チェインを作るところから)
  • ※ドメインをしていすると、リゾルバで引かれたAレコードのIPが代入されます。
    複数のIPが指定されている(DNSラウンドロビン)場合に便利です。

    iptables -t nat -N HAPPY_BIRTHDAY
    iptables -t nat -A HAPPY_BIRTHDAY -i br0 -d twitter.com -j RETURN
    iptables -t nat -A HAPPY_BIRTHDAY -i br0 -d api.twitter.com -j RETURN
    iptables -t nat -A HAPPY_BIRTHDAY -i br0 -m mark --mark 20130117 -p tcp -m tcp -j DNAT --to <自サーバのGIP>:13117
    

    誕生日なチェイン、誕生日なMARKの値*4 、誕生日なNAT先のポート…
    これでお祝いの準備ができました。

    (iptablesの流れ:mangleテーブルでMARKをつけ、natテーブルでMARKを元にNAT。twitterのIPならNATしないでもとのチェインに戻る)

    これで、1. はおわり。
     

    2. ルータでWebサーバへ転送(L4)

     

    • 誕生日っぽいポート(13117)を、誕生日サイトを表示するWebサーバにNAT
    iptables -t nat -I PREROUTING -i br0 -p tcp -m tcp --dport 13117 -j DNAT --to <Webサーバ>:13117
    

    これで、2. はおわり。
     

    3. Webサーバで、お祝いサイトへ転送(リダイレクト)する(L7)

     

    Topotalでは、Webサーバに Nginx を使ってます。
    設定は以下の通り。

    • 13117番ポートへのHTTPリクエストを、Birthdayサイトにリダイレクト
    server {
            listen          13117;
            rewrite     (.*)   http://birthday.topotal.com/ permanent;
    }
    server {
            listen          80;
            server_name     birthday.topotal.com;
            root            /var/www/birthday/;
            access_log      /var/log/nginx/birthday.topotal.com-access.log main;
            index           index.html;
    }
    

    誕生日サイト用にアクセスログを集計するように設定。
    これで、3. もおわり。
     
    最後に、ばれないようにするために、作業を実施したすべてのサーバの履歴(.bash_historyとか) を消し去り、作業を隠蔽します。
    詳細は書きません。
     

    最終的な流れ

     
    最終的な流れは以下です。

    1. reyさんちのiptablesで、80番PortへのパケットをDNAT->topotal.com:13117(自サーバへ)
    2. 自サーバのiptablesで 13117宛のパケットを webサーバの13117へDNAT
    3. topotal.com:13117のアクセスを Nginx で birthday.topotal.com:80 へリダイレクト(permanent)

    IPベースのバーチャルホスト設定なら、3つ目のリダイレクトはいらないのですが、
    ネームベースなのでこういう流れになってます。

    13117番ポートアクセスのときにサイトを表示することも可能ですが、
    やはり、美しいURLで表示させたかったので、リダイレクトしてます。


     

    reyさんがひっかかるのを、ただひたすら待つ

     
    ただ、ひたすらに、待ちます
    待ち方

    1. tail -f /var/log/nginx/birthday.topotal.com-access.log
    2. iptables -t mangle -nvL PREROUTING

    2013/01/17 13:00頃、reyさんのアクセスを確認。おそらく、喜び庭駆けまわってくれた*5と思いますw
    Facebookにもその喜びを投稿してくれましたw
     
    めでたしめでたし


    最後に

     

    スクリーンショット 2013-12-11 16.51.13

    さわださん、素敵なサイトを作ってくれてありがとう (* ゚ω゚ *)!!
    よしおさん、動画作成に協力してくれてありがとう (* ゚ω゚ *)!!

    作成した誕生日サイトは->こちら<-  


    1. HTTPSも引きずり込めばよかったのですが、全部見れないのはいくらなんでもかわいそうな気がしたのでやめました。 []
    2. reyさんちのルータ上でarpコマンドを叩いて確認した。 []
    3. 始めからここだけ説明すればいいとかいうツッコミはなしで []
    4. 誕生日サイトへのトリガーとなるパケットにreyさんの誕生日(%Y%m%d)をMARK値として刻み込む仕様。iptables -nvL でみると、MARK値が16進数に変換されてて微妙 []
    5. 童謡「雪やこんこ あられやこんこ」より: 雪に興奮する犬の様子。今回は、祝福サイトが雪、reyさんが犬 と例えた []