Nekoniumのパブリックノードを立ててみよう その3 Let's Encrypt+Nginxで簡単にSSL対応編

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

##手順

###ドメインの準備

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

###サーバーの準備

####サーバーの用意
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.198.87.166」が割り当てられました。
![25c3837c292cd288d1cb3764e591a67e.png](https://qiita-image-store.s3.amazonaws.com/0/232554/84b3515f-bc3e-62ba-41bb-494970437a13.png)
---
![a6367dbb078f45d5aa3ea0d36ae4fa41.png](https://qiita-image-store.s3.amazonaws.com/0/232554/165bdec1-1c0b-a7e0-68a1-5aefbc677c4e.png)

####固定IPを関連付ける
「アクション」から、先ほど作成したインスタンスにグローバル固定IPを割り当てます。
![7f3926a7bf56f47cf02e5184963253fd.png](https://qiita-image-store.s3.amazonaws.com/0/232554/acdbdbdb-cfee-37fd-4434-ff0a5ea241d6.png)
---
![7621fc71fba839a3e5d30a01e1f3f7f1.png](https://qiita-image-store.s3.amazonaws.com/0/232554/e440fab7-268e-1709-29f4-222053317db9.png)

####ファイアウォールの設定
「セキュリティグループ」のインバウンド設定から、今回使用するTCPの「8293」と、SSL証明書取得に必要な「80」「443」ポートを空けておきます。
![fc94efd8a8d97c5f51fcd88aeade4e5c.png](https://qiita-image-store.s3.amazonaws.com/0/232554/5d20e81b-164c-9cd9-d236-be30ae1c1a8b.png)
---
![4341d22a8dcbb8a2d42babd16953b181.png](https://qiita-image-store.s3.amazonaws.com/0/232554/c96740c7-1fd1-dda3-2cb6-0ee5587be89f.png)

####DNSの設定
今回割り当てられたグローバル固定IPをドメイン名に紐付けます。
バリュードメインのDNS設定からAレコードのsslを「52.198.87.166」に設定します。
![db1440cdbdb624b3bb36ea3dedc17d5d.png](https://qiita-image-store.s3.amazonaws.com/0/232554/fe59293f-109b-3d49-989d-e24696cc8d70.png)

###サーバーの設定

####インスタンスへの接続
Windowsの場合は「PuTTY」を使用します。詳しい接続方法はAWSのページを参照してください。
[Linux インスタンスへの接続 - AWS Documentation](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/AccessingInstances.html)
![b70d4341c63c3f5a400cf33942f7ad34.png](https://qiita-image-store.s3.amazonaws.com/0/232554/6631a99b-1881-84e8-e645-191c3b9c21d3.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`と出力されればインストール成功です。

####Let's Encryptとnginxのインストールと設定

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

#####SSL証明書の発行
下記コマンドを実行してSSL証明書の発行の手続きを行います。
`sudo letsencrypt certonly --standalone -d ssl.nekonium.site`

UIが立ち上がりますので、普段使用している自分のメールアドレスを入力し、規約に同意して下さい。
![24a9cb1b352652d270ef5574c76b55f1.png](https://qiita-image-store.s3.amazonaws.com/0/232554/acc0342a-74db-fb1f-da77-a2fe9a079419.png)
---
![f32ffd4945031b00708305fbd5ccba80.png](https://qiita-image-store.s3.amazonaws.com/0/232554/1d69e6c4-5131-3144-6cfe-637361c71aea.png)

Congratulations!と表示されればSSL証明書の発行成功です。

#####SSL証明書の自動更新設定
下記コマンドでcronを立ち上げてSSL証明書を自動更新できるようにします。
`sudo crontab -e` エディタを聞かれるので好きなものを選んで下さい。以下を書き込み保存します。

```
00 05 01 * * sudo systemctl stop nginx; sudo letsencrypt renew; sudo systemctl start nginx
```
毎月1日の朝5時にSSL証明書を自動更新する設定になります。

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

#####設定の前に
[nginxconfig.io](https://nginxconfig.io/) 
上記のサイトでnginxの最適な設定を簡単に取り出すことが出来ます。
今回こちらをベースに設定をしていきます。 → [設定例](https://nginxconfig.io/#!?domain=ssl.nekonium.site&path=%2Fvar%2Fwww%2Fssl.nekonium.site&https&email=mail@mofumofu.me&php=off&user=ubuntu)

#####nginxの設定
nginxのコンフィグファイルを下記のように設定します。ドメイン名は適宜読み替えて下さい。
`sudo vi /etc/nginx/nginx.conf`

```nginx.conf
user ubuntu;
pid /run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 409600;

events {
	worker_connections 4096;
	multi_accept on;
	use epoll;
}

http {
	proxy_set_header Host $http_host;	
	proxy_set_header X-Real-IP $remote_addr;
	proxy_set_header X-Forwarded-Proto $scheme;
	proxy_set_header X-Forwarded-Host $http_host;
	proxy_set_header X-Forwarded-Server $host;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

	charset utf-8;
	sendfile on;
	tcp_nopush on;
	tcp_nodelay on;
	types_hash_max_size 2048;
	server_tokens off;
	log_not_found off;

	client_max_body_size 50M;
	client_body_buffer_size 128k;

	# mime
	include mime.types;
	default_type application/octet-stream;

	# logging
	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log warn;

	# include configs
	include /etc/nginx/conf.d/*.conf;

	# ssl.nekonium.site
	server {
		listen 8293 ssl http2;
		listen [::]:8293 ssl http2;

		server_name ssl.nekonium.site;

		ssl_certificate /etc/letsencrypt/live/ssl.nekonium.site/fullchain.pem;
		ssl_certificate_key /etc/letsencrypt/live/ssl.nekonium.site/privkey.pem;
		ssl_trusted_certificate /etc/letsencrypt/live/ssl.nekonium.site/fullchain.pem;
	
		include _ssl.conf;
		
		location / {
		proxy_pass http://localhost:8292/;
		proxy_redirect default;
		}
	}
	
	server {
		listen 443 ssl http2;
		listen [::]:443 ssl http2;
	
		server_name ssl.nekonium.site;
		root /var/www/ssl.nekonium.site/public;
	
		ssl_certificate /etc/letsencrypt/live/ssl.nekonium.site/fullchain.pem;
		ssl_certificate_key /etc/letsencrypt/live/ssl.nekonium.site/privkey.pem;
		ssl_trusted_certificate /etc/letsencrypt/live/ssl.nekonium.site/fullchain.pem;
	
		include _ssl.conf;
	
		# ACME-challenge
		location ^~ /.well-known/acme-challenge/ {
			default_type "text/plain";
			root /var/www/_letsencrypt;
		}
	
		# headers
		add_header X-Frame-Options "SAMEORIGIN" always;
		add_header X-XSS-Protection "1; mode=block" always;
		add_header X-Content-Type-Options "nosniff" always;
		add_header X-UA-Compatible "IE=Edge" always;
		add_header Cache-Control "no-transform" always;
		
		# . files
		location ~ /\. {
			deny all;
		}
		
		# assets, media
		location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
			expires 7d;
			access_log off;
		}
		
		# svg, fonts
		location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff|woff2)$ {
			add_header Access-Control-Allow-Origin "*";
			expires 7d;
			access_log off;
		}
		
		# gzip
		gzip on;
		gzip_vary on;
		gzip_proxied any;
		gzip_comp_level 6;
		gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml;
	}

	server {
		listen 80;
		listen [::]:80;
	
		server_name ssl.nekonium.site;

		# ACME-challenge
		location ^~ /.well-known/acme-challenge/ {
			default_type "text/plain";
			root /var/www/_letsencrypt;
		}
	
		return 301 https://ssl.nekonium.site$request_uri;
	}
}
```

SSL用のコンフィグファイルも作成しておきます。
`sudo vi /etc/nginx/_ssl.conf`

```_ssl.conf
# https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=nginx-1.10.3&openssl=1.1.0g&hsts=yes&profile=intermediate
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;

# Diffie-Hellman parameter for DHE ciphersuites
ssl_dhparam /etc/nginx/dhparam.pem;

# intermediate configuration
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
ssl_prefer_server_ciphers on;

# HSTS
add_header Strict-Transport-Security "max-age=15768000" always;

# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;

resolver 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s;
resolver_timeout 2s;
```

#####DHパラメーターファイルの生成
下記コマンドを実行してDHパラメーターファイルを生成します。
`sudo openssl dhparam -dsaparam -out /etc/nginx/dhparam.pem 4096`

#####nginxの再起動
下記コマンドでnginxを再起動します。
`sudo nginx -s reload`

これでnginxの設定は完了です。

####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`

####gnekoniumの初回起動

#####ブロックチェーンの同期
下記コマンドを実行してブロックチェーンの同期を行います。
`build/bin/gnekonium --fast --cache=256 console`
少し時間がかかります。(15分くらい)
※注意 `--cache=512`だとインスタンスのメモリ容量が足りず失敗します。

#####同期終了
`Fast sync complete, auto disabling`と表示されれば同期が成功したことになります。

####SSL通信対応パブリックノードの開始
新しいセッションでgnekoniumを起動します。ポート番号は8292を指定しています。
`tmux new -s gnekonium`
`cd nekonium/go-nekonium`
`build/bin/gnekonium -rpc --rpcaddr 0.0.0.0 --rpcport 8292`

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

##おわりに
以上でメールアドレスとSSL証明書の維持費用がかからない、「Nekonium」のSSL通信対応パブリックノードの構築が完了しました。
/var/www/ドメイン名/public 以下にhtmlファイルを設置してサイトとしても機能できるようになっております。

##参考サイト
[Let's Encrypt の使い方 - Let's Encrypt 総合ポータル](https://letsencrypt.jp/usage/)
[How To SSL Ethereum Geth Node? - Stack Exchange](https://ethereum.stackexchange.com/questions/26026/how-to-ssl-ethereum-geth-node)
[letsencryptをUbuntu16.04 + Nginxで使ってみた - Qiita](https://qiita.com/k-yamada-github/items/7314003de7bdcbb2d39b)