Docker + Tailscale で Fediverse Instances のテスト環境を構築する
追記: 2024-03-01
ここでの内容は、
にまとめているので、この Scrap は close しています。
始めに
この Scrap は、
- Docker コンテナに Tailscale を詰め込む
- Mastodon, Misskey and GoToSocial を Docker コンテナで動かす
- Mastodom, Misskey and GoToSocial 間で ActivityPub S2S 通信を動作させる
と言う事を実現するために何をやったか、と言うメモです。
色々と試行錯誤した結果を書いているメモなので、たぶん間違いとか色々あると思います。
ここのメモの内容を完了するとどうなるか
-
https://{software}.tail{id}.ts.net
と言う URL で各インスタンスにアクセスできる - Mastodon と Misskey、GoToSocial 間で ActivityPub による相互通信ができる
- アカウントを作ったり動作テストをやったりと色々できる
注意点
Tailscale 環境下で Fedivese Software を動かす際の重要な注意点
下記コメントでの 前提 でも書いてありますが、Fediverse Software のいくつか(?)は Server-Side Request Forgery を防ぐために、Private Network での S2S 通信を禁止しています。
そのため Tailscale 環境下でこの点を回避するためにはこの禁止規定を解除する必要がありますが、当然セキュアでは無いので、本番環境で使わないで下さい。
ちなみに今回は S2S 通信の挙動改善のためのローカル環境構築なので、セキュリティチェックは無効にしています。
Misskey と GoToSocial の ActivityPub 通信について
Misskey と GoToSocial の ActivityPub 通信については、Misskey 側で、
# Sign to ActivityPub GET request (default: true)
signToActivityPubGet: true
の設定が無いとそもそも通信が上手くいかない。
※ ちなみに今回の環境構築はこの点を GoToSocial 側の改変なんとかするのが目的です
前提
Tailscale 下で Fediverse Software を動かすための注意点
- まず Fediverse Software の中には private network での S2S を禁止しているものがある
- 手持ちの環境で確認したのは以下
- Mastodon
- GoToSocial
- これは Server-Side Request Forgery を攻撃を防ぐため
- なんだけど、Tailscale の IP range は
100.64.0.0/10
である- そのため Tailscale 下でこの辺りを動かそうとするとこれに引っ掛かる
- そのため今回の Scrap の中ではこの制約にパッチを当てて回避している
- しかしこれはローカルでのテストを目的としたもの
- なので 公開環境では絶対にやってはいけない
- 手持ちの環境で確認したのは以下
Dockerfile
など
Tailscale を Docker コンテナ内で動かすための 参考にしたリポジトリ
Dockerfile
FROM tailscale/tailscale:unstable
COPY bin /opt/bin
RUN chmod +x /opt/bin/*.sh
bin
以下
何をしているか
基本的には /usr/local/bin/containerboot &
で tailscale/tailscale:unstable
のコンテナ内の tailscale
一式を動かし、次いで tailscale serve
で http への reverse proxy を動かしている。
今のところこう言う感じのスクリプトを置いている
#!/bin/ash
trap 'kill -TERM $PID' TERM INT
echo "Starting Tailscale daemon"
/usr/local/bin/containerboot &
PID=$!
wait ${PID}
until tailscale --socket /tmp/tailscaled.sock serve https:443 / http://127.0.0.1:3000 ; do
sleep 0.1
done
wait ${PID}
#!/bin/ash
trap 'kill -TERM $PID' TERM INT
echo "Starting Tailscale daemon"
/usr/local/bin/containerboot &
PID=$!
wait ${PID}
until tailscale --socket /tmp/tailscaled.sock serve https:443 / http://127.0.0.1:3000 ; do
sleep 0.1
done
until tailscale --socket /tmp/tailscaled.sock serve https:443 /api/v1/streaming http://127.0.0.1:4000 ; do
sleep 0.1
done
wait ${PID}
#!/bin/ash
trap 'kill -TERM $PID' TERM INT
echo "Starting Tailscale daemon"
/usr/local/bin/containerboot &
PID=$!
wait ${PID}
until tailscale --socket /tmp/tailscaled.sock serve https:443 / http://127.0.0.1:3000 ; do
sleep 0.1
done
wait ${PID}
docker-compose.yml
での使い方
今のところはこう:
services:
tailscale:
build: ../tailscale
environment:
TS_AUTHKEY: "tskey-auth-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
TS_STATE_DIR: /var/lib/tailscale
TS_USERSPACE: 1
TS_EXTRA_ARGS: --hostname=gotosocial
TS_OUTBOUND_HTTP_PROXY_LISTEN: "127.0.0.1:1055"
TS_SOCKS5_SERVER: "127.0.0.1:1055"
volumes:
- ../tailscale/state/gotosocial:/var/lib/tailscale
command:
- /opt/bin/gotosocial.sh
なお volumes
と command
は各実行環境毎に調整していて、かつ TS_AUTHKEY
は Tailscale の dashboard から発行したものを使っている。
またこの設定を加えた docker-compose.yml
では各サービスの network
系の設定を削除し、その上で network_mode: "service:tailscale"
を指定する。
注意事項
- tailscale serve で https を使うためには tailscale での設定が必要
- これは https://login.tailscale.com/admin/dns の一番下のトグルで有効にする必要がある
Mastodon 編
事前準備
$ git clone -b refs/tags/v4.1.2 https://github.com/mastodon/mastodon
Mastodon へのパッチ
diff --git a/app/lib/request.rb b/app/lib/request.rb
index 0508169dc..17e24f12e 100644
--- a/app/lib/request.rb
+++ b/app/lib/request.rb
@@ -273,9 +273,7 @@ class Request
alias new open
def check_private_address(address, host)
- addr = IPAddr.new(address.to_s)
- return if private_address_exceptions.any? { |range| range.include?(addr) }
- raise Mastodon::PrivateNetworkAddressError, host if PrivateAddressCheck.private_address?(addr)
+ return
end
def private_address_exceptions
Masatodon のセットアップ
をコンテナ環境に読み替えてやっていく。
注意点
postgres
これは下記の様な感じでやっていく
$ docker compose run postgres bash
# su - postgres
# psql
> CREATE USER mastodon CREATEDB;
> \q
# exit
# exit
$
Mastodon のセットアップ
$ docker compose run web bash
でコンテナに入る。
ただし RAILS_ENV=production bundle exec rake mastodon:setup
を打つときには Postgres や Redis が立っている必要があるので、別の Terminal などから、
$ docker compose up db redis
あたりをやっておく。
Mastodon のドメイン
tsnet のドメインは、
https://{hostname}.tail{Id}.ts.net/
と言う感じになっているので、基本的にはこのドメインを指定しておく。
Misskey 編
事前準備
$ git clone -b master https://github.com/misskey-dev/misskey
初期設定
基本的には、
の順番通りにやってく。
ただしドメインは Mastodon と同じく {hostname}.tail{Id}.ts.net
を指定し、.config/default.yml
に下記を設定しておく。
allowedPrivateNetworks: [
'127.0.0.1/32',
'100.64.0.0/10'
]
あとの残りは、
-
services
にtailscale
を足す - ネットワーク周りを
network_mode: "service:tailscale"
と指定する
と言った辺りをやっておく。
GoToSocial 編
事前準備
$ git clone https://github.com/superseriousbusiness/gotosocial
GoToSocial へのパッチ
結構差分がデカい。
diff --git a/internal/httpclient/sanitizer.go b/internal/httpclient/sanitizer.go
index 46540fd8..19ee8865 100644
--- a/internal/httpclient/sanitizer.go
+++ b/internal/httpclient/sanitizer.go
@@ -20,8 +20,6 @@ package httpclient
import (
"net/netip"
"syscall"
-
- "github.com/superseriousbusiness/gotosocial/internal/netutil"
)
type sanitizer struct {
@@ -32,7 +30,7 @@ type sanitizer struct {
// Sanitize implements the required net.Dialer.Control function signature.
func (s *sanitizer) Sanitize(ntwrk, addr string, _ syscall.RawConn) error {
// Parse IP+port from addr
- ipport, err := netip.ParseAddrPort(addr)
+ _, err := netip.ParseAddrPort(addr)
if err != nil {
return err
}
@@ -41,27 +39,5 @@ func (s *sanitizer) Sanitize(ntwrk, addr string, _ syscall.RawConn) error {
return ErrInvalidNetwork
}
- // Seperate the IP
- ip := ipport.Addr()
-
- // Check if this is explicitly allowed
- for i := 0; i < len(s.allow); i++ {
- if s.allow[i].Contains(ip) {
- return nil
- }
- }
-
- // Now check if explicity blocked
- for i := 0; i < len(s.block); i++ {
- if s.block[i].Contains(ip) {
- return ErrReservedAddr
- }
- }
-
- // Validate this is a safe IP
- if !netutil.ValidateIP(ip) {
- return ErrReservedAddr
- }
-
return nil
}
GoToSocial のビルド
これは手元に Go 言語環境を整えた上でこうやる:
$ VERSION=0.9.0-mod ./script/build.sh
Docker container のビルド
docker-compose.yml
を用意した上でこうする:
$ docker compose build gotosocial
なお docker-compose.yml
については
を参考に構築して行くと良い。