mastodon

Mastodon 保守メモ

備忘録として残しておきます

Mastodon専用ユーザにて、Mastodonのインストールディレクトリにて操作することを前提にしています。
(非Dockerならliveディレクトリ)

参考資料

tootctl

v2.5.0より、tootctlというコマンドラインツールが追加された。
Rakeタスクでの引数指定方法等への不満から誕生したものである。

既存Rakeタスクは、tootctlに置き換えられていくものと思われる。

tootctl(v2.5.0)
$ RAILS_ENV=production bundle exec bin/tootctl help
Commands:
  tootctl accounts SUBCOMMAND ...ARGS  # Manage accounts
  tootctl emoji SUBCOMMAND ...ARGS     # Manage custom emoji
  tootctl help [COMMAND]               # Describe available commands or one specific command
  tootctl media SUBCOMMAND ...ARGS     # Manage media files

Rakeタスクの一覧

https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/List-of-Rake-tasks.md

あるいは

# すべてのRakeタスクを表示
$ RAILS_ENV=production bundle exec rails -T

# Namespace "mastodon" のタスクのみ表示
$ RAILS_ENV=production bundle exec rails -T mastodon

で、定義されているタスクが一覧(+簡単な説明文)表示される。

タスク一覧の出力例
rails mastodon:add_user                                     # Add a user by providing their email, username...
rails mastodon:confirm_email                                # Manually confirms a user with associated user...
rails mastodon:daily                                        # Execute daily tasks (deprecated)

Rakeタスクの実体

https://github.com/tootsuite/mastodon/tree/master/lib/tasks

Rails Consoleへの入り方

非Docker

$ pwd
/home/mastodon/live
$ RAILS_ENV=production bundle exec rails console
irb(main):001:0>

Docker

$ docker-compose run --rm web rails console
irb(main):001:0>

※ Docker環境がないので、動作確認はしていません

メディアファイル系

外部インスタンスの古いメディアファイルを消す

デフォルトでは7日以前のメディアファイルを消す
空き容量に困ったらとりあえず流す感じになっている

$ RAILS_ENV=production bundle exec bin/tootctl media remove
Option Description
--days=N N日前までのメディアファイルを消す。規定値は7(日)
--background 削除処理をバックグラウンドで行う(Sidekiqを使用する)。
--no-background 削除処理をフォアグラウンドで行う。規定値
--verbose バックグラウンド処理でない場合、コンソールに処理対象のIDを表示する。
--no-verbose プログレスのみ表示する。規定値
--dry-run 対象を検索するのみで、実際の削除処理を行わない。
--no-dry-run 削除処理を実行する。規定値

バックグラウンド処理を指定した場合、Sidekiqを使用して並列実行を行うため、効率よく処理を行える一方で、他キューの実行遅延・ストレージに対し負荷がかかることが想定されるので、注意が必要。
また、オブジェクトストレージを使用している場合は、DoS攻撃と間違われ規制を受ける可能性が捨てきれないので、特に注意されたい。

Rakeタスク (v2.5.0以前)
$ RAILS_ENV=production bundle exec rails mastodon:media:remove_remote

外部インスタンスユーザのアバターとヘッダ画像を更新する

全インスタンスに対して行う場合は、Rakeタスクが用意されている。
時間がかかる上、エラー落ちすることがあるので注意。

$ RAILS_ENV=production bundle exec rails mastodon:media:redownload_avatars

特定のインスタンスのみ、ということであれば、下記Rails Consoleコードを実行する。
where部分を書き換えたり追加したりすれば、様々な条件で引っ掛けることが可能

Account.where(domain: "nagoyadon.jp").find_each do |account|
    printf("%s@%s\n", account.username, account.domain)
    account.reset_avatar!
    account.reset_header!
    account.save
end; 0

引っ掛けられるカラムは、モデルを見ればだいたい分かるかも
https://github.com/tootsuite/mastodon/blob/master/app/models/account.rb

たまに効かないユーザが居るのが謎。

アカウント系

アカウントを追加する

インタラクティブに作成できるコマンドが用意されている。

$ RAILS_ENV=production bundle exec rails mastodon:add_user
  • ユーザ名とメールアドレスが必要
  • 確認メールを送信するかしないか選べる
  • パスワードはランダムに生成される(作成後に表示される)

メールアドレスを確認する

確認メールが届かねえ! そもそもメールサーバの設定してねえ! って時に

$ RAILS_ENV=production bundle exec rails mastodon:confirm_email USER_EMAIL=hoge@example.tld

特定のユーザを管理者あるいはモデレータにする、権限を剥奪する

管理者

$ RAILS_ENV=production bundle exec rails mastodon:make_admin USERNAME=hogehoge

モデレータ

$ RAILS_ENV=production bundle exec rails mastodon:make_mod USERNAME=hogehoge

権限を剥奪(一般ユーザ化)

$ RAILS_ENV=production bundle exec rails mastodon:revoke_staff USERNAME=hogehoge

管理者とモデレータの権限比較

