洪 民憙 (Hong Minhee)'s avatar
洪 民憙 (Hong Minhee)

@hongminhee@hollo.social · Reply to モナコ広告 :fedibird1: @技術・雑談's post

@monaco_koukoku この問題はx-forwarded-fetchミドルウェアが設定されていないために発生しています。

詳しく説明させていただきますと:

  1. fedify tunnelは、ローカルのHTTPサーバーをHTTPSで外部に公開するリバースプロキシとして動作します。
  2. この過程で、元々のHTTPSリクエストはHTTPに変換されてローカルサーバーに転送されます。このとき、元のプロトコルとホスト情報はX-Forwarded-ProtoおよびX-Forwarded-Hostヘッダーに含まれて転送されます。
  3. しかし、x-forwarded-fetchミドルウェアが設定されていない場合、Fedifyはこれらのヘッダーを認識できず、直接受け取ったHTTPリクエストのURLのみを参照することになります。
  4. その結果、ctx.url.hrefhttps://ではなくhttp://で始まるURLとなり、生成されるActorオブジェクトのURLもすべてhttp://から始まるものになってしまいます。

解決方法としては、以下のようにx-forwarded-fetchミドルウェアをインストールして適用する必要があります:

import { behindProxy } from "x-forwarded-fetch";

serve({
  fetch: behindProxy(request => federation.fetch(request, { contextData: undefined }))
});

このように設定することで、FedifyがX-Forwarded-*ヘッダーを正しく認識し、https://のURLを生成するようになります。

また、この問題についてはFedifyの公式ドキュメントの「ローカルサーバーを外部に公開する」(Exposing a local server to the public)セクションにも詳しく説明があります。

These tools behave like a reverse proxy, so basically the federation server cannot recognize if it is behind a reverse proxy, and if the reverse proxy is in HTTPS. So the federation server will generate HTTP URLs in the ActivityPub messages, which cause interoperability issues. In this case, you can use the x-forwarded-fetch middleware in front of the Federation.fetch() method so that the Federation object recognizes the proper domain name and protocol of the incoming HTTP requests.

For more information, see How the Federation object recognizes the domain name section in the Federation document.
ALT text detailsThese tools behave like a reverse proxy, so basically the federation server cannot recognize if it is behind a reverse proxy, and if the reverse proxy is in HTTPS. So the federation server will generate HTTP URLs in the ActivityPub messages, which cause interoperability issues. In this case, you can use the x-forwarded-fetch middleware in front of the Federation.fetch() method so that the Federation object recognizes the proper domain name and protocol of the incoming HTTP requests. For more information, see How the Federation object recognizes the domain name section in the Federation document.
モナコ広告 :fedibird1: @技術・雑談's avatar
モナコ広告 :fedibird1: @技術・雑談

@monaco_koukoku@fedibird.com · Reply to 洪 民憙 (Hong Minhee)'s post


ありがとうございます。x-forwarded-fetch にはそのような意味があったのですね。(自動生成されたコードに含まれていましたが、その意味までは追っていませんでした)

当該箇所を確認したところ、チュートリアルの通りに進めて自動生成された
fetch: behindProxy(app.fetch.bind(app))
というコードになっていました。
github.com/fedify-dev/microblo
と同じです。

検証には fedify tunnel を使用していたのですが、サーバが受け取るHTTPリクエストヘッダを見ると、X-Forwarded-For, Forwarded ヘッダだけが追加され、X-Forwarded-Proto, X-Forwarded-Host は存在しませんでした。
これをCloudflare Zero Trustのトンネルに切り替えたところ、X-Forwarded-Proto, X-Forwarded-Host ヘッダがリクエストに追加されており、この場合は確かに https:// のURLが含まれる Actor オブジェクトを得ることができました。