暗号通貨用Webサービスを立ち上げるためのmonacoind(bitcoind)のビルドと運用

## 概要
Monacoin（もしくはBitcoin）を利用したWebサービスを新しく立ちあげたい場合、最初の問題はどのようにMonacoinをやりとりするためのプログラムである`monacoind`をビルドするのか分からないことです。また、暗号通貨関連のWebサービスは特にセキュリティに気を付ける必要がありますし、`monacoind`のプロセスを監視するためのスクリプトも欲しいところです。本記事では、暗号通貨用のWebサービスを立ち上げるために必要な`monacoind`のビルド方法と、その簡易的な運用方法について解説します。

これらの情報は海外のサイトを漁れば見つけられますが、情報が分散していて若干面倒です。この記事はこれらの情報を簡単にまとめることで、読者がすぐに実際の開発へ取り組めるようになることを期待しています。なお、今回は使用するディストリビューションに`Ubuntu server 12.04 LTS`を選択しましたが、他のディストリも方法はほぼ同じです。

## monacoindのビルド
`monacoind`のビルド自体は`apt`などのパッケージ管理システムを使えば比較的簡単に行えます。まずはビルドに必要な各種パッケージを次のコマンドでインストールします。

```bash
$ sudo apt-get install git git-core build-essential libssl-dev libdb++-dev libminiupnpc-dev libboost-dev libboost-system-dev libboost-filesystem-dev libboost-program-options-dev libboost-thread-dev
```

次に、[githubのリポジトリ](https://github.com/monacoinproject/monacoin)から`monacoind`のソースコードを取り込みます。なお、本家の`monacoin`は元の`litecoin`に含まれる履歴を全部消去してしまったため、どのような変更が行われたのか直接確認することは困難です。ソースコードを読み解きたい場合は、[Naohiro Aota](http://elisp.net)さんが公開してくれた[Monacoinのパッチ分割](https://github.com/naota/monacoin/commits/monacoin-split)を参照してください。

`monacoind`の場合、一般的なソフトウェアのビルドに必要な`configure`は必要なく、単純に`monacoin/src/makefile.unix`を叩くだけで完了します。

```bash
$ git clone https://github.com/monacoinproject/monacoin.git
$ cd monacoin/src
$ make -f makefile.unix
```

なお、Monacoinを含む多くの暗号通貨は、コンパイルを劇的に遅くすることに定評のある`Boost.Spirit`を使用しています(`boost`を使うことでコンパイルが遅くなる現象は一般に *Boooooooost* と呼ばれる)ので、辛抱強く待ちましょう。

ビルドが完了すれば、`monacoin/src`ディレクトリ内に`monacoind`が生成されます。これを`/usr/bin`や`/usr/local/bin`あたりに移して、試しに実行してみます。

```bash
$ monacoind
Error: To use monacoind, you must set a rpcpassword in the configuration file:
/path/to/user/.monacoin/monacoin.conf
It is recommended you use the following random password:
rpcuser=monacoinrpc
rpcpassword=4LTbb7JnUP6waLXMrZFUr6T6ngLDAXqEnVFftYdXKkuV
(you do not need to remember this password)
The username and password MUST NOT be the same.
If the file does not exist, create it with owner-readable-only file permissions.
It is also recommended to set alertnotify so you are notified of problems;
for example: alertnotify=echo %s | mail -s "Monacoin Alert" admin@foo.com
```

エラーが出たので、指示通りに設定してみます。まず、ホームディレクトリ内に`.monacoin`ディレクトリを作ります。

```bash
$ cd $HOME
$ mkdir -m 700 .monacoin
$ touch .monacoin/monacoin.conf
```

`.monacoin`ディレクトリの中には、`monacoind`の動作に必要な各種データベースファイルが含まれます。次に、`.monacoin/monacoin.conf`ファイルを次のように書き換えます。

```bash
rpcuser=monacoinrpc
rpcpassword=4LTbb7JnUP6waLXMrZFUr6T6ngLDAXqEnVFftYdXKkuV
```

最後にもう一度`monacoind`を実行すれば、特に何もエラーが発生せずに実行されると思います。なお、最初の実行にはやたらCPUを消費しますが、数分程度待機すれば収まります。

## supervisordによる運用と監視
`monacoind`は`-daemon`オプションを入れることでデーモン化する機能が組み込まれていますが、`monacoind`を起動時に毎回立ち上げるのは面倒ですし、万が一ダウンした際には自動的に立ち上がるような設定も必要です。一般にはinitスクリプトやsystemdなどを利用してサービス登録を行いますが、面倒ですので今回は`supervisor`を利用して気軽に`monacoind`の運用と監視を行うようにします。まず、`apt`を利用して`supervisor`をインストールします。

```bash
$ sudo apt-get install supervisor
```

debian系列の`supervisor`は、`/etc/supervisor/conf.d`ディレクトリ内にデーモン化したいプログラムの`.conf`ファイルを入れることでサービスを登録します。`/etc/supervisor/conf.d/`に`monacoin.conf`を作成し、次のような形で`monacoind`のサービスを登録します。

```/etc/supervisor/conf.d/monacoin.conf
[program:monacoin]
user=monacoin
autostart=true
autorestart=true
command=/usr/bin/monacoind -server -rpcallowip=127.0.0.1 -rpcuser=USERNAME -rpcpassword=PASSWORD -rpcport=PORT -datadir=/path/to/datadir/monacoin
```

`$HOME/monacoin/monacoin.conf`に設定を書くのもいいですが、情報が散乱するので今回は`supervisor`のファイルに直接`monacoind`のオプションを記入しています。最後に、`supervisorctl`を利用して設定ファイルのリロードと起動を行います。

```bash
$ sudo supervisorctl reload
Restarted supervisord
$ sudo supervisorctl status
monacoin                        STOPPED    Feb 20 02:44 AM
$ sudo supervisorctl start monacoin
monacoin: started
$ sudo supervisorctl status
monacoin                        RUNNING    pid 4357, uptime 0:00:10
```

無事に`monacoind`の起動が確認できました。

## 運用に関するセキュリティ上の設定
これは実際に運用している方にとっては一般的かもしれませんが、一応補足します。

* `wallet.dat`などの重要なファイルを含む`datadir`のパーミッションは慎重に設定する必要があります。具体的には、`datadir`が他のユーザから見えるような設定は避ける事が望ましいです。同様に、`supervisord`の`conf.d/*.conf`も`root`以外には読めないように設定してください。
* `monacoind`を動かすための専用のユーザ(`monacoin`など)を作成し、権限を限定した上で`monacoind`を起動するべきです。特に、Webアプリケーションを起動しているユーザから`monacoind`の設定ファイルが読めるような設定になることは避けるべきです。
* `rpcpassword`はランダムな文字列を使用すべきであり、推測されやすい単語で構成されるべきではありません。
* `rpcpassword`を記入しているWebアプリケーションの設定ファイルは絶対に外部に公開されないよう気をつける必要があります。
* 特定のIPからのみの通信を許可する`rpcallowip`は必ず設定してください。