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

January 17, 2013

birthday_005c

Topotal メンバーの誕生日

Topotal Project メンバーの誕生日はろくなことが起きないのは毎年恒例のこと。 今までは、サーバHackが主流でした。SSHログインすると、事前に書き換えられた.bash_rcによりお祝いの文章が垂れ流さるケースなどなど。。。

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

戦略パート: お誕生日を祝うための作戦

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

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

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

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

  1. rrreeeyyy さんが なんらかのサイトにアクセスする
  2. ルータの設定に引っかかる
  3. 誕生日サイトが表示される。

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

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

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

また、設定をする上で以下のポリシーを守ることにしました。

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

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

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

作業パート: 3フェーズを順に実装していく

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

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

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

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

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

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

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

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

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

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

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

どうやってMACアドレスを調べようか迷いました。そういえば、以前rrreeeyyyさんが我が家(YAKATA)に来た時にDHCPを利用してたことを思い出しました。 /var/log/dhcpd.log を適当なホストネームで検索して探しました。

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

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

Jan  9 23:53:03 bonjour-01 dhcpd: DHCPACK on 

<ipアドレス> to <macアドレス> (<rrreeeyyyさんのpcのホストネーム>) via br0

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

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

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

iptables の最終的な設定

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

mangleテーブル

  • PREROUTING チェイン
    iptables -t mangle -I PREROUTING 1 -i br0 -m mac --mac-source <rrreeeyyyさん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の値(パケットにrrreeeyyyさんの誕生日(%Y%m%d)をMARK値として刻み込む仕様)、誕生日な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. rrreeeyyyさんちのiptablesで、80番PortへのパケットをDNATし、topotal.com:13117(自サーバへ)
  2. 自サーバのiptablesで 13117宛のパケットを webサーバの13117へDNAT
  3. topotal.com:13117のアクセスを Nginx で birthday.topotal.com:80 へリダイレクト

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

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

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

ただ、ひたすらに、待ちます。待ち方はこちら。

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

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

めでたしめでたし

最後に

19cb7fc1c92dea4582248e36cc4e7c17

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

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


Profile picture

Written by Narimichi Takamura (@nari_ex) who works at Topotal as CEO. He love engineering and fighting game.