S3+CloudFrontでもObservatory高スコアを取りたい
Overview
A目標でしたが無理と判断したので現在Bです。
経緯
- 静的サイトだしCDN通してるしでPageSpeed Insightsだと80後半~100出る
- SSLはCDN任せで十分
- じゃ残りは?
でObservatoryのスコアを上げてみようと決意。ECサイトとかではないのでどれだけセキュリティ気にしてもそんなに意味あるかなぁ…という感じはありますが。
結果
FランクだったObservatoryスコアがBランクになりました🎉
元の構成
今回のターゲットはこのブログと https://www.asterism.xyz の2つです。
6月頃まではCodeCommitをサイトのリポジトリとして使っていましたがリポジトリを賑やかすためGitHubに移行しました。(不純)
サイトの配信はS3とCloudFrontを使っていて、
- Hugo themeはgit submoduleで管理
- GitHubリポジトリの更新があると、WebhookでCodeBuildを起動
- buildspecではHugoサイトのbuild、S3バケットの更新、CloudFrontのキャッシュクリア
というように動いています。
PageSpeedは使うthemeによりけりではありますが、モバイル80点PC90点以上は大体でるんじゃないかなーとか思ってます。
ちなみにHugo Future Imperfect Slimというthemeを使っているこのサイトではモバイル88点PC100点となっています。
SSLLABSはCloudFront任せでスコアA取れます。
ただしObservatoryで見ると妙にスコアが低い…。
問題点
Observatoryのテスト結果を見ると、どうやらHSTSとかCSPとかX-Content-Type-OptionsとかX-Frame-OptionsとかX-XSS-Protectionなどのセキュリティ用httpヘッダが無いよとの事。
webサーバを使ってホスティングしている場合はちょこっと設定を変えて、+コンテンツ側で必要であれば対応というだけで終わりですが上記の通りS3+CDNという構成です。
なにか弄る方法無いのかなと思って調べた所案の定ありました。AWSって出来ないことがないのではと思うくらいにサービス多いですよねホント。
作業
Lambda@EdgeはCloudFrontへのアクセス時にLambdaを動かせますよー、ってやつのようですね。
実はmastodonとpleromaのメディアにはCloudFrontではなくCloudflareを使っていて、このブログのCDNも一時期Cloudflareに移していました。
ただLambda@Edgeでヘッダ書き換えが楽にできるという事が分かったので移行はやめこちらに残留。
作業内容としては上のURLがほぼ全てです。
一応index.jsのコードも乗せておくと、
'use strict';
exports.handler = (event, context, callback) => {
//Get contents of response
const response = event.Records[0].cf.response;
const headers = response.headers;
//Set new headers
headers['strict-transport-security'] = [{key: 'Strict-Transport-Security', value: 'max-age=15768000; preload'}];
headers['x-content-type-options'] = [{key: 'X-Content-Type-Options', value: 'nosniff'}];
headers['x-frame-options'] = [{key: 'X-Frame-Options', value: 'DENY'}];
headers['x-xss-protection'] = [{key: 'X-XSS-Protection', value: '1; mode=block'}];
headers['referrer-policy'] = [{key: 'Referrer-Policy', value: 'same-origin'}];
//Return modified response
callback(null, response);
};
作業順は
-
HSTSとCSPは面倒なので一旦無しで他のヘッダを追加しスコアが上がることを確認
-
https://www.asterism.xyz で使っているHugo-academicだとヘッダ以外の減点要素としてURLスキーム無しで読み込んでる外部リソースがあったためそれらを修正(PullRequest取り込まれました✌)
-
HSTSを設定
-
CSP対応もしようとしたけど今使っているthemeだとインライン実行を無くすのは私の技量ではめっちゃ時間かかりそうだと判断し今は断念
といった感じ。
なんでCSP駄目だったかと言うと、主にHugoのGoogleAnalytics対応のせいでして……。
見ての通りインラインスクリプトにされており、こうなっちゃうと仕方ないなぁと。
オプションでnonce設定できるといいんですが。
金額的には上のLambdaスクリプトも実行時間短いし、対してPVがあるサイトでもないためほぼかかってないです。