🛠️

【Misskey】特定のインスタンスとのみ連合できるようにする

2022/07/18に公開1

建てたインスタンスが実験目的であるなど、連合したいが通常運用しているインスタンスとは連合したくないというレアなケースが生まれる場合があります。
その場合にどのようなことをして実現したかを記事にしました。

使用するもの・環境など

アクセスできるインスタンスを制限するため、サーバー側ではプロキシサーバーソフトウェアのSquidを、クライアント側ではCloudflareを使います。

サーバーの環境は以下のとおりです。
OS: Ubuntu 20.04
Squid: 4.10
Squidは大抵のサーバーOSで標準インストールが可能ですので、インストール時にはパッケージ名を確認してください。

手順

1. Squidをサーバーにインストールする

Ubuntuではパッケージ名squidでインストールできます。

sudo apt install squid

2. Squidの設定を変える

今回Squidを使う目的は連合できるインスタンスを制限するためですので、デフォルトの設定は使いません。元々の設定ファイルはバックアップします。

sudo cp /etc/squid/squid.conf /etc/squid/squid.conf.old
sudo rm /etc/squid/squid.conf

その後新たに/etc/squid/squid.confを作成し、以下の内容を書き込みます。

/etc/squid/squid.conf
http_port 3128

acl Whitelist dstdomain "/etc/squid/acl/misskey_whitelist.txt"
http_access allow Whitelist
http_access deny all

deny allすることで、ホワイトリスト制にしています。

http_port

Squidがリッスンするポートとアドレスの設定です。ここではデフォルトのポート3128にしています。
localhostだけで運用する場合は127.0.0.1:3128にしておいたほうが無難かと思われます。

acl

aclディレクティブではアクセス制御の設定を行うことができます。
書式は acl <ACLセット名> <種類> ...となっています。
今回の設定では種類がdstdomainとなっています。「これはSquidが通信できるホストの設定である」という意味になります。設定ファイル内ではWhitelistという名前で参照することができます。

http_access

指定されたACLを元にアクセス制御を実際に行います。
特定のものを許可したいときは、最初にいろいろ許可して、後からdeny allをするのがSquidの仕様らしいです。奇妙ですね。

通信をプロキシ経由でしたい場合

VPSのIPを露出しないようにプロキシをMisskeyで使用していた場合は、Squidに上位サーバとして参照させることで、引き続きプロキシを使用できます。

以下の設定を書き足すことで実現できます。

/etc/squid/squid.conf
cache_peer [PROXY_SERVER_HOST] parent [PROXY_SERVER_PORT] 0 no-query
never_direct allow all

[PROXY_SERVER_HOST]にプロキシのホスト名、[PROXY_SERVER_PORT]にプロキシのポート番号を入れます。
never_directディレクティブで、すべてのリクエストを上位サーバー(今設定したプロキシサーバー)を経由するように指定しています。

3. ホワイトリストを作成

ディレクトリ /etc/squid/acl を作成します。

sudo mkdir -p /etc/squid/acl

その中に misskey_whitelist.txt を作成します。
このファイルに、通信を許可するインスタンスのホスト名を改行区切りで書き込みます。
注意点として、インスタンスがオブジェクトストレージを使っている場合は、そのストレージのホストもホワイトリストに含める必要があります。これをやらないと、アイコンやアップロードされた動画・画像が表示されなくなります。もしオブジェクトストレージを使っているようだがホスト名が分からない場合はインスタンスの管理者に問い合わせてください。

4. 設定を反映させる

sudo systemctl restart squid でSquidを再起動することで反映されます。ホワイトリストを更新した後もサービスの再起動が必要です。

5. Cloudflareの設定をする

次にCloudflareでアクセスを受け入れるインスタンスの設定を行います。
先にドメインを追加しておきます。
その後、左側のメニューからセキュリティ→WAFと進み、ファイアウォール ルールの設定を表示させます。
右側の「ファイアウォール ルールを作成」をクリックして、新しくルールを作成します。

本当であればグラフィカルな式ビルダーを使いますが、式の都合上使えないので右下にある「式の編集」をクリックします。そして以下の内容を貼り付けます。

(http.host eq "インスタンスのホスト名" and (http.user_agent contains "Misskey" or http.user_agent contains "Pleroma" or http.user_agent contains "Mastodon") and not http.user_agent contains "another.instance.jp" and not http.user_agent contains "another2.instance.com")

式の使い方は Cloudflare公式ドキュメント にあります。
今の式を日本語化すると

  • アクセス先のホスト名が インスタンスのホスト名
  • http.user_agentにMisskeyPleromaMastodonが含まれていて
  • http.user_agentに another.instance.jpanother2.instance.com も含まれていない時

となります。
前者2つは必須で、後者は自分で編集する部分となります。
ほとんどのソフトウェアはユーザーエージェントにインスタンスのホスト名を入れてくるので、それを判断材料にしています。
not http.user_agent contains "許可するインスタンスのホスト名"が基本形で、これをandで繋ぎます。

そして「以下を実行...」のプルダウンリストから「ブロック」を選び、保存します。

これで許可していないインスタンスからのリクエストを拒否することができます。

6. Misskeyの設定を変える

最後にMisskeyの設定を変えて、Squidを経由するように設定します。
example.ymlからコピーして使用している場合はファイルの最後にproxy: ...という行があり、コメントアウトされています。コメントアウトを解除して、以下に書き換えます。該当する行がない場合は最終行でもいいので以下の内容を書き込みます。

.config/default.yml
proxy: http://localhost:3128

今設定したプロキシを利用する際の注意点として、一部のMisskeyの動作に影響があるということです。
hCaptchaなどのシステムに関わるものや、オブジェクトストレージと通信できず不具合を引き起こします。(オブジェクトストレージに関しては設定でプロキシを経由しないように設定できますが、公開用のホスト名はホワイトリストに入れておく必要があります)
そのようなものは先程のホワイトリストに加えるか、proxyBypassHostsに追加してプロキシを経由しないようにします。

proxyBypassHosts: [
 'hcaptcha.com',
 'www.google.com',
 ...
]

設定後Misskeyを再起動します。

7. 動作確認

実際に許可したインスタンスと通信、連合ができるか、またその逆も確認します。

手順の説明は以上となります。

Discussion

nenohinenohi

失礼します
ファイアウォール ルールって。。。。。。。。。。

失礼しました