ALB×ApacheでHSTS対応




HTTP Strict Transport Security

HSTS とは HTTP から HTTPS へのリダイレクト途中の通信を改ざんされたり中間者攻撃を防ぐための設定です。 HTTP の通信は改ざんチェックは行われないため HTTPS のリダイレクト途中の通信でサイトに対して攻撃されてしまうと検知するすべがありません。 HSTS を導入するとサーバ側で HTTPS にリダイレクトされるのではなくブラウザ内部で HTTPS へのリダイレクトが行われます。通信の始点であるブラウザから HTTPS 通信することによって通信の途中で HTTP 通信することがありません。

AWS ALB 配下で HSTS の設定を行う方法


  • http:80プロトコルでアクセスしようとすると、ブラウザUAがhttpsにインターナルリダイレクトする仕組み。
  • サーバーサイドのhttpsリダイレクトではフィッシング詐欺や(httpな)ブックマークによる直アクセスにおいて、リダイレクト前のhttp:80アクセスが脅威にさらされる。
  • レスポンスヘッダにHSTSヘッダを付記して、ブラウザUAにキャッシュさせることで実現させている。
  • HSTSヘッダはhttpsプロトコル下でないとブラウザUAがキャッシュしてくれない。
  • したがってあいかわらず初回のhttpアクセスでは電文は露見する。
  • ただし後述のpreload仕様では初回のhttp:80アクセスさえhttpsインターナルリダイレクトを強要することができる。

ALBのバックエンドで80ポートをフォワードしている場合の対策



  • ALB単体はルールセットでhttpsリダイレクトを組めるがカスタムヘッダーを付記することができないため、バックエンドが付記してやる必要がある
  • ALB<--->バックエンドがhttp:80プロトコルであっても、UAにとっての終端であるALBとの通信がhttps:ならがHSTSヘッダをキャッシュてくれる
  • バックエンドはとにかく常時HSTSヘッダを付記してやる

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

バックエンドがhttpsリダイレクトまでやる場合


  • バックエンドでHSTSヘッダを常時付記しつつ、httpsリダイレクトする
  • ALBがUA<--->ALBのプロトコルをフォワードヘッダに付記してくれるのでhttp:80プロトコルの場合のみリダイレクトする=RewriteCond %{HTTP:X-Forwarded-Proto} =http

# HSTSヘッダを常時付記
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# Rewrite
RewriteEngine On
# ブラウザUA<--->ALBがhttp:80プロトコルの場合httpsにリダイレクト
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]

preload




  • ユーザがWebサイトにHTTPで初回アクセスした場合でもHSTSが有効になり、初回から必ずHTTPSでアクセスを行うための仕組みのことです。事前に自身の所持するWebサイトのドメインをHSTS preloadリストに登録する必要があります。
  • HSTS preloadリストとは主要ブラウザ(Chrome、Firefox、Safari、IE11、Edge、Opera)が参照するHSTS対応サイトリストのことです。HSTS preloadリストに登録されているWebサイトは、ブラウザが予めSSL/TLSを使用することが分かるようになるため、初回からHSTS機能が有効になります。

AWSのCLB(Classic Load Balancer)配下にHSTSとPreload設定を行う方法 | N-LAB


申請は次が条件なので対応後に登録する


  • サブドメインはだめ
  • HSTS対応していないとだめ

動作確認




  • httpsアクセスすると、レスポンスヘッダにstrict-transport-securityがある
  • httpアクセスすると、307インターナルリダイレクトしてhttps通信した

対応済のサイト

curl -v -sS -o /dev/null -L -k https://www.rakuten-sec.co.jp
< HTTP/2 200 
< server: Apache
< strict-transport-security: max-age=31536000;
< content-type: text/html
< date: Thu, 03 Aug 2023 05:41:44 GMT
< server-timing: ak_p; desc="1691041304439_1611081229_148344902_765_433_13_0_15";dur=1 

ストレージ容量を空ける


EC2の治験サーバーのストレージがたびたび逼迫していて、定期的にログをお掃除していたがちゃんと調べたら8年分の思いでが詰まっていた。シークだけで大変だったんじゃないか


