@matsumotory さん謹製の mod_mruby と mruby-geoip で地理情報を使ってアクセス制御してみた。
※ 本記事は mod_mrubyとmruby-geoipを使って地理情報でアクセス制御 にも記載してます。
スペック
# more /etc/redhat-release
CentOS Linux release 7.1.1503 (Core)
# uname -r
3.10.0-229.7.2.el7.x86_64
apacheをインストール
yum -y install httpd httpd-devel
必要パッケージをインストール
yum -y install git vim-enhanced ruby gcc GeoIP-devel GeoIP-update
パッケージの説明をかるく書いておく。
Package | Description |
---|---|
git | mod_mrubyをgitリポジトリから取得するため |
vim-enhanced | なくてもよい |
ruby | mod_mruby入れるのに必要 |
gcc | mod_mrubyコンパイルするために必要 |
GeoIP-devel | mruby-geoipコンパイルするために必要 |
GeoIP-update | GeoIPデータベースのアップデートするツール |
mod_mrubyをcloneする。
git clone git://github.com/matsumoto-r/mod_mruby.git
build_config.rbを修正
今回は、mruby-geoip を導入したので、入れた。さらにredis,vedisは使わないのでコメントに。
# diff -ur build_config.rb_backup build_config.rb
--- build_config.rb_backup 2015-07-03 13:32:27.017667686 +0900
+++ build_config.rb 2015-07-03 13:37:33.756710824 +0900
@@ -15,13 +15,14 @@
conf.gem :github => 'iij/mruby-pack'
conf.gem :github => 'mattn/mruby-json'
conf.gem :github => 'mattn/mruby-onig-regexp'
- conf.gem :github => 'matsumoto-r/mruby-redis'
- conf.gem :github => 'matsumoto-r/mruby-vedis'
+ #conf.gem :github => 'matsumoto-r/mruby-redis'
+ #conf.gem :github => 'matsumoto-r/mruby-vedis'
conf.gem :github => 'matsumoto-r/mruby-sleep'
conf.gem :github => 'matsumoto-r/mruby-userdata'
conf.gem :github => 'matsumoto-r/mruby-uname'
conf.gem :github => 'matsumoto-r/mruby-cache'
conf.gem :github => 'matsumoto-r/mruby-mutex'
+ conf.gem :github => 'matsumoto-r/mruby-geoip'
# mod_mruby extended class
conf.gem '../mrbgems/mod_mruby_mrblib'
ビルドしよう!
sh build.sh
正常にビルドが終わると、以下のように successful
と表示される。
*** 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
apacheに組み込む。
make install
実行結果はこちら
# make install
/usr/bin/apxs -i -a -n 'mruby' /home/atani/mod_mruby/src/.libs/mod_mruby.so
/usr/lib64/httpd/build/instdso.sh SH_LIBTOOL='/usr/lib64/apr-1/build/libtool' /home/atani/mod_mruby/src/.libs/mod_mruby.so /usr/lib64/httpd/modules
/usr/lib64/apr-1/build/libtool --mode=install install /home/atani/mod_mruby/src/.libs/mod_mruby.so /usr/lib64/httpd/modules/
libtool: install: install /home/atani/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]
GeoIPのデータベースを取得する。
初期のGeoIPデータは古いので、geoipupdate
で最新のデータを取得する。
ll /usr/share/GeoIP/
total 17696
lrwxrwxrwx. 1 root root 17 Jul 3 13:56 GeoIP.dat -> GeoIP-initial.dat
-rw-r--r--. 1 root root 1362244 Jun 10 2014 GeoIP-initial.dat
# geoipupdate
/usr/share/GeoIP/GeoLiteCountry.dat can't be opened, proceeding to download database
Updating /usr/share/GeoIP/GeoLiteCountry.dat
Updated database
/usr/share/GeoIP/GeoLiteCity.dat can't be opened, proceeding to download database
Updating /usr/share/GeoIP/GeoLiteCity.dat
Updated database
mruby-geoipの設定
ここからはmruby-geoipを利用するための設定をしよう。
mkdir /etc/httpd/hook
httpd.conf
mrubyChildInitMiddle /etc/httpd/conf.d/geo_init.rb
<Location />
mrubyAccessCheckerLast /etc/httpd/conf.d/geo_check.rb
mrubyHandlerMiddle /etc/httpd/conf.d/geo_handler.rb
</Location>
※ geo_check.rb
を mrubyAccessCheckerMiddle
で処理させようとすると地理情報の値がうまく値が取れなかった。
/etc/httpd/conf.d/geo_init.rb
Userdata.new("geoip_#{Process.pid}").geoip = GeoIP.new("/usr/share/GeoIP/GeoLiteCity.dat")
/etc/httpd/conf.d/geo_check.rb
Server = get_server_class
geoip = Userdata.new("geoip_#{Process.pid}").geoip
geoip.record_by_addr Server::Connection.new.remote_ip
if geoip.country_code != "JP"
Server.return Server::HTTP_FORBIDDEN
end
/etc/httpd/conf.d/geo_handler.rb
Server = get_server_class
r = Server::Request.new
c = Server::Connection.new
geoip = Userdata.new("geoip_#{Process.pid}").geoip
r.content_type = "text/html"
Server.echo "<HEAD><TITLE>your information</TITLE></HEAD><BODY>"
Server.echo "Your IP Address is #{c.remote_ip}<br>"
Server.echo "Your Country Code is #{geoip.country_code}<br>"
Server.echo "Your city is #{geoip.city}<br>"
Server.echo "Your region is #{geoip.region}<br>"
Server.echo "your are at <a href='http://maps.google.com/maps?q=#{geoip.latitude},#{geoip.longitude}'>this pin</a><br>"
Server.echo "</BODY>"
apacheを起動
-
configtestを行い、問題なければ起動。
/usr/sbin/apachectl configtest
Syntax OK
/usr/sbin/apachectl start
- systemdで起動する場合は、httpdにUNIT登録したあと、起動する。
systemctl enable httpd.service
ln -s '/usr/lib/systemd/system/httpd.service' '/etc/systemd/system/multi-user.target.wants/httpd.service'
systemctl start httpd.service
実際にアクセスしてみると国コードなど取得できることを確認!
## 備考
`gcc` が入ってないと以下のようなエラーとなる。
Command Failed: [gcc -g -std=gnu99 -O3 -Wall -Werror-implicit-function-declaration -Wdeclaration-after-statement -Wwrite-strings -fPIC -g3 -Wall -Werror-implicit-function-declaration -I"/home/atani/mod_mruby/mruby/include" -MMD -o "/home/atani/mod_mruby/mruby/build/host/src/array.o" -c "/home/atani/mod_mruby/mruby/src/array.c"]
`bison` が入ってないと以下のようなエラーとなる。
sh: bison: command not found
sh: bison: command not found
rake aborted!
Command Failed: [bison -o "/home/atani/mod_mruby/mruby/build/host/mrbgems/mruby-compiler/core/y.tab.c" "/home/atani/mod_mruby/mruby/mrbgems/mruby-compiler/core/parse.y"]
`openssl-devel` が入ってないと以下のようなエラーとなる。
/home/atani/mod_mruby/mruby/build/mrbgems/mruby-digest/src/digest.c:16:25: fatal error: openssl/evp.h: No such file or directory
#include
^
compilation terminated.
/home/atani/mod_mruby/mruby/build/mrbgems/mruby-digest/src/digest.c:16:25: fatal error: openssl/evp.h: No such file or directory
#include
^
compilation terminated.
rake aborted!
Command Failed: [gcc -g -std=gnu99 -O3 -Wall -Werror-implicit-function-declaration -Wdeclaration-after-statement -Wwrite-strings -fPIC -g3 -Wall -Werror-implicit-function-declaration -DMRBGEM_MRUBY_DIGEST_VERSION=0.0.0 -I"/home/atani/mod_mruby/mruby/include" -MMD -o "/home/atani/mod_mruby/mruby/build/host/mrbgems/mruby-digest/src/digest.o" -c "/home/atani/mod_mruby/mruby/build/mrbgems/mruby-digest/src/digest.c"]
`GeoIP-devel` が入ってないと以下のようなエラーとなる。
/home/atani/mod_mruby/mruby/build/mrbgems/mruby-geoip/src/mrb_geoip.c:12:19: fatal error: GeoIP.h: No such file or directory
#include
^
compilation terminated.
/home/atani/mod_mruby/mruby/build/mrbgems/mruby-geoip/src/mrb_geoip.c:12:19: fatal error: GeoIP.h: No such file or directory
#include
^
compilation terminated.
rake aborted!
Command Failed: [gcc -g -std=gnu99 -O3 -Wall -Werror-implicit-function-declaration -Wdeclaration-after-statement -Wwrite-strings -fPIC -g3 -Wall -Werror-implicit-function-declaration -DMRBGEM_MRUBY_GEOIP_VERSION=0.0.1 -I"/home/atani/mod_mruby/mruby/include" -MMD -o "/home/atani/mod_mruby/mruby/build/host/mrbgems/mruby-geoip/src/mrb_geoip.o" -c "/home/atani/mod_mruby/mruby/build/mrbgems/mruby-geoip/src/mrb_geoip.c"]
`httpd-devel` が入ってないと以下のようなエラーとなる。
--with-mruby: https://github.com/mruby/mruby.git will be used.
checking for rake1.9.1... no
checking for rake... no
checking for ruby1.9.1... no
checking for ruby... /usr/bin/ruby
checking for apxs2... no
checking for apxs... no
configure: error: neither apxs2 or apxs not found.
---
## 参照URL
- [mod_mruby を Amazon EC2、Apache2.4 へ導入する](http://qiita.com/hkusu/items/ca8622c83b0bfc2cac72)
- [mod_mrubyインストール後入門](http://qiita.com/matsumotory/items/7121d6cce728125e5ce2)
- [地理情報を使ってmod_mrubyとngx_mrubyでプログラマブルにアクセス制御](http://hb.matsumoto-r.jp/entry/2014/12/13/004226)