操作 備考 管理者 モデレータ 一般
サイト設定 インスタンスの基本設定 × ×
カスタム絵文字 カスタム絵文字の登録、輸入 ×(できそうで出来ない) ×
バックエンド情報表示 Sidekiq, WebSub, PgHeroへのアクセス × ×
レポート処理 通報の確認、コメント、対応 ×
アカウント情報表示 一覧、確認、編集等 ×
招待 招待URLの生成 △(サイト設定による) △(サイト設定による) △(サイト設定による)
既知のインスタンス 一覧、再講読 × ×
ドメインブロック 一覧、ブロック、サイレンス × ×
メールブラックリスト 一覧、追加、削除 × ×

モデレータ権限でも、ローカルユーザのメールアドレスとか見えちゃうので
信頼のおける人にだけ権限を付与しよう!
※パスワードは管理者でも見えない。

存在しないリモートユーザをパージする

リモートユーザが本当に存在するか実際に問い合わせを行い、存在しなければパージする。

$ RAILS_ENV=production bundle exec rails mastodon:maintenance:purge_removed_accounts

オプションとして -f あるいは --force を与えると、確認メッセージ無しでパージを実行する。

リモートに存在せず(HTTP 404ないし410が返された場合)、
かつパージを明示的に指示した場合、そのアカウントをパージ、つまり 抹消する

証明書切れ、DNS名前解決に失敗、HTTP 404/410以外のエラーコードが返されたとき、などはスルーされる。
(メンテナンス作業中であった場合等を考慮した措置だと思われる)

https://github.com/tootsuite/mastodon/blob/master/lib/tasks/mastodon.rake#L717

その他のタスク

誰もフォローしていないユーザの購読をパージ

連合タイムラインを整理したい時に。

$ RAILS_ENV=production bundle exec rails mastodon:push:clear

アクティブユーザのホームタイムラインを再構築

ホームタイムラインが表示されない(Redisのデータが壊れた)時に。

$ RAILS_ENV=production bundle exec rails mastodon:feeds:build

システム系

Mastodonサービスのログを見たいとき

$ sudo journalctl -r -u mastodon-web
$ sudo journalctl -r -u mastodon-sidekiq
$ sudo journalctl -r -u mastodon-streaming

-r で新しいものを先に表示
-u で表示するモジュールを指定
-f も付ければ、継続監視が可能(tailみたいに)

Nginxのログを見たいとき

$ sudo cat /var/log/nginx/access_log
$ sudo cat /var/log/nginx/error_log

継続して監視したい時は、 tail -f が便利

データベースなどのバックアップを取得したいとき

アップデート手順内にメモってあるので、それを参考に実施
( pg_dump でデータベースダンプファイル取得、tarでPublicディレクトリのアーカイブ化)

https://qiita.com/kumasun/items/f17754e57120f7b13a06

Ruby Gem を再インストールしたい時

稀に壊れたりすることがあるようです。。。

$ bundle exec gem uninstall -aIx
$ bundle install

引数 -aIx で、「全てを確認無しでアンインストール」
その後、通常通りインストールする

bundler 経由で操作しないと、グローバル環境のGemに作用する?らしいので注意。

アセットをゼロから作り直したい時

$ RAILS_ENV=production bundle exec rails assets:clobber
$ RAILS_ENV=production bundle exec rails assets:precompile

clobber で webpackの出力を全消しできる

あるドメインのMXレコードを調べたいとき

MXレコード = 電子メールの配送先。

スパム登録等を避けるために「メールブラックリスト」があるが、ドメイン部分をころころ変えられていたちごっこ。ということ、よくありますよね。
実は「メールブラックリスト」機能はMXも調べてくれるのです!

メールのドメインが違っても、同じMXを使い回しているような場合は、そこを抑えれば一網打尽にできます。

しらべかた

たとえば evil.example.com のMXレコードを調べたい時

nslookup を使う例。
Windows 10 / Linux(Fedora)にて動作確認。

$ nslookup -type=mx evil.example.com
Server:         192.168.xxx.xxx
Address:        192.168.xxx.xxx#53

Non-authoritative answer:
evil.example.com   mail exchanger = 0 mail.evil.example.com.

Authoritative answers can be found from:

dig を使う例。
Linux(CentOS)にて動作確認。

$ dig mx evil.example.com

; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7 <<>> mx evil.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34355
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1280
;; QUESTION SECTION:
;evil.example.com.                  IN      MX

;; AUTHORITY SECTION:
evil.example.com.           299     IN      SOA     mail.evil.example.com. 1 3600 300 2419200 300

;; Query time: 351 msec
;; SERVER: xxx.xxx.xxx.xxx#53(xxx.xxx.xxx.xxx)
;; WHEN: Wed Jul 25 14:28:50 JST 2018
;; MSG SIZE  rcvd: 127

この結果から、メールの配送先は mail.evil.example.com であることが分かる。

パフォーマンスチューニング

(他にやれそうなことがあったら教えてください)

PostgreSQL

サーバスペックに応じたパラメータを設定する