# ルート /varが圧倒的にでかい
du -sh /*
6.5M    /bin
69M     /boot
4.0K    /cgroup
60K     /dev
8.9M    /etc
6.0G    /home
197M    /lib
21M     /lib64
4.0K    /local
16K     /lost+found
4.0K    /media
4.0K    /mnt
456M    /opt
0       /proc
69M     /root
28K     /run
15M     /sbin
4.0K    /selinux
4.0K    /srv
0       /sys
16K     /tmp
4.5G    /usr
96G     /var

# wwwコンテンツとかライブラリがでかいのはいいとしてspoolがでかい
du -sh /var/*
4.0K    ./account
711M    ./cache
4.0K    ./crash
4.0K    ./cvs
108K    ./db
8.0K    ./empty
8.0K    ./ftp
4.0K    ./games
12K     ./kerberos
28G     ./lib
4.0K    ./local
16K     ./lock
627M    ./log
0       ./mail
4.0K    ./nis
4.0K    ./opt
4.0K    ./preserve
628K    ./run
35G     ./spool
4.0K    ./tmp
33G     ./www
4.0K    ./yp

# mailがばかでかい。あー、、と
du -sh /var/spool/*
16K     ./anacron
8.0K    ./at
72K     ./clientmqueue
12K     ./cron
4.0K    ./lpd
35G     ./mail
4.0K    ./mqueue

# エラーログやら通知やら8年分くらいたまってた
du -sh /var/spool/mail
35G     ./ec2-user
176K    ./root
0       ./hoge
0       ./fuga

echo '俺の名前を言ってみろ' > /var/spool/mail/ec2-user

バーストパフォーマンス(T系)インスタンスのCPUクレジット




気軽に利用するt系インスタンスのCPUクレジットの性質と検討ポイントについて

CPUクレジット



クレジットとベース性能


  • 1クレジットは1vCPUを100%で1分間稼働できる
  • 1クレジットは1vCPUを100/60m=1.6%で1時間稼働できる
  • 2vCPUのインスタンスなら0.8%で1時間稼働できる
  • t3.microは12クレジット/h / 2vCPU / 60m = 10%/mで定常稼働できる。これがベース性能。

T系インスタンスにおいてシングルスレッド性能は概ねインスタンスタイプに依存しない
AWS EC2で使われているCPUの種類と性能をまとめてみた。

バースト


  • チャージ量 > 消費量なときは使い切らなかったクレジットはそのインスタンスタイプのクレジット/hの24時間分を上限にスタックされる
  • チャージ量 < 消費量なときはスタックから持ち出しされる=これがバースト
  • スタックを使い果たしたらチャージ量と消費量がイコールになりベース性能しか出せない

みきわめ


  • 定常時にベース性能でスループットが満たせるか
  • CPUスパイクをバーストでカバーできるか

アンリミテッドモードでは性能優先で追金で無制限にスケールすることはできるが、メモリ・ネットワーク帯域などCPU以外の因子についても総合的にコスパ最適なインスタンスタイプを選択することが肝要だ。


バーストパフォーマンス(T系)インスタンスの特徴を理解して上手に利用しよう | Amazon Web Services

vuetify - v-windowタブのスワイプキャンセル


vuetifyv-windowでタブを構成してv-window-item内に含まれるスクロール要素がタッチイベントに反応してタブスワイプしてしまうのをガードする実装

通常スワイプインベントもとい、タッチイベントはwindowコンポーネントにバブリングで伝播されてタブスワイプが実行されるため、特定条件でタッチイベントをキャンセルしたい。

オーバーフロースクロールなテーブルコンテナのタッチイベントのバブリングをキャンセルする例 )


// タッチイベントのソースがTHかTDの場合、親へのイベントバブリングをキャンセル
const touchCancelBehavior = e => {
	if (e.target.tagName === 'TH' || e.target.tagName === 'TD') {
		e.stopPropagation();
		e.stopImmediatePropagation();
    }
}

// v-windowコンポーネント系にリッスンさせる
let wList = document.querySelectorAll('.v-window, .v-window__container, .v-window-item')
wList.forEach( target => {
	target.addEventListener('touchstart', touchCancelBehavior)
    target.addEventListener('touchmove', touchCancelBehavior)
    target.addEventListener('touchend', touchCancelBehavior)
})

Bloggerでコードブロックをスタイリング




highlight.jsを使ってbloggerでいい感じにコードブロックをスタイリングする。

highlight.jsはhtmlの<pre><code>コードブロックに内包される言語を解析して、スタイリングしてくれるjavascriptのオープンライブラリだ。

はじめる


公式 | Usage / CDNのエントリー向けコードスニペット



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>

<!-- and it's easy to individually load additional languages -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/go.min.js"></script>

<script>hljs.highlightAll();</script>

  • スクリプトhighlight.min.js<code>コードブロックに含まれる言語解析スクリプトで、解析結果を<code>ブロックにclass="language-bash hljs"のようにclass名として付記してくれる。highlight.min.jsはメジャーどころの言語をカバーするエントリー向けの実装が収納されている。
  • 未対応の言語はgo.min.js(GoLangの場合)など必要に応じて追加の言語をインクルードして拡張できる。
    • 対応言語をカスタマイズして静的ファイルとしてダウンロードできるので、自ホストからホスティングもできる。Download a Custom Build
    • hljs.highlightAll();で解析実行する。

これが
<pre><code>{ コード部 }</code></pre>

hljs.highlightAll();でこうなる
<pre><code data-highlighted="yes" class="hljs language-php">{ コード部 }</code></pre>

  • スタイルシートdefault.min.cssはそのclass名のスタイルシートだ。demoから好みのスタイルを探してdefault部分を置き換えてスタイルを適応することができる。

好みのスタイルにする


demoからスタイルを吟味して使いなれたvscodeと思しきvs2015.min.cssをセレクト。



<link href='https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/vs2015.min.css' rel='stylesheet'/>

<!-- stackeditでマークダウンをhtmlにエクスポートしたやつ -->
<pre class="language-php"><code class="language-php"><span class="token php language-php"><span class="token delimiter important"><?=</span> ClassName<span class="token punctuation">:</span><span class="token punctuation">:</span>constant_field_name <span class="token delimiter important">?></span></span>

こんなかんじになる

ファイルタイプを付記する

ファイルタイプを付記してこんな感じにする


highlight.min.js解析スクリプトはラベルまで面倒見てくれないのでHEXOとhighlight.jsでシンタックスハイライトし、ついでにファイル名も表示する様を参考にJSでファイルタイプのラベルを補完する。


highlightjsで当てられたスタイルクラスlangage-phpのハイフンをセパレータにしてファイルタイプをラベリングするJS実装を入れる。



document.addEventListener('DOMContentLoaded', () => {

    // highlightjsがpre codeブロックにスタイルクラスをあてる
    hljs.highlightAll();

    // コードブロック解析
    Array.prototype.slice.call(document.querySelectorAll('pre code')).forEach( code => {

        // highlightjsが適用したスタイルクラス(language-{filetype})をもとに{filetype}をdata属性に補完
        Array.prototype.slice.call(code.classList).forEach( className => {
            const asFileType = className.split('language-')[1];
            if (asFileType) code.setAttribute('data-filename', asFileType);
        });

        // コードボディ部を折り返しなしでオーバーフロースクロールなコンテナでラップする
        const wrapperDiv = document.createElement('div');
        wrapperDiv.classList.add('code-wrapper');
        wrapperDiv.innerHTML = code.innerHTML;
        code.innerHTML = '';
        code.appendChild(wrapperDiv);

    });

    // ついでにインラインコードブロックにスタイルクラスを当てる
    let allCodeTags = document.querySelectorAll('code');
    let filteredCodeTags = Array.from(allCodeTags).filter(el => el.parentElement.tagName.toLowerCase() !== 'pre');
    filteredCodeTags.forEach(el => {
        el.classList.add('inline-code');
    });

});



ラベルの表示とコードブロックのスタイリング


/* 疑似要素でコードブロックにファイルタイプをディスプレイ */
pre code.hljs[data-filename]::before {
    content: attr(data-filename);
    padding: 0.3em 1em;
    color: #fff;
    font-size: 0.9em;
    background-color: rgba(255, 255, 255, 0.2);
    border-bottom-right-radius: 8px;
}

