Mastodon

CloudFrontとS3でリダイレクト

Mastodonの旧メディアが外部からアクセス不能になってしまうため、対策しました。

古いURLの問題

メディアをAmazon S3に移動しましたが、実は移動しただけだと一つ問題があります。
それは旧メディアのURLと新メディアのURLが違うこと…。
自鯖でTLを見る分には古い投稿を見ても新メディアのURLになるので困りません。
問題は他のインスタンスに配信済みのトゥート。

他鯖では旧URLで記録されているため、画像とかが見れなくなってしまいます。
実は今の鯖はこれまでに2回、メディアの保存場所を変えてる為にURLが3種類あります。

①https://ifrit.gaia.ff14-mstdn.xyz/system/****
一番最初の頃、オブジェクトストレージも何も使わずに運営してた時。

②https://ifrit.gaia.ff14-mstdn.xyz/media/****
途中でオブジェクトストレージ(minio)に移した時。

③https://media.ff14-mstdn.xyz/****
今現在。Amazon S3に移した後からはこれ。

①と②はAmazon S3に画像を移動済みなのでアクセスできなくなります。

解決策

解決策は簡単。旧URLでアクセスしてきたら新URLにリダイレクトします。
それぞれ、以下のように転送すれば解決できます。

①https://ifrit.gaia.ff14-mstdn.xyz/system/****→https://media.ff14-mstdn.xyz/****
②https://ifrit.gaia.ff14-mstdn.xyz/media/****→https://media.ff14-mstdn.xyz/****

リダイレクト方法

nginxでリダイレクト……と思いましたがCloudFrontとS3でリダイレクトにしました。
理由はnginxのconfigにあんまり設定を増やしたくないし、AWS内でリダイレクトが済むならそれの方が良いかなと。

CloudFrontだけだとリダイレクトは出来ません。
なのでS3の静的Webサイトホスティングとそれのリダイレクトルールを利用してリダイレクトします。

リダイレクトに使うバケットは専用に空のバケット作って対応しました。
まず、CloudFrontで以下のパスのアクセスをすべてリダイレクト用バケットに行くようにOriginを設定します。

・https://ifrit.gaia.ff14-mstdn.xyz/system/*
・https://ifrit.gaia.ff14-mstdn.xyz/media/media_attachments/*
・https://ifrit.gaia.ff14-mstdn.xyz/media/custom_emojis/*
・https://ifrit.gaia.ff14-mstdn.xyz/media/accounts/*
・https://ifrit.gaia.ff14-mstdn.xyz/media/preview_cards/*

/media以下は本当は/systemと同じ用に1個でいいのですが、Mastodonでメディアの短縮URLとして/media/[ランダム文字列]のようなURLを使用しているらしく、単に/media以下をリダレクト設定すると短縮URLが機能しないので個別に設定しました…
minioとか使う時、バケットにmediaとかつけるとこの短縮URLとバッティングするので気をつけようね

リダイレクト用のS3では以下のリダイレクトルールを設定します。

<RoutingRules>
  <RoutingRule>
    <Condition>
      <KeyPrefixEquals>media/accounts</KeyPrefixEquals>
    </Condition>
    <Redirect>
      <Protocol>https</Protocol>
      <HostName>media.ff14-mstdn.xyz</HostName>
      <ReplaceKeyPrefixWith>accounts/</ReplaceKeyPrefixWith>
    </Redirect>
  </RoutingRule>
  <RoutingRule>
    <Condition>
      <KeyPrefixEquals>media/custom_emojis</KeyPrefixEquals>
    </Condition>
    <Redirect>
      <Protocol>https</Protocol>
      <HostName>media.ff14-mstdn.xyz</HostName>
      <ReplaceKeyPrefixWith>custom_emojis/</ReplaceKeyPrefixWith>
    </Redirect>
  </RoutingRule>
  <RoutingRule>
    <Condition>
      <KeyPrefixEquals>media/media_attachments</KeyPrefixEquals>
    </Condition>
    <Redirect>
      <Protocol>https</Protocol>
      <HostName>media.ff14-mstdn.xyz</HostName>
      <ReplaceKeyPrefixWith>media_attachments/</ReplaceKeyPrefixWith>
    </Redirect>
  </RoutingRule>
  <RoutingRule>
    <Condition>
      <KeyPrefixEquals>media/preview_cards</KeyPrefixEquals>
    </Condition>
    <Redirect>
      <Protocol>https</Protocol>
      <HostName>media.ff14-mstdn.xyz</HostName>
      <ReplaceKeyPrefixWith>preview_cards/</ReplaceKeyPrefixWith>
    </Redirect>
  </RoutingRule>
  <RoutingRule>
    <Condition>
      <KeyPrefixEquals>system/</KeyPrefixEquals>
    </Condition>
    <Redirect>
      <Protocol>https</Protocol>
      <HostName>media.ff14-mstdn.xyz</HostName>
      <ReplaceKeyPrefixWith/>
    </Redirect>
  </RoutingRule>
  <RoutingRule>
    <Redirect>
      <Protocol>https</Protocol>
      <HostName>media.ff14-mstdn.xyz</HostName>
    </Redirect>
  </RoutingRule>
</RoutingRules>

 

これで無事、旧URLにアクセスしてきた場合は新URLにリダイレクトされるようになりました。