wwwサブドメインのリダイレクトをCloudFrontとS3で実現する

Sixleaveakkm
The Finatext Tech Blog
Dec 24, 2020

--

初めまして、Finatextの六つ葉と申します。現在、グループ会社のナウキャストが開発中の新サービスのAWSインフラを担当しております。

本稿では、「ドメイン設計」と「CloudFrontとS3を利用して、wwwサブドメインをメインドメインにリダイレクトする方法」について述べます。

ウェブサイトをAWS上でデプロイするインフラ(SRE)エンジニアの方の参考になれば幸いです。

はじめに

突然ですが、ウェブサイトを構築する際に重要なことは何だと思いますか?答えはおそらく十人十色でしょう。目をひくUI、サイトの中身などなど。ただ私はここにドメイン名をあげます。

mediumを例に見てみましょう。

もし、mediumのドメインが 9993.com だったらどう思いますか?いくら内容が整っていたとしても、このサイトに不信感を覚えると思います。

ドメインのネーミング

一般的にはサイトの内容とできるだけ一致し、かつ覚えやすい短いアルファベットの単語をドメイン名にするのが無難です。更にフォーマルな感じを出すため、数字を避けるのがよいでしょう。(数字に関してはあくまで一般論です。一部の例外はあります。)さらに、エレガントさがあると理想です。

  • GitHub
  • 1Password
  • Pocket

などが、わかりやすいと同時に覚えやすい例です。

さらにエレガントな感じを追加すると、

  • BitBucket
  • WordPress
  • NicoNico(笑顔)
  • Alibaba(アリババと40人の盗賊:財宝への扉)

などがあると思います。

Google検索があれば、ドメインなんて何でもよいのでは?と思う方がいるかもしれませんが、残念ながら、ある程度有名にならないとGoogle検索リストの上位には出てきません。(もちろん、Amazon、Google、Yahoo!と同じくらいのレベルにまで知名度を上げればドメインは関係ありません。)

また、英語圏外におけるドメイン名の命名は難易度が高いと思います。日本のドメインでもっとも一般的なのはローマ字でアルファベット表記する方法です。ただ、一つ問題があります。ヘボン式と日本式という二つの変換方法があることです。

・ヘボン式の「し」→ shi
日本式の「し」→ si

例えば、大手家電販売店のヨドバシ。「yodobasi.com」にアクセスしている人はいないと言い切れる保証はありますか?まぁ、ヨドバシは知名度があるので、Google側でうまく対処できますが。

代替ドメインを準備するのが主流

このような問題を解消するために、複数のドメインを持つことになります。

例えば、Googleは各地域のドメインでそれぞれの言語のサイトを提供しています。それと同時に、google.com、google.net、どちらにアクセスしてもすべて google.com になります。また、Googleは一般的な単語ではないのでスペルミスが発生しがちですが、gogle.com や gooogle.com と打ってしまっても、きちんと google.com にアクセスできます。

ほかにも、1Passwordはドメインを短くするために数字の1を使っていますが、onepassword.com でもアクセスできます。

単一ドメインのみの場合の注意点

単一ドメインで注意すべきことは、ほかにもあります。

  1. https化

現代のウェブサイトにhttps化は必須です。もしあなたのウェブサイトがまだhttpのままならば、ぜひ実行してください。ユーザー情報を預かる場合はなおさらです。

AWS上にウェブサイトを構築する場合、静的サイトをS3にホスティングすることが勧められています。サーバーより安く、安全です。ただ、そのままではhttpしか使えません。一般的には、CloudFrontのサービスと併用し、AWS Certificate Managerと合わせてhttps化し、httpのトラフィックをhttpsにリダイレクトすることが多いと思います。このあたりのやり方はネット上にたくさん情報がありますので、ここでは飛ばします。

CloudFront
AWS CloudFront
ACM

2. wwwとメインドメインからのリダイレクト

少し前から、Chromeはアドレスバーのurlを短縮表示しています。例えば、 www.example.com を example.com と表示しています。このことからも、www抜きでウェブサイトを提供することが流行っていることが明白です。

さて、www.example.com というウェブサイトを提供している場合に、example.comにアクセスしたらどうなるでしょうか?

何も準備していなければ、何も表示されないでしょう。個人的には、そういった状況も想定してサイトにアクセスできるようにしておくことは、サイト提供側の仕事だと思います。(よく利用しているサイトのurlからwwwを抜いたり逆に足したりしてみると、けっこうショックな結果になるでしょう。)

wwwサブドメインからのリダイレクト設定

前置きが大変長くなりましたが、ここからが本題です。サブドメインからのリダイレクト設定について、お話ししたいと思います。

