Bash と Caddy サーバで ActivityPub のインスタンス(1) 他の ActivityPub インスタンスに認識させる


## 名前
Bash その他と Caddy で作るので、Baca という名前にする。

## 必要なもの

ドメイン
ドメインと紐付いているサーバ


## 下準備

1. Caddy のダウンロード
https://github.com/caddyserver/caddy
の
Release
から、自分のシステム対応の Caddy バイナリを取ってきて解凍し、そのバイナリ caddy を実行するディレクトリに置いておく。
また、Caddyfile という名前で空のファイルを作っておく。

2. SHA-256 の秘密鍵・公開鍵を作って personal というディレクトリに置いておく
```bash
mkdir personal
openssl genrsa 2048 > ./personal/private
cat ./personal/private | openssl rsa -pubout > ./personal/public
```

## 取り敢えず Mastodon その他の AP インスタンスから認識されるようにする

Mastodon その他から認識される一通りの流れは『Fediverse入門―非中央集権型SNSサーバを作ろう！』(https://gihyo.jp/dev/serial/01/perl-hackers-hub/005901 )の通り。簡単に説明すると

1. Mastodonの検索に @アクター@サーバ と入れると、Mastodonは https://サーバ/.wel-known/host-meta を探す
2. Mastodonはその host-meta にある template= 以下の https://サーバ/.well-known/webfinger?resource={uri} の {uri} に "acct:アクター@サーバ" を入れたアドレスに行く
3. そのアドレスの json の、 links -> rel が self である href の値であるアドレスに行く
4. そのアドレスに ActivitySteream 形式の person があったらそれを返す

しかし実際には AP インスタンスの多くの実装は 1 をすっ飛ばして

`https://サーバ/.well-known/webfinger?resource=acct:アクター@サーバ`

へ

Accept: application/activity+json

で GET リクエストを送っているらしく、host-meta を用意しなくても認識される。

例）
```
curl -H "Accept: application/activity+json" https://mastodon.social/.well-known/webfinger?resource=acct:Gargron@mastodon.social | jq
```
で返ってくる json の、 rel タグが self の href
https://mastodon.social/users/Gargron
へまた GET リクエストを送る。
```
curl -H "Accept: application/activity+json" https://mastodon.social/users/Gargron | jq
```
で返ってくる json が mastodon.social での Eugen Rochko 氏のデータである。
（https://mastodon.social/@Gargron.json にアクセスして得られる json と同じもの）

例おわり)

なので当面に要るものは以下

1. webfinger を記したファイル
2. person タイプの json-ld を記したファイル
3. 各エンドポイントに応じてこれらのファイルをサーブするサーバ

しかし一応、host-meta も用意する。

例としてドメイン名を「ホニャララ」、アクター名を aktor として下にそれぞれ書いてみる。
```xrd:host-meta
<XRD>
  <Link rel="lrdd" type="application/xrd+xml" template="https://ホニャララ/.well-known/webfinger?resource={uri}"/>
</XRD>
```
```json:webfinger
{
  "subject": "acct:aktor@ホニャララ",
  "links": [
    {
      "rel": "self",
      "type": "application/activity+json",
      "href": "https://ホニャララ/users/aktor"
    }
  ]
}
```
```json:aktor
{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    "https://w3id.org/security/v1"
  ],
  "id": "https://ホニャララ/users/aktor",
  "type": "Person",
  "summary": "は？ 太宰？ 違いますけど？",
  "preferredUsername": "aktor",
  "name": "アクター川龍之介",
  "inbox": "https://ホニャララ/users/aktor/inbox",
  "outbox": "https://ホニャララ/users/aktor/outbox",
  "icon": {"type": "Image",
		   "url": "https://ホニャララ/image/icon.jpg"},
  "publicKey": {
		"id": "https://ホニャララ/users/aktor#main-key",
		"owner": "https://ホニャララ/users/aktor",
		"publicKeyPem": "publicファイルに記されている公開鍵を一直線にしたもの"}
}
```

aktor ファイルの publicKeyPem タグの "publicファイルに記されている公開鍵を一直線にしたもの"には

```bash
cat -e ./personal/public | sed 's/\$/\\n/g' | tr -d '\n'
```
で表示されるものをコピーペーストする。
summary, preferredUsername タグは好きに書く。
あと icon タグを見ると分かるように ./personal/image/ ディレクトリを作ってその中に icon.jpg を置いて表示されるようにしているので、これも好みに応じて適当な画像を適当な場所において適当にパスを icon タグに記すと表示される。

この3つも ./personal ディレクトリに移しておく。

そして Caddyfile に
```
ホニャララ {

    handle_path /.well-known/host-meta {
		file_server
        root * ./personal/host-meta
	header {
            Content-Type: application/xml
	    }
	}

    handle_path /.well-known/webfinger {
		file_server
    	root * ./personal/webfinger
	header {
	       Content-Type: application/activity+json
	       }
	}

    handle_path /users/aktor {
		file_server
    	root * ./personal/aktor
	header {
	       Content-Type: application/activity+json
	       }
	}

    handle_path /image/* {
		file_server
    	root * ./personal/image/
	}

}
```
としてから

```bash
sudo ./caddy run
```
すると、Mastodon 他 AP インスタンスで @aktor@ホニャララ を検索すると見つかる筈である。


# 参考文献
- [Mastodonにアカウントとして認識されるActivityPubを実装してみる](https://qiita.com/wakin/items/94a0ff3f32f842b18a25)
- [Fediverse入門―非中央集権型SNSサーバを作ろう！](https://gihyo.jp/dev/serial/01/perl-hackers-hub/005901)
- [Caddy 2を試す](https://kazuhira-r.hatenablog.com/entry/2021/06/15/233116)
- [Caddy WebServer入門](https://qiita.com/SoraKumo/items/1ab9edec306fda4e497d)