## fediverseに接続するサーバアプリの作り方 ![](GT-front-sj1.png) 白方 健太郎 (@argrath) --- ## Me * 白方 健太郎 (@argrath) * Wandering Programmer * 株式会社モカ代表取締役 * 社員1名 * お仕事募集中 * OSS活動系 * Perlドキュメントの日本語訳 (perldocjp) * JNetHackのカレントメンテナ * etc. --- ## Me * 白方 健太郎 (@argrath) * patreon始めてみました * http://patreon.com/argrath * よくわからない… --- ## 質問はマシュマロでも募集します * https://marshmallow-qa.com/argrath --- ## 事前アンケート --- ## twitter使ったことある人? --- ## mastodon使ったことある人? --- ## mastodon今でも使っている人? --- ## Mastodon * 非中央集権型マイクロブログサーバ * 中央サーバのないTwitterみたいなやつ --- ## Fediverse * Mastodon(など)が形成するネットワーク --- ## Actub * 1ユーザー送信専用マイクロブログPoCサーバ * Perl製 * Fediverseと相互運用可能 * https://github.com/actub/actub * このままでは動きません * インストール手順とかの文書がない --- ## fediverseを成立させている中心の機能は? --- ## リモートフォロー --- ## リモートフォロー * 他のサーバのユーザーをフォローする機能 * どのサーバのユーザーでもフォローできて自分のタイムラインを作れる * フォローしたいユーザーのサーバに合わせる必要がない * ユーザーは好きなサーバを選べる --- ## リモートフォローを実現するために必要な機能 * ユーザーの位置を発見する * 他のサーバにフォローリクエストを送る * 他のサーバの更新通知を受け取る --- ## 発見をどうするか * ex."argrath@actub.ub32.org"を解決する方法 --- ## RFC 6415 Web Host Metadata `https://(ホスト名)/.well-known/host-meta` にアクセスして情報を得る。 argrath@actub.ub32.org →https://actub.ub32.org/.well-known/host-meta --- ### https://actub.ub32.org/.well-known/host-meta ```
``` --- ### https://actub.ub32.org/.well-known/webfinger?resource={uri} --- ## RFC 7033 WebFinger ```url https://actub.ub32.org/.well-known/webfinger?resource={uri} ``` * {uri}部分をアカウントに置き換える ```url https://actub.ub32.org/.well-known/webfinger? resource=argrath@actub.ub32.org ``` --- ```url https://actub.ub32.org/.well-known/webfinger? resource=argrath@actub.ub32.org ``` ``` { "subject": "acct:argrath@actub.ub32.org", "aliases": [ "https://actub.ub32.org/argrath" ], "links": [ { "rel": "http://webfinger.net/rel/profile-page", "type": "text/html", "href": "https://actub.ub32.org/argrath" }, { "rel": "self", "type": "application/activity+json", "href": "https://actub.ub32.org/argrath" } ] } ``` --- ``` { "rel": "self", "type": "application/activity+json", "href": "https://actub.ub32.org/argrath" } ``` * https://actub.ub32.org/argrath --- ## ここからActivityPub --- ## ActivityPub * W3Cが定めた非中央集権型データ交換のためのプロトコル * MIME型: ``` application/ld+json; profile="https://www.w3.org/ns/activitystreams" ``` * 長い * リクエストのAcceptヘッダやレスポンスのContent-typeヘッダにはこれを指定 --- ## ActivityPub * https://actub.ub32.org/argrath = アクター情報の位置 * アクター=ユーザーアカウント --- ## アクター情報 ``` { "@context": [ "https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1" ], "id": "https://actub.ub32.org/argrath", "type": "Person", "url": "https://actub.ub32.org/argrath", "inbox": "https://actub.ub32.org/argrath/inbox", "outbox": "https://actub.ub32.org/argrath/outbox", "followers": "https://actub.ub32.org/argrath/followers", "following": "https://actub.ub32.org/argrath/following", "preferredUsername": "argrath", "publicKey": { "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIB...", "id": "https://actub.ub32.org/argrath", "owner": "https://actub.ub32.org/argrath" } } ``` --- ## これは何 * ActivityStreams2 (AS2) で規定されているデータ * 詳細はここでは省略 --- ## 今回の注目点 ```json "inbox": "https://actub.ub32.org/argrath/inbox", ``` * このアクターに対する通知は全てこのURLにPOSTする --- ## リモートフォローを実現するために必要な機能 * ユーザーの位置を発見する done! * フォローリクエストを送る * 更新通知を受け取る --- ## フォローリクエスト ``` { "@context": "https://www.w3.org/ns/activitystreams", "id": "https://mastodon.social/users/argrath#follows/239706", "type": "Follow", "actor": "https://mastodon.social/users/argrath", "object": "https://actub.ub32.org/argrath" } ``` --- ## フォロー承認 フォローリクエストを投げた時点で基本的には自動的に承認される ``` { "@context": "https://www.w3.org/ns/activitystreams", "id": "https://actub.ub32.org/argrath/accept/1", "type": "Accept", "actor": "https://actub.ub32.org/argrath", "object": { "id": "https://mastodon.social/users/argrath#follows/239706", "type": "Follow", "actor": "https://mastodon.social/users/argrath", "object": "https://actub.ub32.org/argrath" } } ``` --- ## ここで問題にお気づきだろうか… --- ## なりすまし放題! * だれでもinboxにPOSTできる --- ## HTTP Signatures * (現在の正式名称(?)は"Signing HTTP Messages") * 現状IETFドラフト * https://tools.ietf.org/html/draft-cavage-http-signatures-11 * HTTPリクエストに署名してSignatureヘッダをつける * 詳細は仕様を参照 --- ## HTTP Signatures ### リクエスト送信側 * 各アクターは鍵ペアを持つ * アクターの管轄サーバが自動生成 * アクターの秘密鍵でリクエストに署名 * "Signature"HTTPヘッダに署名をつけてリクエストを送信 --- ## アクター情報(再掲) ``` { "@context": [ "https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1" ], "id": "https://actub.ub32.org/argrath", "type": "Person", "url": "https://actub.ub32.org/argrath", "inbox": "https://actub.ub32.org/argrath/inbox", "outbox": "https://actub.ub32.org/argrath/outbox", "followers": "https://actub.ub32.org/argrath/followers", "following": "https://actub.ub32.org/argrath/following", "preferredUsername": "argrath", "publicKey": { "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIB...", "id": "https://actub.ub32.org/argrath", "owner": "https://actub.ub32.org/argrath" } } ``` --- ## HTTP Signatures ### リクエスト受信側 ```json "publicKey": { "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIB...", "id": "https://actub.ub32.org/argrath", "owner": "https://actub.ub32.org/argrath" }, ``` * 受信側は送信アクターの公開鍵で署名を検証する --- ## HTTP Signatures * Mastodonはこの署名がされていないPOSTを受け付けない * 従って実装必須 * 以下説明する全てのPOSTはこの署名がされているものとする --- ## フォロー解除 --- ## フォロー解除 ``` { "@context": "https://www.w3.org/ns/activitystreams", "id": "https://mastodon.social/users/admin#follows/2/undo", "type": "Undo", "actor": "https://mastodon.social/users/admin", "object": { "id": "https://mastodon.social/users/admin#follows/2", "type": "Follow", "actor": "https://mastodon.social/users/admin", "object": "https://actub.ub32.org/argrath" } } ``` --- ## リモートフォローを実現するために必要な機能 * ユーザーの位置を発見する done! * フォローリクエストを送る done! * 更新通知を受け取る --- ## 通知 * つぶやきが投稿された時にフォロワーに通知する * …の前に: --- ## つぶやき ``` { "@context": "https://www.w3.org/ns/activitystreams", "id": "https://actub.ub32.org/argrath/20180303185450", "type": "Note", "url": "https://actub.ub32.org/argrath/20180303185450", "published": "2018-03-03T09:54:50Z", "content": "はいさーい", "attributedTo": "https://actub.ub32.org/argrath", "to": [ "https://www.w3.org/ns/activitystreams#Public" ], "cc": [ "https://actub.ub32.org/argrath/followers" ] } ``` --- ## 通知 ``` { "@context": "https://www.w3.org/ns/activitystreams", "id": "https://actub.ub32.org/argrath/20180303185450/activity", "type": "Create", "actor": "https://actub.ub32.org/argrath", "to": [ "https://www.w3.org/ns/activitystreams#Public" ], "cc": [ "https://actub.ub32.org/argrath/followers" ], "object": { "id": "https://actub.ub32.org/argrath/20180303185450", "type": "Note", "url": "https://actub.ub32.org/argrath/20180303185450", "published": "2018-03-03T09:54:50Z", "content": "はいさーい", "attributedTo": "https://actub.ub32.org/argrath", "to": [ "https://www.w3.org/ns/activitystreams#Public" ], "cc": [ "https://actub.ub32.org/argrath/followers" ] } } ``` --- ## 通知 ``` { "@context": "https://www.w3.org/ns/activitystreams", "id": "https://actub.ub32.org/argrath/20180303185450/activity", "type": "Create", "actor": "https://actub.ub32.org/argrath", "to": [ "https://www.w3.org/ns/activitystreams#Public" ], "cc": [ "https://actub.ub32.org/argrath/followers" ], "object": { // つぶやき情報 } } ``` --- ## リモートフォローを実現するために必要な機能 * ユーザーの位置を発見する done! * フォローリクエストを送る done! * 更新通知を受け取る done! --- ## できた! --- ## 第一部完! --- ## 時間を確認して余裕があれば以下落ち穂拾い --- ## ActivityStream2 * もう少しだけ詳しく --- ## フォローリクエスト(再掲) ``` { "@context": "https://www.w3.org/ns/activitystreams", "id": "https://mastodon.social/users/argrath#follows/239706", "type": "Follow", "actor": "https://mastodon.social/users/argrath", "object": "https://actub.ub32.org/argrath" } ``` --- ```json "@context": "https://www.w3.org/ns/activitystreams", ``` * XMLの名前空間+スキーマのようなもの * リンク先にこのJSONが含んでいるデータの情報がある * 配列にして複数書いても良い * 元となっているJSON-LDの機能 --- ```json "id": "https://mastodon.social/users/argrath#follows/239706", ``` * ユニークなID * そのサーバが管轄するURI(基本的にhttps) --- ```json "type": "Follow", ``` * このデータが表している型 --- * ここまでは必須情報、これ以外はオプション * 詳細は仕様を参照 --- ## あれはどうするのシリーズ --- ## リツイート * Announce型を使う --- ## いいね * Like型を使う --- ## 添付画像 * Note型にattachment属性を追加する --- ## ハッシュタグ * Note型にtag属性を追加する --- ## プロフィール情報(アイコンなど) * Actor型にいろいろ属性で追加する --- ## Linked Data Signature * もう一つの検証システム * つぶやきがリレーされるときに必要 * 必須ではない * Actubでは未実装 * 仕様が複雑&Perlライブラリがない… --- ## ActivityPub仕様の読み方 * http://w3c.github.io/activitypub/ * https://github.com/argrath/activitypub (部分訳) --- ## ActivityPub仕様の読み方 * Client to Server Interactions * TwitterAPIのようなもの * Mastodonは実装していない * Server to Server Interactions * fediverse関連はこちら --- ## マシュマロを確認 --- ## 終わり * 資料予定地: https://argrath.ub32.org/slide/2019/0830/builderscon.html