Mozilla Hubsのサーバー「Reticulum」
Mozillaが提供するオープンソースのソーシャルVR「Hubs」のクライアント側は以前から触っているが、
認証周りを抜本的に改造したいなと思ったとき、
サーバー側のコードを見たい、触りたいと思った。
でもReticulumをローカルで動かしたりデプロイする方法は、
未だあまり実践されていない。
一応GitHubのReadMe記載の方法で以前試したが、上手く行かずissueを上げたところ、
本家っぽい人が解決してくれていた。
それに加えて、先日「Mozilla HubsのバックエンドサーバーReticulumを改造する方法」という記事も現れ、
ローカルで動かすだけでなく、それをAWSにデプロイする方法までセットで解決されてしまった!ありがたい。
今回はそれを実践したメモ。
そもそものHubsの設計を確認
英語だがこちらのGitHubレポジトリーに設計概要が記載されている。
https://github.com/MozillaReality/hubs-docs/blob/master/docs/dev-system-overview.md
Our network topology is a little weird. We have two backend services involved for the user-user comms. One is reticulum, which is a mesh network of erlang/elixir/phoenix nodes, and is responsible for all non-voice/video traffic between users. when you connect to a room, you are connecting to a load-balanced node on this mesh over websockets, and messages are relayed between all users in that room across the mesh via a pub/sub system called phoenix channels. Meanwhile, for voice and video, you are also connected to a shared SFU node running Janus and our Janus plugin (so all users are connected in a room to the same physical node for voice/video relay.) There is no P2P traffic. Everything operationally is captured in our ops repo.
上記によると、reticulumは音声・ビデオチャット以外のネットワーク通信を担っていて、
Elixir/Phoenixで実装されている。
ちなみに音声・ビデオチャットはJanus、Janus Pluginで行われている。
reticulumの後ろにはPostgreのDBがあり、
各種プレゼンスはここで管理されている。
VR空間はNetworked-aframeで共有してて、
それがReactのUIの中に作成されている感じかな。
Reticulumをローカルで動かす
インストール手順
基本的にはGitHubのReadMeに沿って各種インストール作業を進める
https://github.com/mozilla/reticulum
要は下記のインストールして、
・nodeJS(12.x)
・Elixir
・Phoenix
・PostgreSQL(recommended version 11.x)
・Ansible
当該GitHubリポジトリーをローカルにClone。
してからルートディレクトリに移動して下記コマンドを実行↓
mix deps.get
mix ecto.create
上記2つ目のコマンドのDB件のなんかでつまづいた場合は、postgreのパスワードが合ってないのでpsqlコマンドで下記の様にして合わせる。
ALTER USER postgres WITH PASSWORD 'postgres';
その前にそもそもpostgresqlが入ってない場合は下記リンク参照してインストール
UbuntuでPostgreSQLの操作メモ
次は、Assetディレクトリに入って下記コマンドで、諸々ライブラリをインストール
npm install
次は、rootディレクトリに戻って、下記コマンドでフォルダ作成
mkdir -p storage/dev
ここで下記コマンドを実行すると・・・
iex -S mix phx.server
Reticulumが一応動く。
で、ローカルに別途用意したHubs側から(インストール方法は割愛)、
npm run local
とすると、ローカルのHubsがローカルのReticulumを通して動きだす。
そしてhttps://hubs.local:4000?skipadmin にアクセスすると、
見事、ちゃんと動かなくてブラウザに下記の様な表示がされる。
また、Reticulum側のコンソールには下記の様なログが出てて、
[info] Running RetWeb.Endpoint with cowboy 2.6.3 at 0.0.0.0:4000 (https)
[info] Access RetWeb.Endpoint at https://hubs.local:4000
Interactive Elixir (1.10.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> 04:37:30 - info: compiled 6 files into 2 files, copied 2 in 1.0 sec
[info] TLS :server: In state :certify received CLIENT ALERT: Fatal - Certificate Unknown
[info] GET /
[debug] Processing with RetWeb.PageController
Parameters: [UNFETCHED]
Pipelines: [:secure_headers, :parsed_body, :browser]
[debug] QUERY OK source="app_configs" db=0.9ms queue=0.9ms idle=9281.6ms
SELECT a0."app_config_id", a0."key", a0."value", a0."owned_file_id", a0."inserted_at", a0."updated_at" FROM "ret0"."app_configs" AS a0 WHERE (a0."key" = $1) ["features|default_room_id"]
[debug] QUERY OK source="app_configs" db=0.5ms queue=1.0ms idle=8285.3ms
SELECT a0."app_config_id", a0."key", a0."value", a0."owned_file_id", a0."inserted_at", a0."updated_at" FROM "ret0"."app_configs" AS a0 []
[info] Sent 503 in 10040ms
一番気になるのは下「CLIENT ALERT: Fatal - Certificate Unknown」。
この現象がどうしても分からず、GitHubでissueに上げたら本家っぽい人から解決してもらえた。
その内容がこれ
要はなんかReticulumのライブラリを少し変更してるみた。
上記ページからmix.exs、mix.lockを丸コピして更新。
で、Reticulumのインストールコマンドを上記の
mix deps.get
からすべてやり直す。
そして、Reticulum実行の前にもう一つおまじないを。
これはkou029wさんの記事「Mozilla HubsのバックエンドサーバーReticulumを改造する方法」からの情報だが、
環境変数に鍵情報を登録しておく↓
export PERMS_KEY="-----BEGIN RSA PRIVATE KEY-----\nMIIEpgIBAAKCAQEA3RY0qLmdthY6Q0RZ4oyNQSL035BmYLNdleX1qVpG1zfQeLWf\n/otgc8Ho2w8y5wW2W5vpI4a0aexNV2evgfsZKtx0q5WWwjsr2xy0Ak1zhWTgZD+F\noHVGJ0xeFse2PnEhrtWalLacTza5RKEJskbNiTTu4fD+UfOCMctlwudNSs+AkmiP\nSxc8nWrZ5BuvdnEXcJOuw0h4oyyUlkmj+Oa/ZQVH44lmPI9Ih0OakXWpIfOob3X0\nXqcdywlMVI2hzBR3JNodRjyEz33p6E//lY4Iodw9NdcRpohGcxcgQ5vf4r4epLIa\ncr0y5w1ZiRyf6BwyqJ6IBpA7yYpws3r9qxmAqwIDAQABAoIBAQCgwy/hbK9wo3MU\nTNRrdzaTob6b/l1jfanUgRYEYl/WyYAu9ir0JhcptVwERmYGNVIoBRQfQClaSHjo\n0L1/b74aO5oe1rR8Yhh+yL1gWz9gRT0hyEr7paswkkhsmiY7+3m5rxsrfinlM+6+\nJ7dsSi3U0ofOBbZ4kvAeEz/Y3OaIOUbQraP312hQnTVQ3kp7HNi9GcLK9rq2mASu\nO0DxDHXdZMsRN1K4tOKRZDsKGAEfL2jKN7+ndvsDhb4mAQaVKM8iw+g5O4HDA8uB\nmwycaWhjilZWEyUyqvXE8tOMLS59sq6i1qrf8zIMWDOizebF/wnrQ42kzt5kQ0ZJ\nwCPOC3sxAoGBAO6KfWr6WsXD6phnjVXXi+1j3azRKJGQorwQ6K3bXmISdlahngas\nmBGBmI7jYTrPPeXAHUbARo/zLcbuGCf1sPipkAHYVC8f9aUbA205BREB15jNyXr3\nXzhR/ronbn0VeR9iRua2FZjVChz22fdz9MvRJiinP8agYIQ4LovDk3lzAoGBAO1E\nrZpOuv3TMQffPaPemWuvMYfZLgx2/AklgYqSoi683vid9HEEAdVzNWMRrOg0w5EH\nWMEMPwJTYvy3xIgcFmezk5RMHTX2J32JzDJ8Y/uGf1wMrdkt3LkPRfuGepEDDtBa\nrUSO/MeGXLu5p8QByUZkvTLJ4rJwF2HZBUehrm3pAoGBANg1+tveNCyRGbAuG/M0\nvgXbwO+FXWojWP1xrhT3gyMNbOm079FI20Ty3F6XRmfRtF7stRyN5udPGaz33jlJ\n/rBEsNybQiK8qyCNzZtQVYFG1C4SSI8GbO5Vk7cTSphhwDlsEKvJWuX+I36BWKts\nFPQwjI/ImIvmjdUKP1Y7XQ51AoGBALWa5Y3ASRvStCqkUlfFH4TuuWiTcM2VnN+b\nV4WrKnu/kKKWs+x09rpbzjcf5kptaGrvRp2sM+Yh0RhByCmt5fBF4OWXRJxy5lMO\nT78supJgpcbc5YvfsJvs9tHIYrPvtT0AyrI5B33od74wIhrCiz5YCQCAygVuCleY\ndpQXSp1RAoGBAKjasot7y/ErVxq7LIpGgoH+XTxjvMsj1JwlMeK0g3sjnun4g4oI\nPBtpER9QaSFi2OeYPklJ2g2yvFcVzj/pFk/n1Zd9pWnbU+JIXBYaHTjmktLeZHsb\nrTEKATo+Y1Alrhpr/z7gXXDfuKKXHkVRiper1YRAxELoLJB8r7LWeuIb\n-----END RSA PRIVATE KEY-----"
動作確認
部屋に入って動き回る
これでReticulumを実行すると、先ほどのFATAL ERRORが消えて、
Hubsが正常に動き出した。
ただ、部屋を作成して入ると中は暗闇。
それでも動き回ると、Reticulum側のコンソールに座標がガンガン入ってくるので、
なんかいい感じだ。
ローカルに立てたReticulumとhubsでやっと正常動作したっぽいかと思ったら、部屋が無くて真っ暗闇だった件。
— Hironori (@hironori_yan) January 9, 2021
追加できん。
ただ真っ暗闇の部屋でも動かすと、Reticulum走らせている側のTerminalに何かしらの座標がガンガン表示されるのはテンション上がる pic.twitter.com/T8Vj3qqPn2
サインアップ
https://hubs.local:4000/signin にアクセスして自分のメールアドレスを入れてボタンを押下する↓
するとこんな感じで確認用メール飛ばしたよー、というメッセージが出る
ただ、GitHubのReadMeにもあるが、実際にはメールは飛んでおらず、
ここではReticulumを動かしているTerminalを確認する。
アカウント有効化用のURLが発行されているので、
それを同じブラウザで呼び出すとサインイン出来る。
管理者ユーザー作成
ちなみに、最初に登録したアカウントを下記コマンドで管理者ユーザーに変更できる。
Reticulumを走らせているTerminalでiexと入力するとElixirのコードが書けるので、
そこで下記のコードを実行すると、それが可能。
Ret.Account |> Ret.Repo.all() |> Enum.at(0) |> Ecto.Changeset.change(is_admin: true) |> Ret.Repo.update!()
但し、このリンクを踏んでも503エラーが出てページが表示されない。
同じ悩みを持った人がissue上げていたが、これはまだ解決されていないようだ。
一応、これを直す話はGitHub上でされているので↓
Run admin panel locally to improve developer experience #123
近々直るかも。
少なくとも今はローカルで管理画面の確認は出来ない為、
開発中は都度都度、AWSにデプロイして進めることになる。
これでサインインしたら、先ほどのアカウントで見てみると管理画面へのリンクが出来ている↓
ローカルのReticulumをAWSへデプロイする
Chef Habitatによってデプロイする
Chef builderのインストール
インストール方法は公式ページにあり↓
https://docs.chef.io/habitat/install_habitat/
今の環境は今回はWSLのUbuntu18.04なので下記コマンドでいける
curl https://raw.githubusercontent.com/habitat-sh/habitat/master/components/hab/install.sh | sudo bash
Chef Habitatへのサインイン
下記サイトにてgithubと連携してサインイン
https://bldr.habitat.sh/
ローカルでセットアップ
hab setup
上記コマンド打つと、下記の様にメッセージが出てBuilder Instanceに接続するのか聞かれるので、ここはnoと入力。
次の質問ではDefault originを作るが聞かれるのでここはyesを入力↓
次にOrigin name聞かれる。
任意で大丈夫だが、Chef HabitatのWEBサイトに後で手で作成するOriginとは同名にする必要がある。
続いてPersonal Access Tokenを発行するか聞かれるので、yesを押下して、
出力されたTokenは控えておく
ビルド
reticulumのルートディレクトリで下記コマンド
hab pkg build .
少し時間がかかるが、
上手くいけばresultフォルダの下に.hartのファイルが作成される
アップロード
下記コマンドで先ほどビルドしたものをWEBへアップロード
hab pkg upload --channel stable {ビルドして出来たhartファイル名} -z {メモっておいたPersonal Access Token}
AWSにSSH接続してデプロイ
SSH接続は下記コマンド
ssh -i [key file] ubuntu@<server name>
keyfileも@以降のアドレスもAWSから拾える。
特に@以降のアドレスについては紛らわしいからメモっとくと、
EC2インスタンスをWEBコンソールで表示した際のここの部分↓
ちなみにEnterprize版のHubsCloudだと合計4台EC2が動いているが、
そのうち2つがReticulumが作動しているサーバーなのでそれらにだけデプロイする。
見分け方はAWSのWEBコンソールでEC2一覧を見て、右の方にスクロールしていくと見えるセキュリティグループ欄に「app」とついているものがあるかどうか(「stream」は違う)。
WSLのコンソールからだとpemファイルのPermissionに引っかかってなんか上手くいかんかったが、
Power Shellでやると何故か進んだ。
このコマンドが通ると今度はonetimepassを聞かれるので、
手持ちのスマホにアプリ「Authenticator」を入れて、
Hubs Cloudの管理画面 > Server Access にあるSHOW QR CODEというところから時限パスを取得して
時間切れになる前に入力すると、見事、EC2に潜入出来る。
からの下記コマンド(全部、kou029wさんの猿マネ)↓
# 稼働中のサービスを停止
sudo bio sup status | tail +2 | awk '$0=$1' | sudo xargs -n1 bio svc stop
# 作成した Chef Habitat パッケージのインストール
sudo bio pkg install hiro_digital/reticulum
# サービス mozillareality/reticulum を kou029w/reticulum に置換
sudo bio svc unload mozillareality/reticulum
sleep 10 # …アンロードするまで数秒待機
sudo bio svc load hiro_digital/reticulum/1.0.1/20210109112237
# 起動スクリプトの改変: hiro_digital/reticulum を読み込んで実行されるように変更
sudo perl -i -pe 's(\b(mozillareality/reticulum)\b)(hiro_digital/reticulum)g' /opt/polycosm/polycosm_boot.sh
# 起動スクリプトの改変: 起動スクリプト実行時のインスタンス名の変更に伴う証明書の更新対応
sudo perl -i -pe 's/^(ln -s)\b/ln -sf/' /opt/polycosm/polycosm_boot.sh
# 起動
sudo /opt/polycosm/polycosm_boot.sh aws aws
Reticulumの接続に失敗している。。。と思ったが
後でブラウザからサイトを見に行くと変更が反映されていた。
EC2インスタンスの名前がこの処理前後で変わっていたので、再起動がかかった結果、繋がらなくなったとかそういう理由だろうか。。
とりあえずこれでおっけー。
以上。