残念ながら現時点(2020年12月末)では、AWSはデフォルトでリダイレクトサービスを提供していません。

一つのやり方としては、Route53を使用して www.にエイリアスを設定し、同じバックエンドを指すようにルートドメインを設定する方法があります。

ただし、ユーザーが www.example.com と example.com という2つのドメインを使っていることに注意が必要です。

もしサイトが簡単なものであれば、Route53でAliasを設定して www.example.comとexample.comの2つのドメインを使うのも一つの方法ですが、APIサーバー側のCORS設定、他のサードパーティサービスと連携する際のドメイン設定(例えばCognito、Auth0など)は、2つのドメインを利用していることを考慮しなければなりません。設定が面倒になるので、やはりリダイレクト設定をお勧めします。

では、具体的にどうすればよいのでしょうか。
Route53、CloudFrontでは、結果は2つのドメインに分かれます。サーバーなどを用意してリダイレクトを実行するのがよさそうです。EC2やBeanstalkを使うほどではないでしょうが、API Gatewayを選択するのは一つの良いやり方です。ですが、ここではS3を利用します。

S3では静的ホスティングの機能があります。一般的にhtmlやcssファイルを中に置き、CloudFrontやパブリックのアクセス権限を与え、サイトをホストするという使い方になります。今回はその中のリダイレクト機能を使います。

構成図としては以下のような感じです。

では、最初から説明します。

すでに example.com というサイトが存在していると仮定し、 www.example.com を作ります。

  1. ブランクのS3バケットを作ります。バケット名は、できればwww.example.com にしましょう。(普通のバケット名も使えるはずですが試していません。)
  2. www.example.com の 静的ホスティングを設定しましょう。ここで生成されるurlをメモしておきます。
    <bucket-name>.s3-website-ap-northeast-1.amazonaws.com
    ここでRoute53に www.example.com のAliasを設定するとhttpだけリダイレクトされますので、CloudFrontを設定します。

3. CloudFrontを作成します。

origin domain nameは、先ほどメモしたurlになります。そしてhttpsのリダイレクトとCNAMEsを設定します。

4. Route53でCloudFrontを指すように設定します。

5. 完了です。

鋭い方はすでに気づいているかもしれませんが、S3のBucket PolicyではCloudFrontからのGetObjectアクセス権が与えられていません。なぜなら、そもそもバケットの中身を参照していないからです。また、念のためこのバケットへのwrite権限をDenyに明言した方がよいでしょう。

SPAサイトのドメイン内フェイルオーバー

ここまでは、ドメインレベルで代替する話をしてきました。

さらに、次のようなケースを考えてみましょう。

ユーザーはあなたのサイトのurlをどこかでコピーしました。正しくは www.example.com/login のはずですが、誤って www.example.com/login> と、末尾に予想外の文字がついてしまいました。S3で静的ホスティングする場合は、そのままAWSの403ページが表示されます。

amazon.comからの図例です

このままではユーザーにとって利便性が高いとは言い難いですので、これを解消していきます。

CloudFrontを使ったエラーハンドリングは、多くの方が知っていると思います。

CloudFrontのユーザーをS3バケットポリシーに追加することで、中身のファイルへのアクセスを許可します。存在しないファイル(パス)にアクセスしようとすると403が返されますが、CloudFrontのエラーページに図の様にルートのindex.htmlへフェイルオーバーを設定していれば、問題を解消できます。この方法はSPAサイトで主流のやり方です。

CloudFrontにWAFを設ける場合

WAFはファイアウォールを設けてアクセスを制御できます。アクセスをDenyする場合は同じく403が返され、index.html にリダイレクトされます。しかし、 cssやjsファイルがindex.htmlと別に存在する場合は不完全な index.html が表示されます。また、all-in-oneの場合はcssとjsも全部index.htmlにあるため、アクセスが許可されてしまいファイアウォールが機能しない、という問題があります。

この問題の解決策は以下です。

CloudFrontが持つS3への権限がs3:GetObjectのみの場合は403しか返せませんが、s3:ListBucket を追加すれば、存在しないファイルへのアクセスに対して404を返すことができます。

CloudFront のエラーページを403と404を別々のパスにリダイレクトさせれば、アクセス不可とフェイルオーバーに分けることができます。もちろん、403を単独なファイルにすることが重要です。

まとめ

実際のところ、これらの仕組みがなくてもウェブサイトは提供できますが、万が一を考慮することが我々の仕事ではないでしょうか。運用費用もさほどかからないので、ぜひ試してください。

現在、Finatextグループではエンジニアを積極的に採用しています。以下の応募フォームからお気軽にご連絡ください。

--

--