/* コードブロックのスタイルを好みに調整 */
pre code.hljs {
    /* ラベルはコードブロックの外辺に沿わせたいのでhljsスタイルクラスを上書いてパディングを無効化 */
    padding: 0 !important;
    /* コードブロックは丸みをもたせてフォントサイズは標準に引き上げ */
    border-radius: 8px;
    font-size: 1em;
}

/* ラップしたコード部 */
pre code.hljs .code-wrapper {
    padding: 1em;
    overflow-x: scroll;
}

/* インラインコードブロック */
.inline-code {
    border: none;
    background-color: #eee;
    border-radius: 4px;
    vertical-align: middle;
    padding: 4px 8px;
    margin: 0 4px;
}

秘密鍵から公開鍵を導出する


ssh鍵を更新したあかつきにauthorized_keysファイルから旧公開鍵を削除したいんだが、、ラベルがなくてどれやと途方に暮れたときに

秘密鍵をソースにssh-keygen -yで公開鍵を導出できる

# 秘密鍵の公開鍵をプリント
ssh-keygen \
-y \ # 公開鍵の抽出オプション
-f path/to/private_key # 秘密鍵の指定オプション

> ssh-rsa XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX...

# 上記の公開鍵を削除する
vi path/to/authorized_keys

phalcon - voltで変数の参照


voltで定数やらグローバル変数を参照するのに、知識不足でphp記述で妥協していたがvoltでいけるじゃないか。

クラス定数は

<?= ClassName::constant_field_name ?>

contantメソッドで定数の値をとってこれるじゃないか。

{{ constant('ClassName::constant_field_name') }}

global変数は

<?php global $GLOBAL_VARIABLE_NAME; ?>
<?= $GLOBAL_VARIABLE_NAME ?>

GLOBALSディレクティブで解決できるじゃないか。

{{ GLOBALS['GLOBAL_VARIABLE_NAME'] }}