今回はmod_mrubyを使ってApacheと戯れたいと思います。
mod_mrubyとは、ペパボのMATSUMOTO Ryosuke氏が作成されたApacheのモジュールで、Rubyを使ってApacheのモジュールが作れるという代物のようです。
「ApacheモジュールをRubyで効率良く実装するためのApacheモジュール。」とのことです。
Apacheのモジュールを作る!なんて敷居が高くて全く手を出したことも考えたこともなかったわけですが、見ながらちょこっと弄くるくらいなら出来そう?
ってことで、やってみますか。
まずは、それどこ情報?どこ情報よー?(・∀・)
人間とウェブの未来 mod_mrubyインストール後入門
200万 Webサイトを支える ロリポップ!と mruby
上のリンクからの情報です。
最初に書いておきますが、新しい試みはしていません!スパーン
参考サイトを見ながら動かしながら、ワクテカしながら挙動を見てるだけです。
参考サイト一覧
Githubのページ matsumoto-r/mod_mruby
Apacheによるバーチャルホスト構築レシピ mod_mruby編
ようへいの日々精進XP mod_mruby を試してみる
Qiita cs_sonar Apacheのmod_vhost_aliasでログをバーチャルホスト単位で分割できない問題をmod_mrubyで解決する
そいではまずはインストールからいきまっする。
サーバーはこないだSuexec環境のテストに使っていたちょっと古いCentOS6を使います。
この事が後に重大な問題に!
関連記事
それもいいんじゃないでSKY
Rubyはrbenvで最新のバージョンをインストールしました。
あとbisonとhiredis-develをインストール。
わりと重要なのがSELINUXを無効化する。
無効化しておかないとハマるぜ!m9(^_^)
っと、ここでハマったのが10行前で言ってた重大な問題でした。
終。
続き。
$ git clone git://github.com/matsumoto-r/mod_mruby.git $ cd mod_mruby $ sh build.sh *** Warning: Linking the shared library src/mod_mruby.la against the *** static library /root/mod_mruby/mruby/build/host/mrbgems/mruby-redis/hiredis/lib/libhiredis.a is not portable! *** Warning: Linking the shared library src/mod_mruby.la against the *** static library ./mruby/build/host/lib/libmruby.a is not portable! mod_mruby building ... Done build.sh ... successful
# make install /usr/sbin/apxs -i -a -n 'mruby' /root/mod_mruby/src/.libs/mod_mruby.so /usr/lib64/httpd/build/instdso.sh SH_LIBTOOL='/usr/lib64/apr-1/build/libtool' /root/mod_mruby/src/.libs/mod_mruby.so /usr/lib64/httpd/modules /usr/lib64/apr-1/build/libtool --mode=install cp /root/mod_mruby/src/.libs/mod_mruby.so /usr/lib64/httpd/modules/ libtool: install: cp /root/mod_mruby/src/.libs/mod_mruby.so /usr/lib64/httpd/modules/mod_mruby.so Warning! dlname not found in /usr/lib64/httpd/modules/mod_mruby.so. Assuming installing a .so rather than a libtool archive. chmod 755 /usr/lib64/httpd/modules/mod_mruby.so [activating module `mruby' in /etc/httpd/conf/httpd.conf]
これでOKだと思われ。インストールじたいはとても簡単です。
# grep -R mruby /etc/httpd/conf/ /etc/httpd/conf/httpd.conf:LoadModule mruby_module /usr/lib64/httpd/modules/mod_mruby.so
とりあえず普通にバーチャルホストの設定をします。
その前にMacから名前解決できるようにしとく。
とりあえず3つくらいでいいかしらっと。
$ vim /private/etc/hosts 192.168.24.81 example.com 192.168.24.81 take.example.com 192.168.24.81 jiro.example.com 192.168.24.81 sayo.example.com
httpd.confの編集。
<VirtualHost *:80> DocumentRoot /home/take/public_html ServerName take.example.com <Directory /home/*/public_html> Options All AllowOverride All AddHandler cgi-script .cgi .pl .php </Directory> </VirtualHost> <VirtualHost *:80> DocumentRoot /home/jiro/public_html ServerName jiro.example.com <Directory /home/*/public_html> Options All AllowOverride All AddHandler cgi-script .cgi .pl .php </Directory> </VirtualHost>
これでtakeとjiroはローカル環境からは見れるようになったはずです。
次いでmrubyでバーチャルホストの設定をしてみます。
httpd.confに追加します。
mrubyTranslateNameMiddle /etc/httpd/conf.d/mruby/vhost.rb
設定ファイルを作成。
vim /etc/httpd/conf.d/mruby/vhost.rb
#/usr/local/bin/ruby # coding: utf-8 r = Apache::Request.new if ["sayo.example.com"].include?(r.hostname) then r.filename = "/home/sayo/html/" + r.uri Apache::return(Apache::OK) else Apache::return(Apache::DECLINED) end
これで3つのドメインで確認ができるようになったと思います。
mrubyの記述の仕方によってはリクエスト毎にコンパイルされるというケースもあるみたいなので、サーバーへの負荷も変わってくると思われます。
適材適所でいこうぜよ。
キャッシュさせておくということもできるようです。
続いてはエラーログをバーチャルホスト毎に取るってのをやってみます。
httpd.confに追加。
mrubyInsertFilterMiddle /etc/httpd/conf.d/mruby/vhost-lo
設定ファイルの作成。
#/usr/local/bin/ruby # coding: utf-8 r = Apache::Request.new unless Dir.exist?("/var/log/httpd/" + r.hostname) then Dir.mkdir("/var/log/httpd/" + r.hostname , 0705) end r.error_log Apache::APLOG_NOTICE, "r.error_log" r.error_log_into "/var/log/httpd/" + r.hostname + "/error_log" Apache::return(Apache::OK)
この後に各ドメインにアクセスすると、以下のファイルができました。
気をつけるべくところはやっぱりパーミッションや所有者情報かなと。
# ls -l /var/log/httpd/ | grep "com$" drwxr-xr-x. 2 apache apache 4096 7月 16 09:37 2015 sayo.example.com drwx---r-x. 2 apache apache 4096 7月 16 09:39 2015 take.example.com drwx---r-x. 2 apache apache 4096 7月 16 09:39 2015 jiro.example.com
存在しないファイルへアクセスしてエラーを吐かせます。
# tail /var/log/httpd/take.example.com/error_log [Thu Jul 16 09:41:15 2015] [error] [client 192.168.24.56] File does not exist: /home/take/public_html/ijigj [Thu Jul 16 09:41:16 2015] [error] [client 192.168.24.56] File does not exist: /home/take/public_html/ijigj [Thu Jul 16 09:41:16 2015] [error] [client 192.168.24.56] File does not exist: /home/take/public_html/ijigj
こんな感じだと成功してます。
では最後にアクセスログを生成するっていう事をやってみます。
httpd.confに追加します。
mrubyInsertFilterFirst /var/www/request_dumper.rb
設定ファイルです。
vim /var/www/request_dumper.rb
LOG_FILE = "/var/log/httpd/request.txt" MAX_LEN = 1024 IN_ONE_LINE = false def format_time(time) sprintf("%04d-%02d-%02d %02d:%02d:%02d", time.year, time.month, time.day, time.hour, time.min, time.sec ) end def log_write(r) File.open(LOG_FILE, "a") do |fh| body = r.body.to_s[0...MAX_LEN] if r.headers_in["Content-Type"].to_s[0,9] == "multipart" body = body.inspect end headers_str = r.headers_in.all.map{|k, v| "#{k}: #{v}"}.join("\n") record = ["[#{format_time(Time.now)}]", "#{r.the_request}\n#{headers_str}", "#{body}"] if IN_ONE_LINE record[1] = record[1].inspect fh.write(record.join(' ') + "\n") else fh.write('='*80 + "\n" + record.join("\n\n") + "\n") end end end r = Apache::Request.new if r.method_number == Apache::M_GET || r.method_number == Apache::M_POST log_write(r) end
アクセスしてみるとこんなログが出来ます。
================================================================================ [2015-07-16 10:09:08] POST / HTTP/1.1 Host: sayo.example.com Connection: keep-alive Content-Length: 0 CSP: active Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36 hoge: null Content-Type: application/x-www-form-urlencoded Accept: */* Accept-Encoding: gzip, deflate Accept-Language: ja,en-US;q=0.8,en;q=0.6 ================================================================================ [2015-07-16 10:09:20] POST / HTTP/1.1 Host: take.example.com Connection: keep-alive Content-Length: 0 CSP: active Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36 hoge: null Content-Type: application/x-www-form-urlencoded Accept: */* Accept-Encoding: gzip, deflate Accept-Language: ja,en-US;q=0.8,en;q=0.6
ほぼほぼコピーして環境を合わせてという作業でしたがどうでしたでしょうか。
ぼんやり〜〜っとですが、mod_mrubyがどういうものなのかってのはじわじわと感じてきました。
harasouさんのスライドでみたようなプロセス制限やDoS対策とかも時間があれば挑戦してみたいと思います。
では、今日はこの辺で。
分からないと思いますが時刻の同期をとってないので、タイムスタンプがめちゃくちゃです・・。