たとえば、pgTune( http://pgtune.leopard.in.ua/ )を参考に、サーバのスペックに合ったパラメータを設定する。

Socketを使う

Unix Socketを使うことで、localhost接続よりも高速化が可能となる。

/var/lib/pgsql/data/postgresql.conf
unix_socket_directories = '/var/run/postgresql' # comma-separated list of directories

デフォルトでは /tmp をソケットディレクトリとして使用する。任意の場所に変更したりする。
設定を変更したら、PostgreSQLサービスを再起動する。

/home/mastodon/live/.env.production
DB_HOST=/var/run/postgresql

設定を変更したら、Mastodonサービス3点セットを再起動する。

pgBouncer を使う

PgBouncer とは

PgBouncer は、軽量なコネクションプーラーです。
通常、クライアントからデータベースに対して大量の接続が発生すると、接続を確立する為の時間のコストや、接続を管理する為のコンピュータリソースが多く必要となります。
このようなケースにおいて PgBouncer を使用すると、これらのコストを劇的に減少させる事ができます。
http://postgres.sios.com/modules/newbb/viewtopic.php?forum=1&topic_id=149&post_id=150

コネクションの開閉にはそこそこパワーを使うので、プールしておいて有効に使おうよ、という仕組み。

Mastodon公式ドキュメントにも、pgBouncerに関する記事がある。

tootsuite/documentation - PgBouncer Guide

Redis

Socketを使う

PostgreSQLと同様、Unix Socketを使うことで、localhost接続よりも高速化が可能となる。

/etc/redis.conf
unixsocket /var/run/redis/redis.sock
unixsocketperm 777

デフォルトではソケットを使用しない設定になっているので、コメントアウトし任意の場所に変更する。
設定を変更したら、Redisサービスを再起動する。

/home/mastodon/live/.env.production
REDIS_URL=unix:///var/run/redis/redis.sock
#REDIS_HOST=127.0.0.1
#REDIS_PORT=6379
#REDIS_PASSWORD=

設定を変更したら、Mastodonサービス3点セットを再起動する。

Mastodon

Tuning Mastodon

jemalloc を使ってメモリ最適化

jemallocとは?

jemalloc は、標準ライブラリで定義されているmalloc, free 等のメモリアロケーション APIの実装である。
http://zonomasa.hatenablog.com/entry/jemalloc_about

詳しい機能については引用元のWebページを参考にして頂きたいが、わたしのざっくりとした理解では:

  • メモリのフラグメンテーションを防止し、有効に使われるようにする
  • マルチコア・スレッド環境においてパフォーマンス向上
  • メモリ周りの不具合(リーク、オーバーフロー等)の検査ツール付

また、このパッケージについて公式ドキュメントでも紹介されている。
Tuning Mastodon - Using jemalloc

Debian系(Ubuntu等)においては、上記公式ドキュメント通りに設定すればよいが、Fedoraにおいてはパッケージ名等が違うので注意が必要。

  • パッケージ名: jemalloc (jemalloc-5.0.1-5.fc28.x86_64 等)
  • インストールパス: /usr/lib64/libjemalloc.so.2

(これは Fedora 28 x64における値なので、他の環境では異なる可能性があります)

yum-install
$ sudo yum install jemalloc
$ ls /usr/lib64/libjemalloc.so.2 
/usr/lib64/libjemalloc.so.2

mastodon-web.service および mastodon-sidekiq.service に対し、
jemallocを読み込ませるため Environment="LD_PRELOAD=/usr/lib64/libjemalloc.so.2" を追記する。
(下記はwebの例だが、sidekiqも同じように追記する。)

mastodon-web.service
[Unit]
Description=mastodon-web
After=network.target

[Service]
Type=simple
User=mastodon
WorkingDirectory=/home/mastodon/live
Environment="RAILS_ENV=production"
Environment="PORT=3000"
Environment="LD_PRELOAD=/usr/lib64/libjemalloc.so.2"
ExecStart=/home/mastodon/.rbenv/shims/bundle exec puma -C config/puma.rb
ExecReload=/bin/kill -SIGUSR1 $MAINPID
TimeoutSec=15
Restart=always

[Install]
WantedBy=multi-user.target

編集後、更新されたファイルを再読み込みし、webとsidekiqを再起動する。

$ sudo systemctl daemon-reload
$ sudo systemctl restart mastodon-{web,sidekiq}

実際にjemallocを有効にした環境においては、pumasidekiqプロセスのメモリ使用率をそれぞれ2~3割程度削減することに成功した。

その他、非技術的な部分

  • ホスティングサービス等を使用せず、独自にインスタンスを立て、自分以外の第三者にも使用できる状態にした場合、各地域の総合通信局に「電気通信事業届出」をしておいた方が無難。
  • 「サイト設定」内に連絡先を記載。メールアドレス、管理者欄を埋める。他のインスタンスのアカウントなどがあれば併記しておく。インスタンスに何かあったときに、誰かが知らせてくれるかも。

あとがき

  • 自分用にメモした内容です。必要に応じて読み替えてください。
  • こうしたほうがいいよ的なアドバイスを頂けると大変助かります
  • こんなのないの? 的なご質問には分かる範囲でお答えいたします(あまり期待しないでください)

以上