- » Kindle
- » iBooks
- » kobo
- » B.W.
- 200円
- » Kindle
- » iBooks
- » kobo
- » B.W.
- 400円
- » Kindle
- » iBooks
- » kobo
- » B.W.
- 300円
- » Kindle
- » iBooks
- » kobo
- » B.W.
- 100円
- » Kindle
- » iBooks
- » kobo
- » B.W.
- 200円
- » Kindle
- » iBooks
- » kobo
- » B.W.
- 490円
- » Kindle
- » iBooks
- » kobo
- » B.W.
- 200円
- » Kindle
- » iBooks
- » kobo
- » B.W.
- 600円
- » Kindle
- » iBooks
- » kobo
- » B.W.
- 200円
doncha.net制作・発行:KindleやiBooks、楽天kobo、BOOK☆WALKERで読む電子書籍
おひとり様ActivityPubサーバー自作実装メモ

ActivityPubを通じてMastodonなどFediverseと呼ばれるネット連合からアカウントとして認識されるように最低限のサーバー構成を作ったのが7/12。その後、秘密鍵・公開鍵を使えるperlのモジュールをlolipopレンタルサーバーにインストールできたことで、それっぽいものにしあがって、実際に運用して今日に至る。
「ため池」
↑perlで自作実装したおひとり様ActivityPubサーバー
そもそもMastodonやMisskeyなどのサーバーを立てるスキルがない。わたしには難易度が高すぎる。
自分のわかる範囲で自作実装したので、間違ってる・勘違いしてるところもあるかも知れないけど、今のところ意図通り。
この雑記帖と同じレンタルサーバーに展開して追加の費用なども必要ない。
自作とはいえ、スグ忘れるのでまとめてメモしておこう、というのがこのエントリ。
5分以上前の自分はアカの他人。
Fediverseからアカウントとして認識されるために必要なもの
1)nodeinfo(json)
サーバー情報。
2)host-meta(xml)
webfingerのURL。
3)webfinger(json)
ユーザー情報のURL。
4)actor.json(json)
ユーザー情報。type:Personのjson。
上から順番にアクセスされて4のユーザー情報にたどり着けばActivityPubサーバーのアカウントとして認識される。
1と2はなくても大丈夫らしいけど、webfingerのURLは「/」だったり「/.well-known/」だったりするので、2の「/host-meta」で教えてあげる。
「ActivityPubを使ってFediverseにたどり着く」
↑各ファイルの詳細。
おひとり様サーバーとして動作しているスクリプトは2つだけ。
・飛んでくるリクエストをさばく門番的スクリプト
・タイムラインを表示、投稿、管理するスクリプト
【飛んでくるリクエストをさばく門番スクリプト】
ActivityPubでの会話を求めて飛んでくるリクエストはいろいろ。
アカウント情報を取得するためにactor.jsonをリクエストされるし、ActivityとしてCreate(投稿)Follow(フォロー)などのリクエストが飛んでくる。
まず「.htaccess」を設置
rewrite ruleでパラメータをつけて門番スクリプトにリダイレクトするところからスタート。
リダイレクトされてリクエストを受けつける門番スクリプトの仕事は以下。
サーバー情報やユーザー情報はGETでリクエストが飛んでくる。
リクエストされたURLに応じて、門番は用意してある静的ファイル、jsonやxmlファイルを返す。
ActivityPubのjsonファイルは「Content-Type: application/activity+json; charset=utf-8」をヘッダにつけるのが必須。
followerやfollowingにアクセスされた時はfollower、followingを記載したテキストファイルを読んで、静的ファイルにそのリスト情報をくっつけて返すようにした。
「最低限お一人様ActivityPubサーバーにちょい足し 」
↑フォローリスト情報をつけ足した経緯。
Activityリクエストは「ユーザー名/inbox」にPOSTでリクエストが飛んでくる。
これはまとめて門番で受け取って。
・HTTPヘッダ類
・content(ボディ)
これをひとつのログファイルとして、所定のディレクトリに保存する。
ボディ=jsonを読んで、CreateだのFollowだのUndoだのログファイル名の一部にしておく。
門番スクリプトの仕事はここまで。
ヘッダ類もログファイルに収録するのは。
公開鍵とhttp signatureで、飛んできたリクエストが正しく署名されているか検証する必要がある。
Mastodonなんかはたぶんリクエストが来たらその場で検証までしてるはずで、ログファイルなど必要ないと思う。
わたしの場合、まだよくわかってないことが多くて、ログファイルで確認したいことがあるので、そのためにログファイルを残している。
ActivityのPOSTリクエストのうちいくつかは今時点スルーしている。
仕様的にはMUSTとかSHOULDだったりするものもあって、対応が必要と思われるけど、ウチの運用的にそれ必要?と微妙なもの。
Like
いわゆる「いいね」は門番のところで破棄。
Announce
ブースト(リツイート)はもし自分の投稿のブーストだったら破棄。
どちらも注目度ということなんだろうけど、それだったらサーバーのアクセスログを眺めるのが正解。
Delete
投稿の削除、だけならともかく、見知らぬアカウントの削除がけっこうなボリュームで流れてくる。なので、とりあえずDeleteも破棄。下記するけど、基本ウチは削除が前提。
【タイムラインを表示、投稿、管理するスクリプト】
あまり考えず「ため池」という名前にした。
Mastodonでいうところの「ローカルタイムライン」のために投稿用のデータベースを用意。
といっても、テーブル2つだけ。それも1つはログインに使うだけのもの。投稿用のテーブルはテキストと、画像のURLや幅・高さぐらいを記録するメモ帳。
投稿するには重複しない一意のIDが必要で、それにはデータベースが便利に使える…ほぼそのため。
おひとり様サーバー、ユーザーはわたしだけ。サーバーに登録しているユーザーの投稿を表示する「ローカルタイムライン」は、わたしの壁打ちとなる。
フォローしたひとの投稿を表示する「ホームタイムライン」はファイルで管理。
自分以外、ひと様のデータを持たないのが原則。ひと様のデータを溜め込むといろいろ考えなきゃいけないことが出てくるから。
ため池にアクセスすると、門番スクリプトが保存したログファイルを開いて。
まずはHTTP SignatureのVerify。
actor情報をリクエストして、公開鍵を取得。公開鍵を使ってログファイルのヘッダ情報にあるSignatureを検証する。
Signatureに問題がなければ、Activityに応じた所定のフォルダに、所定の命名規則で名前をつけたjsonファイルを保存。元のログファイルを削除。
「RSAモジュールで公開鍵と秘密鍵」
「HTTP Signatureをlolipopレンタルサーバーで作成」
↑秘密鍵、公開鍵について
タイムライン用に保存するjsonファイルはCreateかAnnounceのNote
・上限20個
・期間1日
ディレクトリのファイルを読んで制限以上になっていたら削除。
フォローイングが30人を超えてると、読まないまま削除される方が多いし、さらにフォローは増やすつもりなので、読む・目にする投稿の方が圧倒的に少なくなる。知らない間に流れてきて知らないうちに削除されている。
でも、SNSはそのぐらいで適正だと思う。
その時その場で見たものがすべて。「袖すり合うも他生の縁」だ。
「ホームタイムライン」用に保存するjsonファイルは「to」に「Publish」(全公開)が指定されているもの限定。
この「ホームタイムライン」を表示するにはログインが前提。つまり、見ることができるのはわたしだけだ。
ホームタイムラインの投稿にフォローしたひとのアイコンや名前を表示させるために、actor.jsonをリクエストしてpersonを取得してそこからアイコンのURLや名前を取ることになる。
これだけのためにリクエストが生じるんで、ホームタイムラインの表示が重い。
本当だったら非同期で情報を更新したいところだけど、Javascriptとか面倒くさいし、メンテやエラーの特定にあっちもこっちもになってコスト高なので却下。手動更新。
見るのが自分ひとり、一般公開はしないということから、表示が重いのは我慢、また、同じ理由でいくつかのリクエストはスルーしてもいいかな、と。
MentionとFollowは別扱い。
両方とも確認してから返事するなりフォロー返しするなりしてから手動で削除することにした。
Follow
タイムラインに表示するのが20個までなので弾幕系というか投稿数が多いひとをフォローするとタイムラインがそのひとひとりに占拠されてしまうので、事前確認することにした。
FollowをAcceptしたら、Followのjsonを保存して、followersのリストに登録する。
Following、こちらからフォローする場合も同じ。Followingに使ったjsonを保存して、followingのリストに登録する。Followingのjsonを保存するのは、フォロー解除するUndoのために、元になったjsonが必要だから。uuidでIDを作ることにしてしまって、残しておかないと元のjsonを再現できないというオチ。
Mention
連絡先としてサイトや名刺など今まではtwitterのアカウントを入れたんだけど、twitterがなくなったんで、こっちを「連絡先はこちら」にしたい。Mentionを見落としちゃまずいんで、これも確認からの手動にした。
[09/21 10:05:12]
リクエストとして飛んでくるブーストは対応済みで、こちらからブーストのリクエストを飛ばすのも実装してみた。
「おひとり様ActivityPubサーバーにブースト実装」
いろいろ考えなきゃいけないことあった(改めて)
以下のサイトを参考にさせてもらっておひとり様ActivityPubサーバーを実装することができた。感謝深謝。
「NetlifyとSupabaseでほぼ静的なActivityPubサーバ」
「Fediverse入門―非中央集権型SNSサーバを作ろう!」
「田舎の昼のサイレンbotをActivityPubで実装する(マストドンにアカウントを認識してもらう編)」
「ActivityPubの実装についてのメモ」
ActivitiPub本家本元。
「ActivityPub」
» ローカル環境で電子書籍を作る、Macアプリ・Windows版ツール 「かんたんEPUB3作成easy_epub」