Nekoniumのパブリックノードを立ててみよう その2 SSL対応編

##はじめに
前回は通常の「[Nekonium](https://nekonium.github.io/)」パブリックノードの構築方法を記載しましたが、今回はhttp-proxyを使ったSSL通信対応パブリックノードの構築方法を記載します。
[その1](https://qiita.com/ROZ-mofumofu-me/items/f9490e4bd23922b62e54)にいくつか手順を加えたものになりますので、事前に一度ご覧頂けると幸いです。

##手順

###ドメインとSSL証明書の準備

####ドメインの取得
ドメイン取得代行サイトで任意のドメインを取得してください。
なお、今回は既に[バリュードメイン](https://www.value-domain.com/)で取得したドメイン「nekonium.site」のサブドメイン「www.nekonium.site」を使用します。
![6f8a0b14a8ebedac1a4f06f79d869909.png](https://qiita-image-store.s3.amazonaws.com/0/232554/080c5aac-9275-c885-33aa-9b42a145f24a.png)

####メールアドレスの取得
SSL証明書を発行するには事前にドメイン管理者のメールアドレスが必要になります。
今回は[G Suite](https://gsuite.google.com/)で「admin@nekonium.site」というメールアドレスを作成します。
![0b8a4217042a3186827cd5f65344eff1.png](https://qiita-image-store.s3.amazonaws.com/0/232554/a99b38e0-3d5b-df7b-8797-4d7da14e20ef.png)
---
![c619b0569159a8deb9e648c2f16a6c73.png](https://qiita-image-store.s3.amazonaws.com/0/232554/80fd5fb3-f61d-3c7d-9ed7-9bcd82d5dc81.png)

####ドメインの確認とメール設定
ドメインの所有者であることを証明するために、今回はDNSのTXTレコードを使用します。
G Suiteの指示に従いながら、バリュードメイン側でDNSの設定をします。
![90d9147c9f46c1a08dab2c137cffd10f.png](https://qiita-image-store.s3.amazonaws.com/0/232554/3ade4b8d-6bea-47cb-3add-55c111769433.png)
---
![8d7acf02520396ecffe57c0c945d6ebd.png](https://qiita-image-store.s3.amazonaws.com/0/232554/538e8284-50fd-0835-09fc-a87681b2b3f8.png)
---
![fded59ced170fe9860c39f1edda53e54.png](https://qiita-image-store.s3.amazonaws.com/0/232554/a925771f-9895-6e18-c123-b90dccebc3f1.png)

####メール設定の完了
ドメインの確認とメール設定が完了したら、メールの送受信をテストして下さい。
![6665fdd4598ce351c9f793eb6d3517d6.png](https://qiita-image-store.s3.amazonaws.com/0/232554/93295658-87d9-85bd-c5e3-cfd31a8813e4.png)

####CSR・秘密鍵の生成
SSL証明書を発行するには事前にCSRと秘密鍵(プライベートキー)を用意する必要があります。
[バリュードメイン](https://www.value-domain.com/)がオンラインでCSRと秘密鍵の生成と管理をするツールを提供していますので、そちらを利用します。
CSRとプライベートキー(パスフレーズあり)とプライベートキー(パスフレーズ無し)の3つが生成されます。
![a8dd8265620225f04d1e6820c4f418ce.png](https://qiita-image-store.s3.amazonaws.com/0/232554/6c4ae3f5-573d-f52b-cb2f-387ac07ecc67.png)
---
![29d206a464cdd4ae21bd1b0c72d4c520.png](https://qiita-image-store.s3.amazonaws.com/0/232554/55c2a234-773c-ade8-2e54-8943f2b8397c.png)

####SSL証明書の発行
生成されたCSRと秘密鍵を使用してSSL証明書発行代行サイトよりSSL証明書を取得します。
今回はバリュードメインでそのままSSL証明書を発行します。
(生成されたCSRと秘密鍵は他の発行サイトでも使えます)
作成済のCSRを選択して、「admin@nekonium.site」に承認メールが来るようにします。
![4692512c80bd1fe9a5be0b9d3e7ce852.png](https://qiita-image-store.s3.amazonaws.com/0/232554/fb46dfe9-d5a4-fb33-4c9c-ff2febf5ff74.png)
---
![9c4c16a31889d7072ce6406f89bba447.png](https://qiita-image-store.s3.amazonaws.com/0/232554/05459874-71d7-804f-fbe0-9563c25e7a9f.png)
---
![c561d02cdf8f4157fe66ddc08b6a764b.png](https://qiita-image-store.s3.amazonaws.com/0/232554/6f713e0b-2627-1b5e-6b1d-7bbe40d50b07.png)

これでSSL証明書が発行されました。

###サーバーの準備

####サーバーの用意
Linuxサーバーを立ち上げます。
今回も[AWS](https://aws.amazon.com/jp/)の「Ubuntu Server 16.04 LTS (HVM), SSD Volume Type」を選びました。
インスタンスタイプも同じく「t2.micro」にしておきます。
![6c6f74d298db3a429170ea318c1c0f79.png](https://qiita-image-store.s3.amazonaws.com/0/232554/e45c0f9c-5f58-ad12-dfc2-507d828aa526.png)
---
![7d7f92cd7b6508e061f3359b66d8f7e7.png](https://qiita-image-store.s3.amazonaws.com/0/232554/a4fd7b51-45b9-1a2b-1f5a-ef01ba205e87.png)

####固定IPの取得
インスタンスが立ち上がったら、「Elastic IP」でグローバル固定IPを取得します。
今回は「52.10.12.170」が割り当てられました。
![25c3837c292cd288d1cb3764e591a67e.png](https://qiita-image-store.s3.amazonaws.com/0/232554/84b3515f-bc3e-62ba-41bb-494970437a13.png)
---
![0e0916210389664f953e59a980062589.png](https://qiita-image-store.s3.amazonaws.com/0/232554/daf7a8a7-b86a-f340-ad0f-8cbebe47b035.png)

####固定IPを関連付ける
「アクション」から、先ほど作成したインスタンスにグローバル固定IPを割り当てます。
![ecf105334cda6f01d97c2d96b8b19d87.png](https://qiita-image-store.s3.amazonaws.com/0/232554/252a2f86-e946-77ce-293c-e00c2adf9c2c.png)
---
![2149ad15b781c83db22d304fec96cbf9.png](https://qiita-image-store.s3.amazonaws.com/0/232554/a2e7e414-ebb4-b44b-e61b-cd9cffac1434.png)

####ファイアウォールの設定
「セキュリティグループ」のインバウンド設定から、今回使用するTCPの「8293」ポートを空けておきます。
![fc94efd8a8d97c5f51fcd88aeade4e5c.png](https://qiita-image-store.s3.amazonaws.com/0/232554/5d20e81b-164c-9cd9-d236-be30ae1c1a8b.png)
---
![7741084b046e610c2c866f6dc7e34294.png](https://qiita-image-store.s3.amazonaws.com/0/232554/c5d9b6cd-7cda-32be-6ef1-bed37be85f39.png)

####DNSの設定
今回割り当てられたグローバル固定IPをドメイン名に紐付けます。
バリュードメインのDNS設定からAレコードのwwwを「52.10.12.170」に設定します。
ドメイン確認に使用したTXTレコードの行は削除して構いません。
![9d1db600b20bdc9dc6eab5db1389da2b.png](https://qiita-image-store.s3.amazonaws.com/0/232554/b3917dff-a4d2-9197-3f42-7aeb4e52544b.png)

###サーバーの設定

####インスタンスへの接続
Windowsの場合は「PuTTY」を使用します。詳しい接続方法はAWSのページを参照してください。
[Linux インスタンスへの接続 - AWS Documentation]
(https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/AccessingInstances.html?icmpid=docs_ec2_console)
![4d2201d36001ef311d9144da190b2b78.png](https://qiita-image-store.s3.amazonaws.com/0/232554/110550a9-384e-3770-a925-26c4d9b41569.png)
---
![ab7c4cc2774f32febd5961a870c946ef.png](https://qiita-image-store.s3.amazonaws.com/0/232554/498389e9-e2fb-2e26-78c6-671917456d2f.png)

####Ubuntuのアップデート
ログインができたら、まずUbuntuをアップデートして再起動します。
`sudo apt-get update`
`sudo apt-get dist-upgrade`
`sudo reboot`

####build-essentialのインストール
下記コマンドを実行してbuild-essentialをインストールします。
`sudo apt-get install build-essential make`

####Goのインストール
下記コマンドを実行してGoをインストールします。
`wget https://storage.googleapis.com/golang/go1.9.2.linux-amd64.tar.gz`
`sudo tar -xvf go1.9.2.linux-amd64.tar.gz`
`sudo mv go /usr/local`
`export GOROOT=/usr/local/go`
`export PATH=$GOPATH/bin:$GOROOT/bin:$PATH`
`export GOPATH=$HOME/go`
`go version` と入力して`go version go1.9.2 linux/amd64`と出力されればインストール成功です。

####gnekoniumのインストール
下記コマンドを実行してgnekoniumをインストールします。
`mkdir nekonium`
`cd nekonium`
`git clone https://github.com/nekonium/go-nekonium`
※もしgitがインストールされていない場合は、sudo apt-get install gitを実行して下さい。
`cd go-nekonium`
`export GOROOT=/usr/local/go`
`export PATH=$GOPATH/bin:$GOROOT/bin:$PATH`
`export GOPATH=$HOME/go`
`make gnekonium`

####nodejsのインストール
下記コマンドを実行してnodejsをインストールします
`cd`
`sudo apt-get install nodejs`
``sudo ln -s `which nodejs` /usr/bin/node``
`nodejs -v`と入力すると、バージョンが確認できます。

####npmのインストール
下記コマンドを実行してnpmをインストールします
`sudo apt-get install npm`

####http-proxyのインストール
下記コマンドを実行してhttp-proxyをインストールします
`mkdir tools`
`mkdir tools/proxy`
`cd tools/proxy`
`npm init` 途中で止まりますが、`Is this ok? (yes)`までEnterキーで進んでいきます。
`npm install http-proxy --save`
`npm install fs --save`
`touch stop.sh`
`vi stop.sh` stop.shに下記のように書き込みます。

```stop.sh
 #!/bin/bash
 ps aux | grep 'node index.js' | grep -v grep | awk '{print $2}' | xargs kill -9 
```
`vi package.json` package.jsonを下記のように編集します。

```json:package.json
{
   "name": "proxy",
   "version": "1.0.0",
   "description": "Proxy server for ethereum node",
   "main": "index.js",
   "scripts": {
      "start": "node index.js &",
      "stop": "./stop.sh"
   },
   "author": "Robert Lie",
   "license": "ISC",
   "dependencies": {
      "fs": "0.0.1-security",
      "http-proxy": "^1.16.2"
   }
} 
```
`touch index.js`
`vi index.js` index.jsに下記内容を書き込みます。

```javascript:index.js
var httpProxy = require('http-proxy');
var fs = require('fs'); 

httpProxy.createServer({
  target: {
    host: 'localhost',
    port: 8292
 },
 ssl: {
    key: fs.readFileSync(
    '/home/ubuntu/tools/proxy/ssl/www.nekonium.site.key', 'utf8'),
    cert: fs.readFileSync(
    '/home/ubuntu/tools/proxy/ssl/www.nekonium.site.pem', 'utf8')
 }
}).listen(8293); 
```

#####SSL証明書のインストール
`mkdir ssl`
`cd ssl`
`touch www.nekonium.site.key`
`touch www.nekonium.site.pem`
`touch www.nekonium.site.ca.pem`
`vi www.nekonium.site.key` 取得したSSL秘密鍵(プライベートキー パスフレーズ無し)の内容を書き込みます。

```www.nekonium.site.key
-----BEGIN RSA PRIVATE KEY-----

中略

-----END RSA PRIVATE KEY-----
```
`vi www.nekonium.site.pem` 取得したSSL証明書の内容を書き込みます。

```www.nekonium.site.pem
-----BEGIN CERTIFICATE-----

中略

-----END CERTIFICATE-----

```
`vi www.nekonium.site.ca.pem` 取得したSSL中間証明書の内容を書き込みます。

```www.nekonium.site.ca.pem
-----BEGIN CERTIFICATE-----

中略

-----END CERTIFICATE-----

```
`cat www.nekonium.site.ca.pem >> www.nekonium.site.pem` 2つの証明書を結合します。

これでhttp-proxyの準備が出来ました。

####gnekoniumの初回起動
#####ブロックチェーンの同期
下記コマンドを実行してブロックチェーンの同期を行います。
`cd`
`cd nekonium/go-nekonium`
`build/bin/gnekonium --fast --cache=256 console`
少し時間がかかります。(15分くらい)
※注意 `--cache=512`だとインスタンスのメモリ容量が足りず失敗します。
#####同期終了
`Fast sync complete, auto disabling`と表示されれば同期が成功したことになります。


####http-proxyの開始
新しいセッションを開き、下記コマンドを実行してhttp-proxyを開始します。
`cd tools/proxy`
`npm start`

####SSL通信対応パブリックノードの開始
`cd`
`tmux new -s gnekonium`
`cd nekonium/go-nekonium`
`build/bin/gnekonium -rpc --rpcaddr 0.0.0.0 --rpcport 8292` 今回はポート8293ではなく8292で起動します

####動作確認
ノードが動作しているか確認するには別セッションで下記コマンドを実行します。
`curl -s -X POST --data '{"jsonrpc":"2.0","id":0,"method":"eth_getBalance","params":["アドレス","latest"]}'  https://www.nekonium.site:8293/`
`アドレス`にはNekoniumのアカウントを入力して下さい。
16進数でアカウントの残高が表示されれば無事SSL通信で動作していることになります。

##おわりに
これでSSL通信対応のパブリックノードの構築が完了しました。
しかし、SSL証明書やメールアドレスの維持費が気になりますね。
次回はもっと安上がりで簡単なSSL通信対応パブリックノードの構築方法を投稿したいと思います。

##参考サイト
[How to make geth support SSL - mobilefish.com](https://www.mobilefish.com/developer/blockchain/blockchain_quickguide_geth_support_ssl.html)

[How To Install Node.js on Ubuntu 16.04 - DigitalOcean](https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-16-04)