RequestBin をインストールしてみる
発行された URL に対して送信された HTTP リクエストの内容を確認することが出来る Webサービス RequestBin ですが、ソースコードも MIT ライセンスで公開されている ようなので、今回は自前のサーバに立ててみました。
構築した環境は CentOS 6.5 x86_64 になります。
Python 2.7 のインストール
最初に CentOS 6 にデフォルトで入っていた Python 2.6.6 で試してみたのですが、インストールは出来たものの上手く動作してくれませんでした。
そのため、まずは Python 2.7 を入れるところから始めました。
まずはビルドに必要なライブラリをインストール。
# yum groupinstall -y "Development tools" # yum install -y zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel
必須ではないですが、ソースコードからインストールするので綺麗に消せるよう EPEL から paco も入れておきます。
# rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6 # yum install -y http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm # yum install -y paco
2.7.6 をダウンロードして configure します。
# cd /usr/local/src # wget http://www.python.org/ftp/python/2.7.6/Python-2.7.6.tgz # tar xzf Python-2.7.6.tgz # cd Python-2.7.6 # ./configure --prefix=/usr/local
SSL サポートを有効にするためここで一手間かけます。
まずはインストールされている OpenSSL の場所を確認。
# find / -name openssl
/usr/lib64/openssl
/usr/bin/openssl
/usr/include/openssl
/etc/pki/ca-trust/extracted/openssl
Setup ファイルを編集します。
# vi ./Modules/Setup
218 行目辺りからのコメントアウトを解除して、「SSL=/usr/local/ssl」のところを先ほど調べた OpenSSL インストールパス(/usr)に修正します。
218 SSL=/usr 219 _ssl _ssl.c \ 220 -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \ 221 -L$(SSL)/lib -lssl -lcrypto
修正したら make して make altinstall します。
paco 経由で実行するのを忘れずに。
# make # paco -D make altinstall
バージョンを確認します。
# python2.7 -V
Python 2.7.6
以下を実行してエラーが出なければ SSL サポートが有効になっています。
# python2.7 -c "import ssl"
setuptools をインストールしておきます。
# cd /usr/local/src # wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py # python2.7 ez_setup.py # easy_install-2.7 --version setuptools 3.3
pip もインストールしておきます。
# easy_install-2.7 pip # pip2.7 --version pip 1.5.4 from /usr/local/lib/python2.7/site-packages/pip-1.5.4-py2.7.egg (python 2.7)
これで Python 2.7 環境の準備ができました。
RequestBin のインストール
libevent-devel が必要なのでインストールしておきます。
# yum install -y libevent-devel
/opt 以下に requestbin を clone し、pip で必要なライブラリをインストールします。
# cd /opt/ # git clone git://github.com/Runscope/requestbin.git # cd requestbin/ # pip install -r requirements.txt
RequestBin はデフォルトではメモリ上にデータを保持しますが、今回は Redis を使うようにしたいと思います。
ここでは Redis インストール用に Remi リポジトリを追加しました。
# rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi # yum install -y http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
リポジトリを追加したら Redis をインストールして起動しておきます。
# yum --enablerepo=remi install -y redis # echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf # sysctl -p # service redis start # chkconfig redis on # chkconfig --list redis redis 0:off 1:off 2:on 3:on 4:on 5:on 6:off
RequestBin の設定ファイルを編集。
# vi requestbin/config.py
ROOT_URL の値を環境に合わせて修正します。
ROOT_URL = "http://192.0.2.1:4000"
STORAGE_BACKEND の値を RedisStorage を変更します。
STORAGE_BACKEND = "requestbin.storage.redis.RedisStorage"
これでインストール自体は完了ですが、起動・終了を簡単にするため、Supervisor で管理するようにしてみます。
Supervisor のインストール
easy_install コマンドから supervisor をインストールします。
# easy_install supervisor
設定ファイルを作成して編集。
# echo_supervisord_conf > /etc/supervisord.conf # vi /etc/supervisord.conf
ファイル末尾に以下の追記します。
[include] files = /etc/supervisord.d/*.conf
指定したディレクトリを実際に作成。
# mkdir /etc/supervisord.d
Supervisor 用の起動スクリプトを配置します。
# cd /usr/local/src/ # git clone git://github.com/Supervisor/initscripts.git # cp initscripts/redhat-init-jkoppe /etc/init.d/supervisord # cp initscripts/redhat-sysconfig-jkoppe /etc/sysconfig/supervisord # chkconfig --add supervisord
このままだと supervisord コマンドのパスが若干異なるため上手く動かないので、起動スクリプトを修正します。
# vi /etc/init.d/supervisord
スクリプト内のコマンドのパスを以下のように修正します。
- /usr/bin/supervisord を /usr/local/bin/supervisord に変更。
- /usr/bin/supervisorctl を /usr/local/bin/supervisorctl に変更。
次に以下のファイルを編集します。
# vi /etc/sysconfig/supervisord
PIDFILE のパスを /etc/supervisord.conf の内容に合わせて以下のように修正します。
PIDFILE=/tmp/supervisord.pid
これで Supervisor 自体の準備はできたので、いよいよ RequestBin 用の設定ファイルを作成します。
# vi /etc/supervisord.d/requestbin.conf
以下のような内容にしました。
[program:requestbin] directory=/opt/requestbin command=/usr/local/bin/python2.7 web.py user=requestbin autostart=true autorestart=true redirect_stderr=true stdout_logfile=/var/log/requestbin.log stopasgroup=true
RequestBin の場合、「stopasgroup=true」が無いと上手くプロセスを終了できないようなので注意してください。
指定した起動用ユーザを作成。
# useradd -s /sbin/nologin -M requestbin
supervisord サービスを起動します。
自動的に requestbin も起動したことがわかります。
# service supervisord start
Starting supervisord:
requestbin STARTING
これでブラウザで対象サーバのポート 4000 番にアクセスすると RequestBin を使用することができます。
Nginx の設定
ここまででも問題なく使用できるのですが、毎回ポート番号を指定してアクセスするのも面倒なので、Nginx 経由でアクセスするようにしてみます。
まずは Nginx をインストール。
# yum install -y http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm # yum install -y nginx
設定ファイルを編集します。
# vi /etc/nginx/conf.d/default.conf
location / の設定を以下のように変更しました。
location / { proxy_pass http://localhost:4000; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }
Nginx を起動します。
# service nginx start
これでポート番号を指定しなくても RequestBin へアクセスできるようになります。
Webサービスとして公開されているし、Heroku を使うならもっと簡単に動かせるようですが、外部に公開されていない環境に自前で一つ立てておくと気軽に使えるのでそれはそれで便利なんじゃないかなー、と思います。
参考サイト
How to install Python 2.7 and Python 3.3 on CentOS 6 | Too Much Data
http://toomuchdata.com/2014/02/16/how-to-install-python-on-centos/
Codrspace - Run RequestBin locally to debug restful APIs by glenbot
http://codrspace.com/glenbot/run-requestbin-locally-to-debug-restful-apis/
GracefulExit - Running Flask App and Celery with Supervisor on Vagrant
http://papaeye.tumblr.com/post/76624602909/running-flask-app-and-celery-with-supervisor-on-vagrant
Ruby から Sentry を使う
前回インストールした Sentry に Ruby からイベントを登録してみます。
Ruby から Sentry を使うには、プロジェクトの設定画面の Ruby のところにも書いてあるように sentry-raven という gem を使います。
getsentry/raven-ruby
https://github.com/getsentry/raven-ruby
インストール
gem から入れる場合は以下。
# gem install sentry-raven --no-rdoc --no-ri
bundler から入れる場合は Gemfile を作成。
# bundle init # vi Gemfile
以下を追記します。
gem "sentry-raven"
bundle install します。
# bundle install
Ruby から使う
以下のような Ruby コードを記述します。
require 'raven' Raven.configure do |config| config.dsn = 'http://6e874f2d864c4925b2049069f5e8af86:04756c0af5154d69aee463018cef97c0@192.0.2.1/2' end Raven.capture do 1 / 0 end
config.dsn には Sentry 上で [設定]-[APIキー] のところに表示されている値を使用します。
実行してみます。
% ruby sentry01.rb I, [2014-03-23T17:08:18.060929 #10369] INFO -- : ** [Raven] Raven 0.7.1 ready to catch errors D, [2014-03-23T17:08:18.062539 #10369] DEBUG -- : ** [Raven] Sending event 18180a944cdd445799d8de694e7691e8 to Sentry D, [2014-03-23T17:08:18.068214 #10369] DEBUG -- : ** [Raven] Raven HTTP Transport connecting to http://192.0.2.1 sentry-ex01.rb:8:in `/': divided by 0 (ZeroDivisionError) from sentry-ex01.rb:8:in `block in <main>' from /home/akishin/.anyenv/envs/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/sentry-raven-0.7.1/lib/raven.rb:89:in `call' from /home/akishin/.anyenv/envs/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/sentry-raven-0.7.1/lib/raven.rb:89:in `capture' from sentry-ex01.rb:7:in `<main>'
例外が発生しました。
Raven.capture に指定したブロックの内部で例外が発生すると自動的に Sentry に通知されます。
実行後に Sentry 上ストリームを見ると以下のようにエラーが通知されているはずです。
また、例外を自分で処理した上で通知を行いたい、という場合には capture_exception が使用できます。
begin raise ArgumentError.new("test") rescue ArgumentError => e Raven.capture_exception(e) end
例外ではない、任意のイベントを通知したい場合には capture_message を使用します。
Raven.capture_message("test event", { level: 'debug', logger: 'debug', extra: { foo: "123", bar: "abc" }, })
Rails から使う
Rails から使う場合は、まずは作成した Rails プロジェクトの Gemfile に sentry-raven を追記して bundle install します。
インストールすると以下の rake タスクが追加されます。
% bundle exec rake -T | grep raven rake raven:test[dsn] # Send a test event to the remote Sentry server
このタスクに Sentry の画面で確認した dsn を指定することで Sentry の動作確認を行う事ができます。
実行して以下のような感じで event ID が取得できていれば Sentry サーバとの通信は成功しています。
% bundle exec rake "raven:test[http://6e874f2d864c4925b2049069f5e8af86:04756c0af5154d69aee463018cef97c0@192.0.2.1/2]" Client configuration: -> server: http://192.0.2.1 -> project_id: 2 -> public_key: 6e874f2d864c4925b2049069f5e8af86 -> secret_key: 04756c0af5154d69aee463018cef97c0 Sending a test event: -> event ID: e09165be7fb741a18ebe214139430c39 Done!
Sentry 画面のストリームからもこのテストイベントを確認することが出来ます。
テストが問題なければ、Rails から sentry-raven を使うための設定ファイルを作成します。
% vi config/initializers/raven.rb
以下のような内容を記述します。
Raven-Ruby はデフォルトでは development 環境の時にイベントの送信を行わないので、ここでは確認のため config.environments で対象に含めるよう設定しています。
Raven.configure do |config| config.dsn = 'http://6e874f2d864c4925b2049069f5e8af86:04756c0af5154d69aee463018cef97c0@192.0.2.1/2' config.environments = %w[ development ] end
これで設定は完了です。
Rails で使う場合はこれだけで処理されなかった例外が全て Sentry へ通知されるようになります。
Controller 内などで適当に例外を投げてみれば Sentry へ通知される事が確認できると思います。
まとめ
エラー管理ツールについては実際に試してみるまでは「ログ見ればいいじゃん」などと思っていましたが、使ってみると本番環境でしか発生しなかったり、たまにしか発生しなかったりするようなエラーまでその発生箇所や発生頻度を一元管理することができるようになり、その有用性が理解できました。
また、Sentry ではエラーだけでなく、任意のイベントを管理する事もできるため、どの処理がどれくらい呼ばれているか、などといった事も簡単に調べる事ができるので、プロダクトの品質向上に一役買ってくれそうです。
ちなみに、他のサービスなどとの連携についてはプラグイン方式を取っているようです。
対応しているサービスは以下のページの [3rd Party Extensions] にまとまっています。
Plugins
https://sentry.readthedocs.org/en/latest/plugins/index.html
これらのサービスと連携させる事でより効果的に活用することができそうです。
Sentry をインストール
商用サービスもあるオープンソースのイベントログ収集ツール Sentry をインストールしてみたのでメモ。
getsentry/sentry
https://github.com/getsentry/sentry
Airbrake やオープンソースの Errbit 辺りと同じ系統のサービスな感じです。
インストールした環境は CentOS 6.5 x86_64 です。
MySQL のインストール
まずは MySQL をインストール。
5.1 で試したら途中 sentry upgrade 実行時にエラーになったので、公式リポジトリから 5.6 を入れました。
# yum install -y http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm # yum install -y mysql-community-server mysql-community-devel
設定ファイルを変更。
# vi /etc/my.cnf
mysqld セクションに以下を追記します。
[mysqld] character-set-server = utf8
mysqld を起動。
# service mysqld start
起動したら mysql_secure_installation を実行し root パスワードの設定などを行っておきます。
# mysql_secure_installation
mysql_secure_installation の実行が終わったら設定したパスワードでログインします。
# mysql -uroot -p
sentry 用の DB とユーザを作成します。
パスワード等は適宜変更して下さい。
mysql> CREATE DATABASE IF NOT EXISTS sentry DEFAULT CHARACTER SET utf8; mysql> GRANT ALL PRIVILEGES ON sentry.* TO sentry@localhost IDENTIFIED BY 'sentry'; mysql> FLUSH PRIVILEGES; mysql> exit
Sentry のインストール
setuptools をインストール。
# yum install -y python-devel python-setuptools
easy_install コマンドを使って Sentry をインストールします。
# easy_install -UZ sentry[mysql]
インストール完了までそれなりに時間がかかるので、しばらく待ちます。
インストールが完了したら、以下のコマンドを実行して設定ファイルを作成。
# sentry init /etc/sentry.conf.py
作成した設定ファイルを編集します。
# vi /etc/sentry.conf.py
以下の箇所を先ほど作成したデータベース接続情報に変更します。
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'sentry', 'USER': 'sentry', 'PASSWORD': 'sentry', 'HOST': 'localhost', 'PORT': '3306' } }
また、設定ファイル内の SENTRY_URL_PREFIX の値をインストールしたサーバのホスト名または IP アドレスに変更します。
#SENTRY_URL_PREFIX = 'http://sentry.example.com' # No trailing slash! SENTRY_URL_PREFIX = 'http://192.0.2.1' # No trailing slash!
設定ファイルを保存したら DB のマイグレーションなどを実行する upgrade コマンドを作成した設定ファイルを指定して実行します。
# sentry --config=/etc/sentry.conf.py upgrade
createsuperuser サブコマンドを実行して管理用のユーザを作成します。
# sentry --config=/etc/sentry.conf.py createsuperuser !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! SENTRY_URL_PREFIX is not configured !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Username: akishin Email address: akishin@example.com Password: Password (again): Superuser created successfully.
これでインストールは完了です。
以下のコマンドでサーバを起動するとポート 9000 番で Sentry が起動します。
# sentry --config=/etc/sentry.conf.py start
軽く試すだけならこのままでも問題ないと思いますが、このままだと起動・終了が面倒なので、supervisord でプロセスを管理するよう設定します。
起動が確認できたら一旦 Ctrl-C などで sentry サーバを停止しておきます。
sentry を supervisor で管理する
以下のコマンドで supervisor をインストールします。
# easy_install supervisor
設定ファイルを作成。
# echo_supervisord_conf > /etc/supervisord.conf
作成した設定ファイルを編集します。
# vi /etc/supervisord.conf
ファイル末尾の以下の行をアンコメントし、ディレクトリパスを修正します。
[include] files = /etc/supervisord.d/*.conf
設定ファイルで指定したディレクトリを作成。
# mkdir /etc/supervisord.d
supervisor 用の起動スクリプトを clone して設置します。
# cd /usr/local/src/ # git clone git://github.com/Supervisor/initscripts.git # cp initscripts/redhat-init-jkoppe /etc/init.d/supervisord # cp initscripts/redhat-sysconfig-jkoppe /etc/sysconfig/supervisord # chkconfig --add supervisord
このままではデフォルトの設定ファイルと pid ファイルの場所が異なるので、以下を編集します。
# vi /etc/sysconfig/supervisord
ここでは /etc/supervisord.conf 側に合わせたので、以下のように変更しました。
#PIDFILE=/var/run/supervisord.pid PIDFILE=/tmp/supervisord.pid
これで supervisor の準備は出来たので、Sentry 用の設定ファイルを作成します。
# vi /etc/supervisord.d/sentry.conf
以下のような内容にしました。
[program:sentry-web] command=/usr/bin/sentry --config=/etc/sentry.conf.py start http user=sentry autostart=true autorestart=true redirect_stderr=true stdout_logfile=/var/log/sentry-web.log
指定した起動用ユーザを作成します。
# useradd -s /sbin/nologin -M sentry
supervisord を起動します。
# service supervisord start
Starting supervisord:
sentry-web STARTING
これで supervisord 経由で sentory の起動・停止が出来るようになりました。
Nginx の設定
このままでは 9000 番ポートを指定してアクセスする必要があります。
80 番ポートでアクセスできるようにするため、Nginx 経由で Sentry にアクセスできるように設定します。
まずは Nginx をインストール。
# yum install -y http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm # yum install -y nginx
設定ファイルを編集します。
# vi /etc/nginx/conf.d/default.conf
location / の設定を以下のように変更しました。
location / { proxy_pass http://localhost:9000; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }
設定したら Nginx を起動します。
# service nginx start
以上で Sentry のインストールは完了です。
これでブラウザからポート 9000 を付けなくても Sentry にアクセス出来るようになります。
アクセスするとログイン画面が表示されるので、作成したユーザ情報でログインします。
ログインすると、初回ログインではチームの作成画面が表示されます。
チームを作成すると次はプロジェクト作成画面が表示されます。
プロジェクトを作成すると以下のような設定画面が表示されます。
商用サービスもあるだけあって大部分日本語化されているようです。
使い易そうですね。
ちょっと長くなったので、実際の使い方はまた次回にでもまとめたいと思います。
Packer で Vagrant の Box を作る
テンプレートを自分で作るのがどうにも面倒に感じてなかなか手を出せずにいた Packer ですが、調べてみたら結構テンプレートを公開してくれている方がいるようです。
misheska/basebox-packer
https://github.com/misheska/basebox-packer
shiguredo/packer-templates
https://github.com/shiguredo/packer-templates
hnakamur/my-packer-template-files
https://github.com/hnakamur/my-packer-template-files
nickchappell/packer-templates
https://github.com/nickchappell/packer-templates
という訳で今更ながら試してみました。
環境は Windows7 64bit です。
インストール
Downloads - Packer
http://www.packer.io/downloads.html
上記ページ内の [Windows] のところの [amd64] のリンクをクリックしてダウンロードします。
ダウンロードした際のバージョン 0.5.2 でした。
ダウンロードした 0.5.2_windows_amd64.zip を適当なフォルダに解凍し、フォルダを環境変数 PATH に追加します。
コマンドプロンプトから以下のようにバージョンが確認できればインストールは完了です。
>packer --version Packer v0.5.2
Box の作成
まずは適当なフォルダに移動して、テンプレートを clone します。
ここでは以下のテンプレートを使用させて頂きました。
misheska/basebox-packer
https://github.com/misheska/basebox-packer
>git clone git://github.com/misheska/basebox-packer.git
CentOS 6.5 を入れてみます。
CentOS 用のテンプレートのあるフォルダまで移動します。
>cd basebox-packer\template\centos\
配布されているテンプレートでは言語設定やキーボードなどが US になっているので、以下のファイルを変更します。
- basebox-packer\template\centos\http\ks.cfg
上記ファイルをエディタ等で開いて、以下の部分を変更しました。
lang ja_JP.UTF-8 keyboard jp106 timezone Asia/Tokyo
作成する Box のメモリやディスク容量などは以下のファイルで変更できます。
今回は以下のように変更しました。
・・・ "builders": [{ "vm_name": "centos65", "type": "vmware-iso", ・・・ "disk_size": 30420, "vmx_data": { "memsize": "1024", "numvcpus": "2", "cpuid.coresPerSocket": "1" } }, { "vm_name": "centos65", "type": "virtualbox-iso", ・・・ "disk_size": 30420, "vboxmanage": [ ["modifyvm", "{{.Name}}", "--memory", "1024"], ["modifyvm", "{{.Name}}", "--cpus", "2"] ] ・・・
もし VirtualBox 用の box しか作成しない、というような場合は変更するのは「"type": "virtualbox-iso"」側の該当箇所だけで OK なはずです。
準備が出来たので Box を作成します。
VirtualBox 用の box だけ作成すればいいので、「-only=virtualbox-iso」オプション付きでビルドします。
>packer build -only=virtualbox-iso centos65.json
これでしばらく待つと「basebox-packer\virtualbox」フォルダの下に Box ファイルが作成されます。
ちなみに上記の「misheska/basebox-packer」にある centos510.json のテンプレートを使った場合、手元の環境では build 中に「Unknown command unsupported_hardware」エラーになってしまいました。
その場合、ks.cfg 内の「unsupported_hardware」の行をコメントアウトしてから再度実行したら上手く行ったので、参考までに。
公開されているテンプレートを使うとかなり簡単に Box が作成できていいですね。
ありがたく使わせて頂きたいと思います。
Ruby から Windows の共有フォルダにアクセスする
Linux 上で Samba マウントせずに Windows の共有フォルダにアクセスしたかったので、Ruby の sambal というライブラリを使ってみました。
johnae/sambal
https://github.com/johnae/sambal
試した環境は以下です。
Ruby が 2.0 なのは単に手元で 2.1 の RPM をまだ作成していないだけです^^;
インストール
sambal は smbclient コマンドのラッパーなので、動作には smbclient コマンドが必要になります。
smbclient は yum から samba-client コマンドを実行するとインストールできます。
# yum install -y samba-client
インストールしたら Windows の共有フォルダにアクセスできるかを確認。
$ smbclient //PC001/Share "shakiyamain" -U akishin -p 445
smb: \> というプロンプトが表示されていれば接続は成功です。
ls と打つと共有フォルダ内のファイルを確認する事が出来ます。
プロンプトは exit で抜ける事ができます。
smb: \> ls . D 0 Tue Feb 18 22:43:37 2014 .. D 0 Tue Feb 18 22:43:37 2014 test.txt A 0 Tue Feb 18 22:43:36 2014 62499 blocks of size 16777216. 33957 blocks available smb: \> exit
ちなみに WORKGROUP ではなくドメインに参加している場合は以下のような感じ。
$ smbclient //PC001.example.co.jp/Share "p@ssword" -W example.co.jp -U akishin -p 445
これで sambal を使う準備は整いました。
ここでは bundler でインストールするので、まずは Gemfile を作成します。
$ bundle init
実行したディレクトリ内に Gemfile が生成されるので編集します。
$ vi Gemfile
本来なら配布されている gem を使えばいいので「gem 'sambal'」と書けばいいのですが、試したところ CentOS では以下のようなエラーになってしまい上手く動きません。
$ bundle exec ruby sambal_example.rb Failed to connect Unknown Process Failed!! (exit): "exit" /root/vendor/bundle/ruby/2.0.0/gems/sambal-0.1.2/lib/sambal.rb:70:in `exit' /root/vendor/bundle/ruby/2.0.0/gems/sambal-0.1.2/lib/sambal.rb:70:in `initialize' sambal_example.rb:9:in `new' sambal_example.rb:9:in `<main>'
どうも smbclient コマンドのプロンプト文字列をパースしている正規表現が若干異なるようです。
仕方ないので取りあえず Fork してエラーにならないように修正したものを使用しました。
https://github.com/akishin/sambal
上記を使う場合、 Gemfile には以下のように記述します。
gem 'sambal', github: "akishin/sambal"
bundle install 実行。
bundle install --path=vendor/bundle
これで sambal のインストールは完了です。
使ってみる
以下のような感じで接続して ls を実行してみます。
require 'sambal' begin HOST = 'PC001' DIR = 'Share' USER = 'akishin' PASS = 'p@ssword' client = Sambal::Client.new(host: HOST, share: DIR, user: USER, password: PASS) puts client.ls client.close rescue => e puts e end
ドメインに参加している Windows に接続する場合は以下のようにしてドメインを指定します。
require 'sambal' begin DOMAIN = 'example.co.jp' HOST = 'PC001.example.co.jp' DIR = 'Share' USER = 'akishin' PASS = 'p@ssword' client = Sambal::Client.new(domain: DOMAIN, host: HOST, share: DIR, user: USER, password: PASS) puts client.ls client.close rescue => e puts e end
実行すると以下のような結果が表示されました。
$ bundle exec ruby sambal_example.rb {"."=>{:type=>:directory, :size=>"0", :modified=>2014-02-18 22:43:37 +0900}, ".."=>{:type=>:directory, :size=>"0", :modified=>2014-02-18 22:43:37 +0900}, "test.txt"=>{:type=>:file, :size=>"0", :modified=>2014-02-18 22:43:36 +0900}}
ちゃんと共有フォルダの内容が読み取れているようです。
次は何かファイルを置いてみます。
Sambal::Client#put メソッドでローカルのファイルを共有フォルダに配置することができます。
require 'sambal' begin HOST = 'PC001' DIR = 'Share' USER = 'akishin' PASS = 'p@ssword' client = Sambal::Client.new(host: HOST, share: DIR, user: USER, password: PASS) client.put('/home/akishin/image.png', 'image.png') # <- 追記 puts client.ls client.close rescue => e puts e end
実行すると以下のように image.png が結果に含まれている事がわかります。
また、実際に共有フォルダを確認するとファイルが配置されていました。
$ bundle exec ruby sambal_example.rb {"."=>{:type=>:directory, :size=>"0", :modified=>2014-02-18 23:06:46 +0900}, ".."=>{:type=>:directory, :size=>"0", :modified=>2014-02-18 23:06:46 +0900}, "image.png"=>{:type=>:file, :size=>"29618", :modified=>2014-02-18 23:06:46 +0900}, "test.txt"=>{:type=>:file, :size=>"0", :modified=>2014-02-18 22:43:36 +0900}}
当然ですが Windows の共有フォルダに接続ユーザで書込み権限が必要なので、もし上手く行かない場合には確認してみて下さい。
というわけで、こんな感じでわざわざマウントしなくても Windows の共有フォルダに簡単にアクセスする事が出来ました。
Windows, Linux が混在しているような環境でスクリプトを書く際には結構重宝しそうです。
CentOS 6.5 に kippo をインストールしてみる
digitalOceanクラウド上に安く簡単にkippoハニーポットを構築する | 徳丸浩の日記
http://blog.tokumaru.org/2014/01/digitaloceankippo.html
sshハニーポットをkippoで作ってみる - ろば電子が詰まっている
http://d.hatena.ne.jp/ozuma/20130829/1377703104
さくらのVPSに来る悪い人を観察する その2
http://www.slideshare.net/ozuma5119/vps-28984029
この辺りの記事を読んでとても面白そうだったので、SSH ハニーポットの kippo を CentOS 6.5 環境にインストールしてみました。
依存ライブラリのインストール
まずは kippo を動かすためのライブラリ等をインストールしていきます。
yum から gcc, python-devel, setuptools をインストール。
# yum install -y gcc python-devel python-setuptools
setuptools を入れると使えるようになる easy_install コマンドで pip をインストールします。
# easy_install pip
pip から pyasn1, pycrypto, twisted パッケージをインストール。
# pip install pyasn1 pycrypto twisted
これで必要なライブラリは一通り入りました。
SSH ポート番号の変更
SSH の標準ポート 22 番は kippo で使用したいので、本来の sshd が使用するポート番号を変更します。
# vi /etc/ssh/sshd_config
ここでは徳丸さんの記事に習って 10022 番ポートに変更しました。
#Port 22 Port 10022
変更したら sshd を再起動します。
# service sshd restart
※ 手元の TeraTerm ではここで sshd を再起動しても特に問題なく作業を続行できましたが、VPS などで試している場合、もし不安なら先に以下を実行して、iptables で変更後の SSH ポートを空けておいた方が無難かも知れません。
iptables の設定
iptables で変更後の sshd 用ポートと kippo の LISTEN ポートを開放します。
ここでは CentOS のデフォルトのルールをそのままにしてあるので、-A で末尾に追加しても上手く動きません。
なので -I で先頭にルールを追しています。
# iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport 2222 -j ACCEPT # iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport 10022 -j ACCEPT
ポート 22 を kippo のデフォルトポート 2222 にリダイレクトするように以下のルールを追加します。
# iptables -t nat -A PREROUTING -p tcp --dport 22 -j REDIRECT --to-port 2222
kippo のインストール
いよいよ kippo をインストールします。
まずは kippo の起動用ユーザを追加します。
# useradd kippo
作成した kippo ユーザになり、ダウンロードして展開します。
# su - kippo $ wget https://kippo.googlecode.com/files/kippo-0.8.tar.gz $ tar xzf kippo-0.8.tar.gz $ cd kippo-0.8
ログを有効にするため、設定ファイルを編集します。
$ vi kippo.cfg
ファイル末尾の以下の行のコメントアウトを解除。
[database_textlog] logfile = kippo-textlog.log
また、kippo でログインを可能とするユーザが以下のファイルで定義されています。
$ cat data/userdb.txt root:0:123456
デフォルトでは上記のように root ユーザがパスワード「123456」で定義されています。
このファイルを変更することでユーザを追加したり、パスワードを変更したりといった事ができます。
準備ができたら kippo を起動してみます。
$ ./start.sh
Starting kippo in background...Loading dblog engine: textlog
Generating RSA keypair...
done.
無事起動できました。
起動で来たら先ほど設定ファイルで有効にした以下のログを tail しておきます。
$ tail -f ./kippo-textlog.log
この状態で別の SSH クライアントを起動してポート 22 に接続し、root / 123456 でログインすることができます。
ログイン後、コマンドを実行してみると kippo-textlog.log に以下のように何を実行したかが記録されている事が分かります。
$ tail -f ./kippo-textlog.log b52fc974918911e3b432000c29ca5f43 [2014-02-09 21:57:18]: New connection: 192.168.81.1:50270 b52fc974918911e3b432000c29ca5f43 [2014-02-09 21:57:26]: Login succeeded [root/123456] b52fc974918911e3b432000c29ca5f43 [2014-02-09 21:57:26]: Terminal size: 150x45 b52fc974918911e3b432000c29ca5f43 [2014-02-09 21:57:29]: Command [w] b52fc974918911e3b432000c29ca5f43 [2014-02-09 21:57:32]: Command [ls] b52fc974918911e3b432000c29ca5f43 [2014-02-09 21:57:37]: Command [ls -l]
取りあえず試したのはここまで。
CentOS でも結構簡単に導入出来る事が分かったので、いろいろ遊んでみたいと思います。
Vagrant 1.4.0 で private_network を指定しているとエラーになる件
Vagrant 1.4.0 で追加された Docker provisioner などを試してみたいと思い、勇んでアップデートしてみたところ vagrant up でエラー。
・ ・ ・ [default] Configuring and enabling network interfaces... The following SSH command responded with a non-zero exit status. Vagrant assumes that this means the command failed! /sbin/ifdown eth1 2> /dev/null Stdout from the command: Stderr from the command:
どうも CentOS などの Redhat 系 OS を使っている場合に private_network を指定してるとなるっぽい・・・。
以下の Issue が上がっていました。
"Configuring and enabling network interfaces" fails with ssh error · Issue #2614 · mitchellh/vagrant
https://github.com/mitchellh/vagrant/issues/2614
この Issue で上げられていた以下のパッチで直るみたいです。
Merge pull request #2628 from makern/ifdown-fix · 70b662e · mitchellh/vagrant
https://github.com/mitchellh/vagrant/commit/70b662e3073c5a6aed2374ca289f8818f8ef8ed1
取りあえずすぐ動かしたかったので、アップデートのリリースを待たずに当ててみました。
Windows だと該当のファイルはデフォルトでは以下の場所にあります。
C:\HashiCorp\Vagrant\embedded\gems\gems\vagrant-1.4.0\plugins\guests\redhat\cap\configure_networks.rb
コード量も多くなかったのと面倒だったので元のファイルをバックアップしておいて、直接編集してしまいました。
上の URL の [View file] をクリックして次の画面で [RAW] をクリック。
この内容をコピーして、先ほど見つけた該当のファイルに貼り付けるだけ。
これで一応手元の環境では無事起動できるようになりました。
それにしても久しぶりにバージョンアップ時の地雷踏んだなー。