ServiceWorkerやWebRTCと組み合わせたモノを作るため、httpsで通信できるNISがほしかったのですが、対応しているノードが少ないし、あっても署名が切れていたりでイマイチ使い物にならなかったので自分で立てることにしました。

ServiceWorkerやWebRTCの利用で必要な方はどうぞご利用ください。(落ちてたり、証明書切れてたら、教えてくれれば対応します)

追記: メインネットのノードは停止してしまいました。

替わりにhttps://shibuya.supernode.me:7891をご利用ください。

tl;dr

以下の手順をスクリプトに落とし込みました。

何度か失敗することがあったり、うまく行ったりするので微妙に不安定ですが、よろしければ参考に。

構築

元ネタはnemブログ。Debianでのチュートリアルですが、今回はUbuntu 16.04で行いました。

同じ手順で構築できます。

(以下、面倒なのでrootでログインしての作業を前提とします)

なお、ドメイン名やメールアドレスはご自身のものに置き換えてください。

まずはLet’s Encryptによる署名の取得を自動化するためにdehydratedというパッケージをインストールします。

githubからスクリプトをダウンロードしてもよいですが、こっちのほうが手軽だと思います。

dehydratedのインストール

aptリポジトリを追加します。

$ echo 'deb jessie-backports main' > /etc/apt/sources.list.d/backports.list

追加したリポジトリの情報をupdateでとってきて、インストールします。

$ apt-get update && apt-get install dehydrated

dehydratedの設定

/etc/dehydrated/domains.txt にドメイン名を書き込みます。

$ echo 'nis.example.com' > /etc/dehydrated/domains.txt

/etc/dehydrated/conf.d/config.sh を以下の内容で作成してください。

$ vim /etc/dehydrated/conf.d/config.sh

BASEDIR=/var/lib/dehydrated
WELLKNOWN="${BASEDIR}/acme-challenges"
DOMAINS_TXT="/etc/dehydrated/domains.txt"
CONTACT_EMAIL="youremail@example.com"

/etc/dehydrated/hook.sh を以下の内容で作成してください。

$ vim /etc/dehydrated/hook.sh

#!/bin/bash
function deploy_challenge {
  local DOMAIN="${1}" TOKEN_FILENAME="${2}" TOKEN_VALUE="${3}"
  echo "Please add the following record to the DNS zone:"
  echo "_acme-challenge.$DOMAIN IN TXT \"$TOKEN_VALUE\""
  echo "Press enter when installed!"
  read
}

function clean_challenge {
  local DOMAIN="${1}" TOKEN_FILENAME="${2}" TOKEN_VALUE="${3}"
}

function deploy_cert {
  local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" CHAINFILE="${4}"
}

HANDLER=$1; shift; $HANDLER $@

最後に実行権限を付けます。

$ chmod +x /etc/dehydrated/hook.sh

dehydratedで証明書を取得・設定

以下のコマンドを実行して、証明書の取得と認証を行います。

$ /usr/bin/dehydrated --cron --challenge dns-01 --domain nis.example.com --hook /etc/dehydrated/hook.sh

# INFO: Using main config file /etc/dehydrated/config
# INFO: Using additional config file /etc/dehydrated/conf.d/config.sh
 + Generating account key...
 + Registering account key with ACME server...
Processing nis.example.com
 + Signing domains...
 + Creating new directory /var/lib/dehydrated/certs/nis.example.com ...
 + Generating private key...
 + Generating signing request...
 + Requesting challenge for nis.example.com...
Please add the following record to the DNS zone:
_acme-challenge.nis.example.com IN TXT "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Press enter when installed!

ここで一旦処理が停止します。表示された情報でDNSレコードの設定を行います。

ホスト名として「_acme-challenge.nis.example.com」を、タイプは「テキスト」とし、コンテンツには表示されている文字列を設定します。

record edit stardomain

画像はスタードメインのものですが、ほかの業者でも同じようなフィールドがあるはずです。

設定が済んだらターミナルの画面へ戻り、Enterを押して処理を再開させます。

stunnelのインストールと設定

stunnelをインストールします。こちらはリポジトリの追加無しです。

$ apt-get install stunnel4 -y

/etc/stunnel/stunnel.conf を以下の内容で作成してください。

$ vim /etc/stunnel/stunnel.conf

[nis]
accept = 7891
connect = 127.0.0.1:7890
cert = /var/lib/dehydrated/certs/nis.example.com/fullchain.pem
key = /var/lib/dehydrated/certs/nis.example.com/privkey.pem

[websocket]
accept = 7779
connect = 127.0.0.1:7778
cert = /var/lib/dehydrated/certs/nis.example.com/fullchain.pem
key = /var/lib/dehydrated/certs/nis.example.com/privkey.pem

/etc/default/stunnel4 を開いて ENABLED=1 と書き換えます。

vim /etc/default/stunnel4

これで設定は完了です。サーバを再起動します。

NISがサービス化されていない場合は手動で立ち上げなおしてください。

これでNISにアクセスできるようになったはずです。

証明書の自動更新

Let’s Encryptの証明書は期限が三ヶ月なので、自動的に更新コマンドが叩かれるようにします。

crontab -e で以下の内容を追記します。

0 2 * * 6 /usr/bin/dehydrated --cron
2 2 * * 6 /etc/init.d/stunnel4 reload

時間は各々お好きなように設定していいと思います。

Service WorkerやWebRTCなどを駆使したサービスを作ろうと思うとブラウザのセキュリティがhttps通信を要求してきます。

そのため、NISへのリクエストもhttpsで行わなくてはいけません。

現状、httpsのセットアップをしたところでインセンティブは無いし、余計な設定がセキュリティホールになる可能性あるので、SN保有者はあまりやりたがらないでしょう。

なので何のメリットもなくサーバを立てる人もあまりいないのではないかと思われます。

(あるとすれば自分の管理下にあるサービスのためだけにhttpsを通したNISを立てるくらい)

http APIでアクセスでき、Web技術によってnemコンテンツを作れるという良い部分を活かすには、乗り越えなければならない課題です。

(NISの設定にはhttpsの項目があるにはあるんですが、実装されていないのか、どうつかうのかが不明です。このnemブログ記事があるということは多分実装されてないのでしょう)

現状でHTTPSの対応をしているノードは以下の通りです。また安定稼働しているものが見つかったら追記したりします。(もしくは情報提供よろしくお願いします)

testnet

mainnet