はんドンクラブ 運営ブログ

Mastodonインスタンス「handon.club」の運営ブログです。コラムなど,Mastodonに関する一般的な記事も投稿予定です。

ストリーミング障害発生のお詫びとご報告

みなさんこんにちは。はんドンクラブ管理人のはんです。

本日は先日発生したストリーミング障害に関するお詫びと、発生原因や再発防止策のご報告をさせていただきます。

概要

  • 日時: 2023年8月29日 23:04 - 9月4日 23:59、および 2023年9月5日 6:16 - 14:14
  • 対象: すべてのユーザー
  • 内容: ユーザーストリーミングが不安定(定期的にタイムラインが更新されなくなる)

長期間にわたりストリーミングサービスが停止し、ご不便をおかけして申し訳ございませんでした。

経緯

日時(JST) 時系列
8/29 22:43 サーバー移転作業が終了し動作確認を開始
8/29 23:04 サーバー移転の動作確認が完了(このタイミングから障害が発生
8/29 23:05 ユーザー申告により問題が発生していることを認知
8/29 23:30 Redisサーバーの設定変更を行いDebugログが取得できる状態になった
8/29 23:36 RedisサーバーとStreamingコンテナ間のTCPコネクションに異常がある可能性を発見 ※結果的にこれが根本原因の一つでした
8/30 00:13 解析の結果、影響範囲軽減に有効だと判断し、 【暫定対処(1) 5分おきにStreamingコンテナを再起動】 を開始(このタイミングから障害が緩和
8/31 23:32 TCPコネクションの異常がStreamingの更新されない事象と本障害が直接関連していると断定し、対処策を本格的に検討開始
9/1 00:25 【対処案(1) ARPキャッシュTTL/TCP KeepAlive時間の調整】 を実行、同時に 暫定対処(1) を一時中断
9/1 00:30 対処案(1) 実行後に事象が再発したため、不十分と判断し、暫定対処(1) を再開
9/4 23:01 解析の結果、根本原因(後述する原因A・B・Cとその因果関係)を断定
9/4 23:22 【対処案(2) クラウドサービスのVPC設定変更等】 を実施、監視を継続
9/4 23:59 対処案(2)の効果が見られたと判断し、暫定対処(1) を中断
9/5 06:16 対処案(2) 実行後に最初に事象が再発(一時的に障害が悪化
9/5 09:02 暫定対処(1) を再開(障害が再度緩和
9/5 14:14 【対処案(3) コンテナのネットワーク設定変更】 を実行、暫定対処(1) を中断(障害が完全に回復
9/5 22:37 対処案(3) により事象が完全に回復したと判断、ユーザ周知

結果的にサービス影響は以下のとおりとなります。

  1. 全く使えない状態(サービス停止状態)
    • 合計3時間55分
    • 8/29 23:04〜8/30 0:13の1時間9分、9/5 06:16〜9/5 09:02の2時間46分
  2. 定期的にサービスが使えなくなるものの、数分以内に自動的に再接続が行われる状態(サービスデグレ状態)
    • 合計148時間58分
    • 8/30 0:13〜9/4 23:59の5日23時間46分、9/5 09:02〜9/5 14:14の5時間12分

原因

データセンター内のサーバー間の通信(TCPコネクション)が不安定となり再接続が行われた場合、MastodonがRedisのSubscribe要求を再送しますが、Redisの上限値である1024*1024を超過して送出する場合があり、かつMastodonがRedisサーバーのエラーを正しくハンドリングできていないためにタイムラインの情報がStreamingで更新できない状態となりました。

発生メカニズムの詳細

まずは構成を説明します。

構成図

要因となった動作を説明するには、メインホスト (=Streamingコンテナが動いているホスト)と Redisホスト が登場します。他にMastodonを構成するために必須なPostgresホストなどもありますが、今回の障害要因に関係ないため、この記事では記載を省略します。

メインホスト である host名 prd-host1 および prd-host2 は、Dockerでいくつかのコンテナが動いています。その中の一つがstreamingコンテナです。コンテナはbridgeでVPCに繋がっており、このbridgeではNATが行われます。

Redisホスト であるhost名 prd-redis は Redisが直接ホストで動いており、メインホストと同様にVPCに繋がっています。

さて、事象が発生するメカニズムは以下のとおりです(ただし、後の解析で、①②は③を誘発する要因の1つでしかなく、必要条件ではないことが分かっています)。

事象発生のフローチャート

  • ARPキャッシュTTL切れを契機にメインホスト → Redisホストに ARPリクエストを送出
  • ② Redisホスト → メインホストにARPリプライを応答、メインホストは正常に受け取る
  • ③ 根本原因は不明だが、メインホストがRedisホストに対して全てのTCPコネクションをリセットする要求を送出する場合がある ・・・【原因A】
  • ④ 直後にメインホストがRedisホストに対してTCPの再接続要求を送出し、3-way handshake完了後にRedis上でSubscribeリクエストを送出。このとき、元々のSubscribe量によって、Redisのmulti bulk 引数制限(1024*1024)を超過したメッセージを送出する場合がある・・・【原因B】
  • ⑤ multi bulk 引数制限を超過している場合のみ、Redisサーバーはsubscribeリクエストに対してエラー応答
  • ⑥ StreamingコンテナはSubscribe要求を再送せず、要求が認められたとして以後の処理を継続する・・・【原因C】

①②の後に100%で③が発生しています。しかし前述のとおり、③は①②のARPキャッシュTTL切れ有無によらず、発生する場合がありました。そのため、③が発生する契機は完全には解明できていません。

④はSubscribe量によるため、アクティブユーザー数によって発生する場合と発生しない場合がありました。私の感覚では10分の1〜5分の1程度です。④が発生した後、継続して⑤⑥が発生する確率は100%です。

各要因の深掘り(原因A)

特に負荷が高い状況でなくとも、当初は60秒に1度全てのTCPコネクションをリセットする送出していました。このTCPリセット送出の要因は、ホストの可能性とStreamingコンテナの可能性があります。実際にはキャプチャをVPCに接続しているNICでしか取得できなかった(=bridge側インターフェースで取得できなかった)ため断定はしておりませんが、他のコンテナで同様の問題が発生していないことから、Streamingコンテナが送出元と想定しています。

○パケットキャプチャの例

○Redisサーバー側

12249:M 05 Sep 2023 13:24:54.971 - Reading from client: Connection reset by peer
12249:M 05 Sep 2023 13:24:55.034 - Reading from client: Connection reset by peer
12249:M 05 Sep 2023 13:24:55.083 - Reading from client: Connection reset by peer
12249:M 05 Sep 2023 13:24:55.083 - Reading from client: Connection reset by peer
12249:M 05 Sep 2023 13:24:55.274 - Reading from client: Connection reset by peer
12249:M 05 Sep 2023 13:24:55.285 - Reading from client: Connection reset by peer
12249:M 05 Sep 2023 13:24:55.679 - Reading from client: Connection reset by peer
12249:M 05 Sep 2023 13:24:55.888 - Reading from client: Connection reset by peer
12249:M 05 Sep 2023 13:24:55.988 - Reading from client: Connection reset by peer
12249:M 05 Sep 2023 13:24:56.190 - Reading from client: Connection reset by peer
12249:M 05 Sep 2023 13:24:56.218 - Reading from client: Connection reset by peer

送出している原因は断定できていません。しかし、当初はARPを契機にTCP RSTを送出していたため、ARPが一つの要因であることに間違いはありません。メインホストはRedisサーバーからAPRリプライを受け取った直後100ms以内でTCP RSTを送出していました。これは再現率100%です。しかし、MACアドレスの変動などは見受けられなかったため、この原因は不明です。

一方、ARPキャッシュ時間を長くしても、この問題は完全には解消されませんでした。そのため、TCPの何らかのタイムアウト値の設定が悪く、例えばKeep Aliveの不具合が発生しているものだと考えました。DockerをBridgeで接続していたことで間にNATが居たわけですが、このNATが原因で、タイムアウトの瞬間がほぼ同時に発生しTCPクライアント・サーバー間で状態の認識に齟齬が発生した可能性が高いと考えています。

各要因の深掘り(原因B)

MastodonのStreamingプロセスの実装上、一度TCPコネクションが切断されても再度TCPコネクションを張り直し、Redisに対してSubscribeしていた内容を再度Subscribeしようとします。この実装自体に問題はありません。

しかしながら、このSubscribeを1リクエスト(1パケット)にまとめて送る仕様のようで、稀にRedisサーバーが受け取れる上限を超えて送ってしまうようです。具体的には、Redisサーバーはmulti bulkリクエストを送る場合に1024*1024までというサイズ制限があるのに、MastodonのStreamingプロセスはこれを無視して全ての要求を一度に送ってしまう ことが原因です。

○Redisサーバー側

29 Aug 2023 23:51:51.721 - Protocol error (unauth mbulk count) from client: id=502 addr=192.168.1.9:60128 fd=58 name= age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=1122 qbuf-free=31646 argv-mem=0 obl=55 oll=0 omem=0 tot-mem=61440 events=r cmd=NULL user=default. Query buffer during protocol error: '*39..$9..SUBSCRIBE..$28..timeline:access_token:XXXXXX..$17..time' (... more 994 bytes ...) ':XXXXX..$14..timeline:XXXXX..$28..timeline:XXXXX:notifications..'

※ユーザIDを含む部分はログ上でマスクしています。

○Streamingプロセス側

ERR! Redis Client Error! Error: read ECONNRESET
ERR! Redis Client Error!     at TCP.onStreamRead (node:internal/stream_base_commons:217:20)
ERR! Redis Client Error!  Error: read ECONNRESET
ERR! Redis Client Error!     at TCP.onStreamRead (node:internal/stream_base_commons:217:20) {
ERR! Redis Client Error!   errno: -104,
ERR! Redis Client Error!   code: 'ECONNRESET',
ERR! Redis Client Error!   syscall: 'read'
ERR! Redis Client Error! }

各要因の深掘り(原因C)

MastodonのStreamingプロセスは大変イケてなくて、一度RedisサーバーにSubscribe要求を断られても、それを再送するということをしません。プロセス内部的には、Subscribeされた状態だと認識しているのです。これを再度Subscribeさせるためには、TCPコネクションを完全に切断するか、プロセス毎を起動するしかありません(もっとも、TCPコネクションを完全に切断してしまうと、原因Bをもう一度引き起こすので解決しないのですが)。

対処方法

StreamingコンテナのみTCPポート4000番(Streamingプロセスが利用するポート)をホストに直接接続する構成変更を行い、本件の解決を行いました。

対処実施後の構成図

対処方針の検討プロセス

当然ですが、発生を根絶するためには、ワークフロー後段の原因から対処を検討すべきです。

そこでまず、原因Cの対処を考えましたが、断念しました。この修正のためにはMastodonの実装の確認・修正が必要ですが、Streamingのコードを読んだことすらなかったので、時間的/スキル的制約から取りえない手段でした。

次に原因Bの対処を考えます。Redisサーバーの1024*1024制限はソースコードにハードコードされており、confファイルでは変更できないことが分かりました。ということは、原因Bと同様に、この修正のためにはMastodonの実装の確認・修正が必要です。

以上から、障害認知後の初期段階から、原因Aを修正する方法のみを中心に検討を進めていました。

原因Aの対処案(1)とその評価

発生直後から、1分単位でTCPコネクションが頻繁に切れていることはわかっており、かつUbuntuで1分のタイマ値として思いつくものがARPキャッシュ・TCP Keep Aliveしかありませんでした。 そして、取得したパケットキャプチャから、ARPのタイミングとTCP RSTのタイミングが100ms以内であることを特定していましたので、まずはARPキャッシュを1日に延長することにしました。

echo xxxx >/proc/sys/net/ipv4/neigh/default/gc_stale_time

若干の影響軽減は認められたものの、根本解決はしませんでした。 これは、前述のとおり、①②のARPシーケンスは原因Aの発生原因の1つでしかなかったからです。

なお、そのほか、Kernel上でTCP Keepaliveの調整をいくつか試しましたが、こちらは効果はありませんでした。

sudo sysctl -w net.ipv4.tcp_keepalive_time=xxxx
sudo sysctl -w net.ipv4.tcp_keepalive_intvl=xxxx

原因Aの対処案(2)とその評価

他に同じ事象で困っている鯖缶がいないということは、クラウド事業者側の問題ではないかと疑いました。そこで、VPCの異常を疑いました。

他社のVPSサービスで費用を払い忘れるとネットワーク帯域を絞られた経験があったので、その可能性を考え、費用を先行してデポジットしようとしました。すると、そもそもクレジットカードの支払いに失敗しており、先月分の支払いができてない状態になっていました・・・。

支払い失敗

当初、この支払いにより障害の回復が行われたように見えていました。しかしこれも原因Aの発生確立を高める事象の1つでしかなかったようで、すぐに頻発しました。結果的に、対処案(1)ほどの効果はなかったと評価しています。

余談: 当初VultrのVPC2.0をつかっていたのですが、これだとProxy ARPをしている人がいるように見えて気持ち悪かったので、VPC1.0に戻しました。しかし、この処置により改善は見られませんでした。

原因Aの対処案(3)とその評価

主に切り分けを目的として、ネットワーク経路の被疑箇所を減らすべきだと考えました。よって、NATを除去すべきだと考えました。 具体的には、StreamingコンテナのみTCPポート4000番(Streamingプロセスが利用するポート)をホストに直接接続することで、切り分けを行おうとしました。実際には、docker-compose.yml に network_mode の設定を加え、docker compose down && docker compose up -d しました。

  streaming:
    network_mode: "host"

この変更は効果があり、結果的に一度も問題が再発せず、障害が解決しました。

対処プロセスの評価

早い段階でメカニズムを解明し、かつ原因Aの対処案策定に絞れたことは評価できると考えています。しかしながら、以下の理由により、具体的な対処案策定には時間を要してしまいましたので、改善が必要だと考えています。

  • 管理人の寝不足
    • 前日までの手順確認作業により寝不足であり、発生当日の切り分け時間が十分確保できませんでした。
  • 管理人の風邪
    • 子供から風邪をもらってしまい、寝込んでしまいました。

対処案策定から実行までの時間に問題はありませんでした。

加えて、例えばVPC等に障害が起こった場合に、原因A以外の原因で原因Bが発生し、結果的に同一障害が発生してしまうリスクは残っています。 すなわち、原因B・原因Cの本格対処が不要となったわけではありませんので、原因Bの発生を検知したらStreamingコンテナを自動再起動するようなスクリプトの開発が必要 だと考えています。

再発防止策

  • 開発環境での長期安定性試験の強化(実施中)

事前に発見できなかったのかという観点での再発防止です。 負荷がある程度ある状態でないと再現しない問題だったとはいえ、開発環境でも複数回再現していた痕跡がありました。

そのため、開発環境での試験項目に長期安定性試験を加え、Streamingの確認をより入念に行うようにします。

  • 体調管理の徹底(実施中)

もうすこし日常的に運動をして、免疫を付けたいと思います。よい運動の方法について、慎重に検討を重ねております。

また、子供(1歳)に、帰宅後は手をよく洗うようにお願いしたところ、「はい」と返事しました。これで大丈夫でしょう。

  • 原因C発生時の自動再起動スクリプトの開発(実施中)

スクリプトの開発は概ねできていますが、いくつか技術的な問題があり、苦戦中です。力業で解決できる見込みなので、2023年10月中に完了予定です。

おわりに

今回はご迷惑をおかけして申し訳ありませんでした。ひきつづき、はんドンクラブをよろしくお願いいたします。

もし引き続き調子が悪い方がいらっしゃれば個別にご連絡をお願いいたします。

新たに登録された方へ

はんドンクラブ(handon.club)へようこそ! 管理人のはん(@highemerly@handon.club)です。

数あるMastodonサーバーから、この「はんドンクラブ」を見つけてくださり、ありがとうございます。Mastodonは、Twitterと非常に似たサービスですが、意外と異なる部分もあります。ですから、もしかしたら、少しだけ取っつきにくいと感じる方もいらっしゃるかもしれません。この記事では、そんな方が悩みやすいポイントとその解説をまとめました。

決して、はんドンクラブを使う前に必ず読んでください、という訳ではありません。でも、もしMastodonを使うのが初めてで、不安なことがある方は、是非この記事を読んでみてください!

はじめに: 管理人が一番伝えたいこと

上記の投稿のとおり、PCでもスマホでも、最初はWeb(ブラウザ)を使うことをオススメします。

MastodonのWebは、とってもよくできています。更に、アカウント作成直後にログインすると、フォローするユーザーをオススメしてくれます。でも、アプリやクライアントはこのオススメユーザーに対応していない場合が多いので、最初のフォローだけでもブラウザで済ませちゃうことをオススメしているのです。

ランディングページ。+ボタンを押すことでフォローできます。エクスプローラページ。
最初のページ(左)とエクスプローラ(右)

では、オススメユーザーの探し方について、具体的にご説明します。最初のページ(図左)で、気になるユーザーを見つけ、フォローボタンを押すだけです。もしこの画面が出なかった場合や、しばらくMastodonを使ってみた後にまたオススメユーザーを見たい場合は、画面右メニューの「#(エクスプローラー)」を開いて「おすすめ」をクリックしてください。ほぼ同じ画面(図右)に飛べます。ユーザの選出方法は若干違うのですが、十分参考になると思います。

ローカルタイムライン(左)と連合タイムライン(右)

加えて、ローカルタイムライン(左)という機能もあります。これは、あなたが誰もフォローしていなくても、はんドンクラブに登録しているユーザーの公開投稿が全て勝手に流れてくるタイムラインです。このローカルタイムラインからユーザーを見つけるのもまた良いかもしれません。ちなみに、連合タイムライン(右)という似た機能もありますが、流量が多すぎるため、最初は見なくてよいですよ。

いかがでしょう。フォローを増やせましたでしょうか? もし何か分からないことがあれば、先の投稿にあったとおり、何でも気軽に聞いてください。実はこれが一番伝えたかったことです。 お気軽に管理人のはん(@highemerly@handon.club)宛にリプライを頂ければ、手が空いたときにお返しします!

どうやって投稿するの?

ここまでで、私の伝えたかったことは終わりました。以下はもう読まなくて良いので、適当に触ってみてくださいね!

・・・。まあ、それでももっと知りたいという方のために、もう少しだけ続けますね。

投稿欄

まずはとりあえず投稿してみましょう。 初期設定でかつ誰にもフォローされていなければ、はんドンクラブのローカルタイムラインにだけ流れ、他のサーバーには流れません。 気楽に挨拶でもしておきましょう。

もしかしたら、ローカルタイムラインを監視している暇人がフォローしてくれるかもしれません。気に入った方であれば、フォローを返してみてくださいね。それか、フォロー有無に関係なく、ローカルタイムラインに投稿している他の人の投稿にリプライを送ってみてもといいかもしれませんね。

この投稿は全世界に伝わってしまうの?鍵垢にできるの?

はんドンクラブ所属のユーザーであれば、ローカルタイムラインで誰でもあなたの投稿を見ることができます。時間が経つと、他のサーバーでも見えるようになるでしょう。

でも、 設定変更により、Twitterの鍵垢と同じように、あなたが許可した人にしか投稿を見せなくすることができます。 ただ、Mastodonは高機能な故にすこしだけ複雑な設定が必要です。すなわち、

  • 投稿単位での公開範囲設定
  • アカウント単位での公開範囲設定(=フォロー許可設定)

の2つが別々に設定できるようになっており、Twitterの鍵垢と同じことをするには両方の設定を変えなくてはならないです。

具体的には、各投稿毎の公開範囲設定を「フォロワー限定」にして、かつ、アカウントの設定で「承認制アカウントにする」にする必要があります。 長くなるので、具体的な設定方法の説明は省略させてください(知りたい方はリプライしてください)。

ちなみに、一見複雑でめんどくさそうに思えますが、この「各投稿毎に公開範囲を設定できる」という仕様は慣れるととても便利です。例えば、普段は鍵垢として運用しながら、拡散したい投稿だけ公開投稿とすることができますよね。

なお、投稿毎の公開範囲は以下の4つが選べるようになっています。

投稿ごとの公開範囲 概要
公開 初期設定/通常の公開投稿
非収載 ローカルタイムラインには流れないが、アカウントページからは誰でも閲覧できる
フォロワー限定 フォローされているユーザーしか閲覧できない
指定された相手のみ いわゆる「ダイレクトメッセージ(DM)」

4つの違いは少し難しいので、まずは気にせず初期設定のまま、「公開」投稿をするのがオススメです。繰り返しですが、「フォロワー限定」の投稿をしても、アカウントの設定で「承認制アカウントにする」を有効にしていない場合、誰でも許可なくフォローできる状態ですので、結果的にその投稿は誰でも見れてしまいますからご注意ください。

他のサーバーの人をフォローできるの?フォローするために、他のサーバーにもアカウントを作った方がいいの?

フォローできます。ですから、他のサーバーのアカウント作成を急ぐ必要はありません。

Mastodonサーバーには連合という機能があり、はんドンクラブ以外のサーバーと勝手に連携して動く仕組みになっています。つまり、あなたは、はんドンクラブ以外のサーバーの人ともコミュニケーションを取ることができます。ただ、ローカルタイムラインには他のサーバーの投稿は流れませんから、そのユーザーのIDをどうにかして仕入れてきてフォローする必要があります。

フォローしたいユーザーのIDは、短縮形ではなく正確なIDを知る必要があります。ここで、「正確な」IDというのは、@username@domain のように、@マークが2つある形式のことです。例えば、あなたの登録したIDが donmi で、登録先がはんドンクラブなら、あなたの正確なIDは @donmi@handon.club となります。所属するサーバーが異なれば短縮形のIDはかぶる可能性がある、つまり @donmi@example.com と @donmi@handon.club が別の人かもしれないので、正確なIDが必要なんです。技術的には、メールアドレスに近いです。いずれにせよ、この正確なIDをフォローしたいユーザーに直接聞くなどして、あらかじめ控えておいてください。

エクスプローラーで他サーバーのユーザを探す

後は簡単です。教えてもらった正確なIDをエクスプローラの検索窓に打ち込み、Enterキーを押します。すると、そのユーザーが表示されるはずです。その画面でフォローしちゃいましょう。

ちなみに、フォローしたいユーザーがMastodon以外のソフトウェア、例えばMisskeyやPleromaといった他の分散型SNSを使っていても、はんドンクラブからフォローできます。ですから、はじめてMastodonに登録したあなたは、他のサーバーにアカウントを作る必要はありません。 もちろん、使いこなしてきた後、他のサーバーの雰囲気を知りたいとか、Misskeyをやってみたいとか、そういった用途でアカウントを増やすことはよいと思います。

おすすめの設定があったら知りたい!

設定

以上です!

用語が分からない!

  • トゥート: TwitterでいうTweet。投稿のこと*1
  • ブースト: TwitterでいうReTweet
  • リモートフォロー: 別サーバーの人をフォローすること。
  • HTL: ホームタイムラインのこと。Twitterにもある、通常のタイムライン。
  • LTL: ローカルタイムラインのこと。そのサーバーの人の公開投稿が流れる。
  • FTL: 連合タイムラインのこと。そのサーバーで認知しているユーザー*2全員の公開投稿が流れる。
  • インスタンス: サーバーのこと。たくさんあるMastodonサーバーのうち、1つだけ特定のサーバーを差して使う*3
  • Fediverse: MastodonやMisskeyなど、多数の分散型SNSサーバーが繋がっている空間全体を指す、ちょっと概念的な言葉。ただ、最近は分散型SNSのことを総称してFediverseと呼ぶ場合が多いです。
  • NSFW: Not safe for work。閲覧注意フラグという言い方が正確。ちょっとアレなトゥートやネタバレなどを一時的に隠して投稿できる。
  • CW: Content warning。ちょっとエッチな画像を一時的に隠して投稿できる。
  • カスタム絵文字: 管理人が登録した特殊な絵文字。そのサーバーに属している人なら誰でも使える。他のサーバーの人は使えないけど、あなたの投稿で使われたカスタム絵文字は見ることができるので、気軽に使ってみよう。

もっと深く知りたい!

まきはらさんのとてもわかりやすいまとめです。この記事との重複もありますが、ぜひどうぞ。

prgm.x0.com

はんドンクラブでは、他のMastodonサーバーにない独自機能を実装しています。詳しくはこちらをどうぞ。

handon.hatenablog.jp

*1:正確には、現在はトゥートという表記は正式ではなく、「投稿」「ポスト」と呼称します。ただ、古い表記である「トゥート」を使うユーザーが多いです。

*2:分散SNSの仕組み上、全てのユーザーを全てのサーバーが知っている訳ではありません。例えば、誰一人としてフォローしていない別のサーバーのユーザーは、そもそも自分の所属サーバーから存在を認知できません。その場合は、連合タイムラインには流れません。

*3:正確には、現在はインスタンスという表記は正式ではなく、「サーバー」と呼称します。ただ、古い表記である「インスタンス」を使うユーザーが多いです。

はんドンクラブの利用規約を変更します。

Mastodonの新しいシステムに対応するため、利用規約を更新します。 意図を変えているつもりはありませんが、文章構造が変わっているため、内容をご確認ください。

**2023/2/4 追記 何ヶ所か微調整を行い、期限を延長しました。**

  • プライバシーポリシーに更新はありませんので、このページからは記載を省略しています。
  • Mastodonのシステムの都合上、「利用規約」を「サーバーのルール」と言い換えます。
  • 不安な点があれば、2023/2/62023/2/11までにお問い合わせください。問い合わせが無ければ、2023/2/72023/2/12以降に本サーバーのルールを適用します。

更新のポイント

  • 規約の構造を修正しました。
    • 利用者に守って頂く必要がある事項のみ、"サーバーのルール" に記載することにしました(通報時、このルールを選択する必要があるためです)。結果、他の免責事項などの利用規約は "その他" に移動しました。
    • その他、文意が変わらない範囲で、段落を組み替えました。
  • 「みんな仲良くしてください。」の意図を明確にしました。
  • 細かな文言修正を行いました。
    • Mastodonインスタンス」を「Mastodonサーバー」へ変更しました。
    • 「サーバー」「サーバ」や「ユーザー」「ユーザ」などの表記揺れを修正しました。

更新後

Mastodonサーバーのはんドンクラブ(以下,本サービス)をご利用いただく場合,以下の「サーバーのルール」と「プライバシーポリシー」の両方に同意するものとします。

サーバーのルール

サーバーのルールに概要を記載しています。このページでは,補足を含め,ルールの原本を記載します。

1. みんな仲良くしてください。

「馴れ合いましょう」という意図ではありません。「能動的に仲を悪くする行動をしないでください」という意図です。嫌な人・投稿を見つけても,まずはブロックやミュートを活用し,自衛してください。他人に思想や行動を強いないでください。

2. 法または道徳に反する投稿はやめてください。

特に,自身が権利を有している,または適切な同意を得ているもののみ投稿してください。

3. 投稿画像や動画には,必要と認める場合は閲覧注意フラグを付与してください。

基準は皆さんの良心にお任せします。閲覧注意フラグが付いていれば,投稿内容画像や動画の制限は行いません。ただし,法に前項の規定に反する場合はこの限りではありません。

4. サーバーに過度な負荷をかけないでください。

常識的な利用(サードパーティー製クライアントの利用,多重接続,実況,動画投稿などを含む)は問題ありません。botによる大量の反復動作など,機械的かつ非常識的な利用はやめてください。

その他

  • 本サービスを利用したこと,および利用できなかったことによる損害は,いかなる場合も補償しません。
  • 投稿内容の著作権等の権利は,いかなる場合も投稿したユーザーに帰属します。
  • サーバーのルールに反する場合など,管理人が必要と判断した場合は,発言投稿またはアカウントの削除を行うことがあります。
  • サーバーのルールは以下を全て満たす場合改定できるものとし,改定後も本サービスを継続利用しているユーザーは新たなルールにも同意したとみなします。
    • 新たな規約案は適用1週間以上前に掲載し,広く意見を求めます。
    • 掲載は分かりやすい複数の方法で行います。

更新前

Mastodonインスタンスのはんドンクラブ(以下,本サービス)をご利用いただく場合,以下の「サーバーのルール」と「プライバシーポリシー」の両方に同意するものとします。

  • 1. みんな仲良くしてください。
  • 2. 法または道徳に反する投稿はやめてください。
    • 投稿内容は,投稿者が著作権等の権利を有している,または適切な同意を得ているものにしてください。
  • 3. 投稿画像や動画には,必要と認める場合は閲覧注意フラグを付与してください。
    • 基準は皆さんの良心にお任せします。
    • 閲覧注意フラグが付いていれば,投稿内容の制限は行いません。ただし,法に反する場合はこの限りではありません。
  • 4. 安定運用のため頑張りますが,万一全てが吹っ飛んでも泣かないでください。
    • 本サービスを利用したこと,および利用できなかったことによる損害は,いかなる場合も補償しません。
    • 管理者は,運営ガイドラインに従った運営を行います。ただし,本ガイドラインは都度改定できるものとします。
  • 5. サーバに過度な負荷をかけないでください。
    • 常識的な利用(サードパーティー製クライアントの利用,多重接続,実況,動画投稿などを含む)は問題ありません。
    • botによる大量の反復動作など,機械的かつ非常識的な利用はやめてください
  • 6. 利用規約に違反している場合,その他管理人が必要と判断した場合は,発言またはアカウントの削除を行うことがあります。
  • 7. 投稿内容の著作権等の権利は,いかなる場合も投稿したユーザに帰属します。
  • 8. 利用規約は以下を全て満たす場合改定できるものとし,改定後も本サービスを継続利用しているユーザは新たな規約にも同意したとみなします。
    • 新たな規約案は適用1週間以上前に掲載し,広く意見を求めます。
    • 掲載は分かりやすい複数の方法で行います。

はんドンクラブの運営について

サーバーのルール・プライバシーポリシー

プライバシーポリシー - handon.club

運営ガイドライン

管理人は,はんドンクラブを,以下3つの基本方針(「運営ガイドライン」と呼称します)に従い運営するよう努めることとします。

インフラ運用

安定運用を第一に,常時監視,データの定期バックアップ,各種作業時の検証環境による事前テスト等を行います。運用状況は可能な限りオープンにします。Mastodonの新バージョンにいち早く追従するため,ソースコード改変は最小限にします。

モデレーション

サーバブロックやアカウント停止は必要最低限とし,その内容や理由は運営やプライバシーに支障が無い限りオープンにします。通報についても,真に必要な場合のみ対処を行います。ユーザーのプライバシーを最大限尊重します。

コミュニティ

サーバ内での話題,フォロー関係,イベントやオフ会等については、サーバ管理人が管理するところではないため,特に制限しません。

また,上記運営ガイドラインに従うための具体的なアクションとして,ユーザへの注意喚起事項や実際の運営方法など(「運営に関する情報」と呼称します)を別途定めることとします。

運営に関する情報

運営に関して,必要と思われる情報をまとめたものです。管理人の意向により周知なく改定されることがあります。

管理人へのリクエスト方法

記載の無い内容で管理人へリクエストが必要な場合は、お気軽にリプライ・ダイレクトメッセージ等でご連絡ください。

レポート(スパム報告)

レポートには理由をできる限り詳細に記載して下さい。記載頂いた理由のみから客観的に判断し,処置を検討します。なお,すべてのレポートは公開される場合がある旨はご了承下さい。より詳細な事項については, 「通報」機能についてのお願いをご参照ください。

handon.hatenablog.jp

カスタム絵文字の追加

以下の条件をすべて満たす画像であれば登録を受け付けています。管理人まで個別にリプライまたはダイレクトメッセージでお申し出ください。

  • ルール: 「法に反しない」「公序良俗に反しない」
  • フォーマット: 「アスペクト比(画像サイズの縦横比)1:1」「透過png形式」「サイズ50KB以下」

アカウント削除

ユーザ設定画面からのアカウント削除は,技術的な理由により無効にしています。アカウント削除をご希望の方は,管理人まで個別にリプライまたはダイレクトメッセージで申し出てください。原則3日後までの深夜帯に処理します。

ただし,分散型SNSの性質上,他サーバへ配送済の投稿を全て削除することは保証できません。これは,はんドンクラブから連合している全てのサーバへ削除要求を送ったとしても,そのサーバが確実に削除するかどうかを掌握できないためです。管理人はユーザの"忘れられる権利"を最大限尊重し,個人運営サーバとして現実的に可能な範囲での努力を行いますが,連合先サーバでのデータ削除保証はできないことをあらかじめご承知おきください。

権利侵害の報告,情報開示請求

権利侵害の申告,法令等に基づく情報開示請求,警察・行政機関等からの問合せについては,Google Formでご連絡ください。

はんドンクラブの特徴

ユーザーの新規登録,ユーザの招待

はんドンクラブは招待制インスタンスです。招待は,はんドンクラブにアカウントをお持ちの方であれば,誰でも可能です。設定画面の「新規ユーザーの招待」よりURLを発行してください。利用規約を遵守出来る方であれば,招待する人にも人数にも制限はありません。

また,招待が無くても登録できる「承認制」も採用しています。意気込みを記載の上,登録申請をしてください。管理人の独断により承認可否を決定することをご了承ください。

独自機能

以下の記事でまとめていますので,よろしければご一読ください。

handon.hatenablog.jp

カスタムテーマ

以下のカスタムテーマを採用しており,誰でも設定で有効にできます。

ソースコード

mastodonの公式リポジトリソースコードをupstreamとし,一部独自に改変したコードが動いています。upstreamへの追従は,原則として正式なreleaseまたはpre-releaseへの追従のみとし,いわゆる"main追従"は可能な限り行いません。実際に動作しているコードについては,github で公開しており,独自部分もgithub上のcompareページで確認可能です。

マスコットキャラクター

「ドン美ちゃん」 ドン美ちゃん をよろしくお願いします。

  • アカウント: @donmi
  • 誕生日: 4月14日
  • 好きなもの: ヤクルト400LT
  • カスタム絵文字: :donmi:

運営状況

運営情報の発信

メンテナンスなどのサーバ公式情報は,以下のいずれかの方法で発信します。なお,やむを得ず予告なくメンテナンスを実施する場合もございますので予めご了承ください。

  1. HTL上部の「お知らせ」欄
  2. https://status.handon.club/
  3. このブログ
  4. ハッシュタグ #handon_info

運営費用

このサーバは各種クラウドサービスを使って運営されています。クラウドサービスには月額で費用が発生するため、以下ページで月額制でのカンパを募集しています。

ファンティア[Fantia] - はんドンクラブ (はん)

なお,カンパは決して強制ではありません。もちろん,「カンパをしていないから〇〇をしてはいけない」ということもありません。

実際にカンパをいただいた方のお名前は、 このサーバーについて - handon.club にて掲載しています。

連合状況等

Fediverseとの連合状況などをお伝えします。

連合を停止またはメディアを拒否しているサーバー

このサーバーについて - handon.club をご参照ください。

通報を受理していないサーバー

以下のサーバーからの通報は受理していません。

サーバ名 理由
ro-mastodon[.]puyo[.]jp 意図不明の通報が多く,正常な運営に著しく支障をきたしているため

プッシュ通知を送信していないサーバー

以下のアプリ・サービスへのプッシュ通知は送信しません。

アプリ・サービス名 理由
tootle ほぼ常時通知サーバーが応答せず,サーバ全体のパフォーマンスに著しく支障をきたしているため
avalanche ほぼ常時通知サーバーが応答せず,サーバ全体のパフォーマンスに著しく支障をきたしているため

なお,あくまでプッシュ通知を送信しないだけなので,その他の用途ではお使い頂けます。

リレーの利用

本サービスでは,リレーは利用していません。

その他

運営者による人的リスク

Webサービスを提供する以上,技術的に排除できない人的リスクが残ります。そのリスクとそれに対する考え方を以下のとおり説明します。

  • Mastodonに限らず全てのwebサービスに共通することですが,特定のソースコードで確かに動作していることをユーザーに対して保証する方法は世に存在しません。すなわち,技術的には,管理人は特定の改変を無断で行えてしまうため,例えばパスワードを平文で取得する改変が出来てしまいます。しかしながら,管理人はこういった改変行為を行う,または試みることは決してないと宣言します。
  • 管理人は,ダイレクトメッセージや非公開の投稿などの秘匿すべき情報であっても,技術的には閲覧できる状態にあります。これは,現在MastodonにE2E暗号化機能が存在しないための技術的な制約であり,回避不可能です。しかしながら,プライバシーポリシーに示す真にやむを得ない事項を除き,個人的な目的および趣向に基づいてそれらの情報を閲覧・公開したり,またはそれらを試みたりすることは決してないと宣言します。

届出電気通信事業

当サーバの運営は,電気通信事業として関東総合通信局に届出を行っています(届出番号: A-04-19588)。

沿革

  • 2017.04 運営開始
  • 2018.08 電気通信事業の届出
  • 2018.09 一部サーバ移転,IPv6対応
  • 2018.11 完全招待制へ移行
  • 2019.07 電気通信事業の届出先変更(関東→近畿)
  • 2019.10 100万トゥート達成
  • 2020.11 200万トゥート達成
  • 2021.05 一部サーバ移転
  • 2022.02 電気通信事業の届出先変更(近畿→関東)
  • 2022.05 300万トゥート達成

2022年年末のご挨拶

こんにちは。はんドンクラブ管理人のはんです。

2022年も残すところわずかとなりました。今年も皆様はんドンクラブをご利用いただきありがとうございました。

毎年言っているような気がしますが、元々はんドンクラブは自分用に建てたおひとり様サーバーで、正直ここまで長く続くと思っていませんでした。それがもうすぐ6周年です。みなさんがたくさん使ってくれているので、その結果私のモチベーションは一切衰えることなく運営できています。

2022年、私自身はプライベートがめちゃくちゃ忙しく投稿数は若干減ってしまいましたが、タイムラインはめっちゃ見てます。来年も引き続きたくさん投稿してくださいね。あ、もちろん私も頑張りますよ。

いくつか、はんドンクラブの状況を貼って、年末の挨拶に変えさせて頂きます。

主なイベント

  • 2022/2/4 脆弱性(CVE-2022-24307)への対応
  • 2022/2 管理人の引越に伴う電気通信事業者届出先変更
  • 2022/3/3 サイトテーマが増えました
  • 2022/4/1 3.5.Xへのメジャーアップデート
  • 2022/4/15 5周年🎉
  • 2022/5/10 300万トゥート達成
  • 2022/5/29 ステータスページの公開
  • 2022/6/18 LT大会実施
  • 2022/6/21 CloudFlareの大規模故障に伴うサービス停止
  • 2022/6/22 攻撃によるサービスのデグレ
  • 2022/7/29 動画がアップロードできない問題への対処
  • 2022/11/13 データベースサーバの移転(スケールアップ)
  • 2022/11/20 4.xへのメジャーアップデート
  • 2022/11/22 トレンド承認に協力頂く方を募集、運用開始

adventar.org

adventar.org

統計情報

基本情報

  • ローカルの情報
項目 説明
総アカウント数 371
総トゥート数 3,353,951 削除されたトゥートはカウントされません。
総ふぁぼ数 2,890,440 はんドンクラブのユーザが登録したお気に入りの数の合計です。
総ブックマーク数 10,977 はんドンクラブのユーザが登録したブックマークの数の合計です。
総被通報数 560
  • Fediverseの情報
項目 説明
総アカウント数(Fediverse) 102,232 はんドンクラブが認知している、Fediverseのアカウント数です。
総サーバ数(Fediverse) 8,144 はんドンクラブが認知している、Fediverseのサーバ数です。
  • サーバの情報
項目 説明
Postgresql 24.4GB トゥートの内容などを保存してるデータベースの容量です。
メディアストレージ 265GB トゥートに添付されている画像・動画などを保存しているデータベースの容量です。

トゥート数ランキング

自分のトゥート数から、自分が何位なのか確認してみてください。

rank トゥート数 (参考)アカウント作成日時
1 178,656 2017-04-16 3:14:45
2 163,997 2018-09-26 14:00:25
3 146,379 2017-04-19 23:46:21
4 131,224 2018-08-15 15:46:57
5 130,053 2018-09-06 12:13:56
6 120,478 2018-08-17 4:55:37
7 114,850 2017-04-14 15:25:19
8 109,053 2018-09-26 13:34:53
9 99,747 2017-12-10 5:50:00
10 95,954 2017-04-15 2:53:53
11 75,130 2018-08-21 3:56:49
12 74,348 2017-04-15 2:55:00
13 69,004 2017-04-15 1:58:28
14 67,690 2018-11-19 4:43:11
15 65,230 2018-11-19 4:44:54
16 62,461 2018-09-09 8:15:50
17 59,387 2018-08-16 13:33:58
18 57,333 2018-03-21 4:27:47
19 54,388 2017-10-07 6:55:04
20 54,232 2018-08-27 18:58:04
21 53,739 2020-01-04 15:34:32
22 52,305 2018-08-16 15:52:20
23 51,015 2019-08-16 9:27:19
24 51,003 2017-04-15 2:53:10
25 50,959 2018-08-23 10:41:05
26 48,670 2017-04-15 2:01:40
27 45,025 2018-08-17 12:06:59
28 45,005 2018-08-18 23:14:01
29 42,951 2018-12-13 10:31:58
30 42,037 2018-09-25 9:56:11
31 39,312 2018-10-19 10:33:07
32 33,396 2020-01-04 15:38:40
33 33,355 2017-04-25 0:18:50
34 31,416 2017-04-25 0:39:03
35 31,113 2018-09-19 8:50:06
36 30,990 2019-05-28 10:45:39
37 30,125 2018-08-17 17:18:25
38 30,123 2017-04-15 11:42:28
39 29,726 2018-09-05 14:53:39
40 29,189 2018-04-08 13:43:48
41 27,585 2018-08-16 6:30:05
42 26,833 2018-11-02 6:18:32
43 25,271 2018-08-16 5:59:16
44 24,877 2018-08-18 1:04:58
45 24,600 2019-03-04 12:21:16
46 24,394 2018-08-15 15:39:00
47 23,818 2018-09-07 20:46:42
48 22,591 2018-09-23 9:01:47
49 22,507 2017-04-22 10:16:54
50 20,154 2018-08-17 3:38:12
51 18,902 2019-01-20 15:15:23
52 18,890 2017-11-01 12:48:57
53 18,869 2018-08-20 13:48:26
54 17,707 2018-08-24 04:52:52
55 17,057 2018-08-15 05:07:14
56 16,526 2019-12-14 16:12:36
57 15,700 2017-04-15 03:00:31
58 15,617 2018-09-27 03:28:07
59 14,917 2018-09-01 10:00:56
60 13,604 2018-12-30 14:05:18
61 13,589 2018-08-27 00:11:08
62 10,197 2018-12-06 03:18:37
63 10,121 2017-04-19 10:59:09
64 9,856 2017-04-15 09:47:13
65 8,275 2018-08-26 03:40:14

フォロワー数

rank フォロワー数
1 693
2 426
3 368
4 333
5 301
6 297
7 293
8 283
9 198
10 191
11 188
12 185
13 182
14 162
15 160
16 159
17 157
18 154
19 153
20 152

メディア容量ランキング

自分のメディア容量は、設定画面から確認できます。

rank メディア容量 (GB)
1 14.68
2 13.39
3 11.04
4 7.28
5 6.65
6 5.39
7 4.78
8 4.51
9 4.44
10 3.93
11 3.85
12 3.72
13 3.41
14 3.24
15 3.20
16 2.97
17 2.94
18 2.87
19 2.87
20 2.77
21 2.72
22 2.46
23 2.38
24 2.27
25 2.17
26 2.15
27 2.12
28 1.86
29 1.77
30 1.72

はんドンクラブが認知している外部サーバのアカウント数

rank サーバ名 アカウント数
1 mastodon.social 12,640
2 mstdn.jp 10,653
3 pawoo.net 8,809
4 fedibird.com 2,522
5 misskey.io 2,389
6 非公開 1,604
7 mastodon.online 1,482
8 noagendasocial.com 1,173
9 poa.st 1,017
10 mstdn.social 869
11 sushi.ski 856
12 best-friends.chat 761
13 m.cmx.im 732
14 mastodon.art 723
15 fosstodon.org 717
16 chaos.social 674
17 botsin.space 642
18 mstdn.maud.io 568
19 mas.to 530
20 mastodon.cloud 524
21 vocalodon.net 421
22 alive.bar 390
23 misskey.cf 372
24 knzk.me 364
25 vivaldi.net 362
26 shitposter.club 341
27 mstdn.guru 337
28 lesbian.energy 322
29 kiwifarms.cc 322
30 freespeechextremist.com 321

容量の大きな動画がアップロードできなかった問題が解決しました

ご報告いただいていたにも関わらず長らく解決できていなかった、容量の大きな動画がアップロードできなかった問題が解決しました。分からないことも多いのですが、原因と対策について説明します。

事象の概要

  • 発生日時: 2021年5月9日(推定)-2022年7月28日23:00頃
  • 事象の内容: 容量の大きな動画のアップロードに失敗する場合がある
    • 手元での再現試験とログの解析結果から、2つの失敗事例がありました。
      • 422エラーが表示される場合
      • 500エラーが表示される場合
    • 発生条件:
      • Webまたは/api/v2/mediaを使って非同期アップロードを行う3rdパーティークライアントからのアップロードであること
        • /api/v1/mediaではおそらく問題は発生していないと思いますが、自信はありません。
      • おおむね15MB以上の動画であること
  • 原因: オブジェクトストレージへのアップロード処理に失敗していたため。
    • 2つの事象毎に原因が異なるようでした。
      1. マルチパートアップロードに失敗している
      2. アップロード自体は成功しているが、何らかのタイムアウトにより失敗したと勘違いしている
    • 当初、1. だけが原因かと思ったのですが、どうも2. もたまに発生している場合があるようです。
  • 対処: マストドン側の設定変更。
    • 2つの事象毎に以下の対処を行いました。
      1. マルチパートアップロードを行う閾値を大幅に上げ、事実上マルチパートアップロードが行われないようにしました。
      2. S3関係のリードタイムアウトを延長しました。

原因

Web側の問題のときは Api::V2::MediaController がエラーを吐き、バックエンド処理(sidekiq)側の問題のときは PostProcessMediaWorker がエラーを吐いていました。当初、バックエンドの問題に引っ張られてApi::V2::MediaControllerがエラーを吐いているのだと思っていましたが、稀に違う場合があり、バックエンド側は正常終了しているのにもかかわらずWeb側が前述の問題と同じエラーを吐いているログも見つけました。

ただ、バックエンド側が明らかにアップロードに失敗しているログが一番多くありましたので、先にここを調査しました。

2022-07-28T13:05:08.717Z pid=18954 tid=h71ve class=PostProcessMediaWorker jid=○○○○○○○○○○○○○○○ ERROR: Processing media attachment ○○○○○○○○○○○○ failed with undefined method `split' for nil:NilClass
from /home/highemerly/mastodon/vendor/bundle/ruby/3.0.0/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/file_downloader.rb:127:in `block (3 levels) in thread_batches'
/home/highemerly/mastodon/vendor/bundle/ruby/3.0.0/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/file_downloader.rb:135:in `write': undefined method `split' for nil:NilClass (NoMethodError)
#<Thread:0x00007f3f816ef290 /home/highemerly/mastodon/vendor/bundle/ruby/3.0.0/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/file_downloader.rb:123 run> terminated with exception (report_on_exception is true):

調査の結果、このバックエンド側の根本的な問題は、オブジェクトストレージをWasabiに変えた際にマルチパートアップロード(大容量のファイルを複数のチャンクに分割してアップロードする方法)が上手くいっていないことが分かりました。本当は対応しているそうなのですが、少なくともpaperclip(mastodonがS3へのアップロード処理等で使っているgem)からは使えませんでした。

wasabi-support.zendesk.com

ぐぐったところ、オブジェクトストレージをGCPにしている場合にも同じ問題が発生しているそうで、こちらの投稿を参考にさせていただいて対処しました。具体的には、マルチパートアップロードを行う閾値を大きくする(=マルチパートアップロードが起こらないような閾値にする)という設定変更を行いました。

mstdn.anqou.net

一方、422でサムネイルが作られないというエラーは、実際にアップロードが成功しているのにも関わらずAPIの内部処理がタイムアウトしていることが分かりました。以下の問題が関係ありそうだと考え、リードタイムアウトも長めにとりました。

github.com

どちらもなんと .env ファイルへの記載だけで変更できるということで、以下のような設定をいれてみました。

S3_READ_TIMEOUT=20
S3_MULTIPART_THRESHOLD=52428801

現時点では両方を設定しています。しかし、リードタイムアウトの変更は本当に必要だったのか怪しいと考えており、余裕のあるときにA/Bテストを行ってもう少し原因を追跡する予定です。

その他

実はここ最近、バックエンド(sidekiq)サーバで、特定プロセスがファイルディスクリプタを食い潰してしまい、システムが不安定になるケースが散見されていました。特に、/etc/resolve.confが開けなくなり、外部サーバ宛の配信が失敗することが多かったです。この問題はsidekiqプロセス再起動によりファイルディスクリプタは返してもらえるので、当面は定期的なプロセス再起動でやり過ごしています。しかし、今回のアップロード処理失敗によりファイルディスクリプタを食い潰していたのかもしれないですね。

以前より5分おきにlsofコマンドで開いているファイル数を監視するスクリプトを回しているので、本当にこれが原因だったのか、少し様子を見てみようと思います。

はんドンクラブの独自機能・特徴

この記事ははんドンクラブの独自機能や構成をまとめたものです。誰がいるか,どう使われているかは記載していません。管理人のメモ(仕様書)として使うことも想定しています。随時更新されます。

追加機能

Mastodonの内部処理を書き換えている追加機能で,ブラウザでも3rdパーティー製のクライアント(アプリ)でも影響するものです。

DMをホームTLに表示しない

Mastodonは,Twitterなど他のSNSと違い,ダイレクトメッセージ(DM)もホームTLに表示されます。しかし,はんドンクラブでは,①初期設定では,DMをホームTLに表示しない ②希望する場合,DMをホームTLに表示することもできる 仕様に変更しています。つまり,DMの表示は以下のとおりです。

通常 はんドンクラブ
ホーム欄 表示される* 表示されない(設定で表示される*にも変更可)
通知欄 表示される 表示される
ダイレクトメッセージ欄 表示される 表示される

*フォローしている場合に限る

設定を変更したい場合,設定→ユーザ設定→その他→DMをホームTLに表示しない で変更してください。

プロフィール絵文字

自分または他人のアイコンをカスタム絵文字のように使えます。私のアイコンであれば :@highemerly: とすることで,誰でも利用できます。best-friends.chat さんの実装を参考に,だいぶ書き換えてます。

他のサーバの実装では3rdパーティのクライアントでプロフィール絵文字が表示されない場合が多いのですが,はんドンクラブでは3rdパーティのクライアントであっても表示可能な実装に書き換えています。API上,通常のカスタム絵文字かのように絵文字の情報を渡しています。

連合については,以下の仕様となります。

  • ○ はんドンクラブのユーザは,他のサーバのユーザのアイコンを使ったプロフィール絵文字は投稿できる
  • ○ はんドンクラブのユーザは,他のサーバのユーザのプロフィール絵文字の投稿を表示できる
  • ○ プロフィール絵文字に対応しているサーバのユーザは,はんドンクラブのユーザのプロフィール絵文字の投稿を表示できる*
  • × プロフィール絵文字に対応していないサーバのユーザは,はんドンクラブのユーザのプロフィール絵文字の投稿を表示できない

* はんドンクラブの実装と同様の実装の場合。

全文検索機能

自分の投稿やお気に入り・ブックマークした投稿は全文検索が可能です。もともとMastodonある機能なのですが,別コンポーネントが必要なため有効にしているサーバは多くありません。

はんドンクラブでは,日本語検索を最適化するため,日本語専用の形態素分析を行うプラグインを導入しています。kuromojiを使っており,利用するためにソースコードを修正しています。

アナウンス機能

投稿欄の下に私からのアナウンスが表示される欄です。mstdn.maud.io さん の実装を参考に,いじっています。間違って押してしまうということで苦情が来ているので,いつか別の形で実装し直そうと思っています。実はjsonでも取れます。

パラメータのチューニング内容

追加機能というほどではありませんが,いくつか通常よりも制限を緩和しているものがありますので紹介します。ブラウザでも3rdパーティー製のクライアント(アプリ)でも影響します。

メディアファイルの制限

はんドンクラブへ投稿できる画像や動画のサイズ上限を以下のように変更しています。なお,実際にサーバに保存される画像や表示される画像は,リサイズ・圧縮・フォーマット変換が行われる場合があります。

項目 通常 はんドンクラブ
画像ピクセル数上限 1920x1080px 2880x1440px
画像サイズ上限 10MB 15MB
動画サイズ上限 40MB 65MB

その他の上限などが知りたい方は,以下のソースコードを参照してください。

github.com

投票(poll)の選択肢の制限

投票機能では,選択肢の数と投票可能期間をより柔軟に選択できるようにしています。

項目 通常 はんドンクラブ
選択肢の上限 4 16
投票期間 5,30分/1,6時間/1,3日 1,5,10,30分/1,2,6時間/1,3日

タイムライン取得上限値

タイムラインは,過去に遡れる上限値があります。400投稿から1,200投稿に増やしています。

トレンドの選出閾値

トレンドに選出される条件にはいくつかの閾値が設定されています。トレンドに選出されやすいように少々いじっています。

Webの表示形式の変更内容

3rdパーティー製のクライアント(アプリなど)では関係のない,ブラウザでの見た目だけの項目です。一番簡単にカスタマイズできるので,結構いじっています。

3.x系風UIへの修正

4.0になってUIが使いにくくなったとの声が多かったので、3.x風のUIに修正を行っています。

  • タイムライン中の無駄な余白を削除
  • タイムライン中のアイコン画像とその余白を縮小
  • タイムライン中のリプライ表記とその余白を縮小
  • スマホからのアクセス時、投稿ボタンをサイドバーに追加
  • 「投稿」を「トゥート」表記に変更
  • その他余白の微修正

ブックマークボタンの追加

各投稿にブックマークボタンが表示されるようにしています。通常はメニューの奥深くにありますが,はんドンクラブではブックマークしやすくしてあります。fedibird.com さんを参考にさせて頂いています。

→すでにバニラ(標準)にも実装されています。

カスタム絵文字のスタンプ機能

カスタム絵文字を一つだけ投稿すると,スタンプのように大きく表示されます。2つ以上投稿された場合や普通の文字(ユニコード絵文字を含む)が投稿されている場合は対象外ですが,クリックorタップすることで一時的に大きくなります。独自機能です。なお,スタンプのように大きく表示される機能は Tootoise にも実装されています。

カスタムテーマ

いくつかのカスタムテーマを取り入れています。Blacklead ThemeCanta Darkの他に,InstanceTickerを取り入れており,好きなものを選べます。

inst.ance.tk

Blacklead Theme,Canta Darkは,一部スタイルを変更し,文字を読みやすくしています。その他にもよさそうなテーマ(かつ,ライセンス上問題ないテーマ)があれば,随時取り入れていこうと考えています。

InstanceTickerは,アカウントが所属するサーバを見やすくしてくれるツールです。Type1のみ実装しています。また,自分と同一サーバのユーザのティッカーは非表示にしています。そのためローカルタイムラインにはティッカーが出現しません。

どんなテーマがあるか試してみたい方は,設定→ユーザ設定→外観→サイトテーマ から変更できます。

より見やすいVisibility

各投稿の右上にVisibility(公開範囲)を表すアイコンが表示されますが,見やすさを向上するため,以下表のような修正を行っています。

同一サーバのIDを赤文字で表示

同一サーバのユーザは,タイムライン上でのIDが赤文字になります。それ以外のユーザは,テーマに沿った色で表示されます。

はんドンロゴの表示

スマホからのアクセス時、 @inabap に頂いたはんドンクラブのロゴが表示されます。

ユーザコミュニティ

管理人が把握している外部のユーザコミュニティを紹介します。いずれも管理人は一切関与していません。

  • 投稿まとめ

hagetter.hansode.club

hndn.blazing.jp

  • おみくじ

donmikuji.netlify.app

また,私が見えていない範囲でこれ以外にもあるかもしれません。掲載を希望するものがあればお気軽に教えてください。

運営の考え方

サーバ運営の考え方をまとめたものです。

ガイドライン

handon.hatenablog.jp

カスタム絵文字の追加申請方法、アカウントの削除申請などはこちらに記載があります。

プライバシー

はんドンクラブは,全ての投稿の著作権は投稿者に帰属すると考えています。当然,日本国内の法律である改正個人情報保護法を遵守し,当該法に基づく自己の個人情報の照会はGoogle フォームで受け付けています。併せて,GDPRも一つの指針として捉えています。主に日本国内に向けてのみサービス提供しているためGDPR準拠は必須ではないと認識していますが,これを目標として設定することでユーザのプライバシー尊重に努めています。

詳しいプライバシーポリシーは以下を参照ください。

handon.club

その他法令(プライバシーを除く)

はんドンクラブは,直接料金を徴収していないものの寄附を募っていること,及びダイレクトメッセージ機能を提供していることから,電気通信事業法に基づき届出電気通信事業として総務省関東総合通信局へ届出を行っています。提供役務は「31 インターネット関連サービス(IP電話を除く。)」,提供区域は「全国」です。なお,利用者が少ないため即時報告の対象となることはありませんが,四半期報告の対象になる場合があります。

はんドンクラブは,プロバイダ責任制限法の適用を受けると考えています。発信者情報開示に関する請求や権利の侵害に関するお問い合わせは,Google フォームで行うことができます。

費用

fantia.jp

費用は原則として管理人のポケットマネーから捻出しています。しかし,よりよいサービス提供のため,ファンティアで寄附を募っています。スポット的な寄附ももちろん助かるのですが,サーバ代は月額で発生しますので,月額寄附が可能なファンティアを使っています。

また,2023年上期には毎月の収支報告ができるようにしたいと思っています。

サーバ構成

これ以降は技術的な話です。興味の無い方は読み飛ばしてください。

概要

規模

2023年3月現在

  • ヒット数: 25万〜30万アクセス / 1日
  • 転送容量: 20GB〜25GB / 1日
  • データベース容量: 28GB程度
  • メディアストレージ容量: 300GB程度

利用しているサービス・コンポーネント

サービスを提供するため,以下のサービス・コンポーネントを利用しています。

2023年3月現在

  • サービス
    • コンピューティング: さくらVPS(データ保存あり: 運用は東京,バックアップは大阪)
    • オブジェクトストレージ: wasabi(データ保存あり: 東京)
    • メール送信: sendgrid
    • CDN: CloudFlare Proプラン
    • WAF: CloudFlare Proプラン
    • レジストラ: GMO
    • ネームサーバ: CloudFlare Proプラン
    • SSL証明書: Origin-CDN間はLet's Encrypt,CDN-ユーザ間はCloudFlareが提供
    • 監視: LINE
  • コンポーネントOSS
    • OS: CentOS 7.x系
    • リバースプロキシ: nginx 独自コンパイル
    • データベース: postgresql 17.x系 (with pgbouncer), redis 7.x系
    • 全文検索: Elasticsearch 7.x系
    • テレメトリ取得・監視・可視化: prometheus, grafana

CDNは画像・動画のキャッシュのために利用しており、投稿/プロフィールをはじめとするAPI応答が保存されることはありません(cache-control: private)。画像・動画もパーソナルデータであると考えていますが、重要な情報が抜かれることはないと考えていただいてよいと思います。

2つのWebサーバは,グローバルロードバランサによるロードバランシングではなく,DNSラウンドロビンによるロードバランスが行われます。しかし,ユーザが接続するのはCloudFlareのサーバですので,実際に接続するWebサーバを選択しているのはCloudFlareです。

監視系については,CPUやディスクなどのメトリクスの監視の他,外形監視を行っています。警報は管理人のLINEに飛ぶようになっています。以下の記事も参照ください。

handon.hatenablog.jp

運用状況は,一般ユーザからもuptimerobotで確認できます。ただし,管理人による監視は,上記記載のとおりprometheus+grafana+LINEで行われています。

stats.uptimerobot.com

セキュリティ

handon.hatenablog.jp

  • アプリケーションセキュリティ
    • Mastodon本体の脆弱性には1週間以内(目標:2日以内)に対応する体制を取っています。
    • Mastodonが直接依存するパッケージや関連するパッケージなどは定期的(目標:1ヶ月に一度)にアップデートする体制を取っています。
    • CloudFlareでWAFを利用しています。精度はよく分かりませんのであまり過信していません。
  • DDoS対応
    • 現状は全ての通信がCDNを通過するため,DDoSはCDN側で緩和されます。
    • はんドンクラブサーバのIPアドレスを直接外部に公開しないことで,CDNをバイパスする攻撃が発生しないようにしています。
  • ネットワークセキュリティ
    • ファイアウォールは一般的な対策(インターネット側インターフェースで必要最低限のポートのみ公開するなど)を完了しています。
    • 管理用SSHログインについては一般的な対策(公開鍵認証を必須とする,fail2banの導入など)を完了しています。
    • TORからのアクセスは原則ブロックしています。
  • 暗号化・署名
    • ユーザとの通信は全てTLSで暗号化されます。Origin-CDN間,CDN-ユーザ間ともに,TLS1.1以下を無効化し,1.2・1.3のみで運用しています。
    • SNIを利用しているため,ガラケー,Android2.x,Windows XPIEからはアクセスできません。
    • HSTSを設定しています。
    • CloudFlareの設定上,一部弱めの暗号化スイートもオファーされる場合がありますが,普通のブラウザやOSをお使いの方には十分安全な暗号化スイートが選択されます。
    • DNSトラヒックの暗号化(DoH、DoT)やレコードの署名(DNSSEC)は行っていないため、悪意のあるユーザーや雇用主などによって通信先が傍受・書き換えられるリスクがあります。署名(DNSSEC)の導入に向けて取り組んでいます。
  • 監査
    • ログは可能な限り90日以上保管されるように設定しています。
  • DR(Disaster Recovery)プラン
    • 1日2回のオフラインバックアップを行っています。詳細は,上記の記事を参照してください。

バッチ処理

日本時間の夜間帯にいくつかのバッチ処理を実行しています。

  1. 他サーバから受信したメディアファイルの削除
    • 他サーバに所属するアカウントが投稿した画像や動画のメディアファイルなどは,一度はんドンクラブ側にキャッシュされます。しかし,容量削減のため,約1ヶ月経過したメディアはバッチ処理によって削除されます。
    • 削除されたメディアのリンクは保持しているため,リンクから当該サーバにアクセスすれば閲覧可能です。
    • はんドンクラブに所属するアカウントが投稿した画像や動画のメディアファイルは,時間が経過しても削除されません。
  2. アカウントの削除
    • アカウントの削除は他の全てのサーバへその通知を送るため,サーバにとって非常に大きな負荷となります。そのため,アカウントの削除タイミングは管理人が管理しています。
    • 概ね依頼のあった翌日の夜間帯にバッチ処理が行われます。
  3. トレンドの更新
    • トレンド更新頻度がゆっくりなため,結構短い頻度で強制的に更新しています。

その他,いくつかバッチがありますが,主なものはこれくらいです。

ソースコード

MastodonはAPGLでライセンスされているため,はんドンクラブで運用しているコードも以下で公開しています。

github.com