概要

モノリシックなサービスでは1つのWebアプリを内部ネットワーク向けAPIと外部公開するAPIをまとめて搭載したい場合があります。 複数のALBからEC2を向けることもできますが、ブルーグリーンデプロイができない制約があります。

ALBとNLBを組み合わせることでブルーグリーンデプロイしつつ内外のネットワークから利用できる構成を検討しました。

構成

通常通り外部向けにはALBを配置してEC2に接続します。内部向けにはNLBからALBにターゲットグループを設定し同一のEC2に接続します。

ALBとNLBはそれぞれRoute53でドメイン名を指定します。NLBにはエイリアスが利用できないためプライベートIPアドレスを固定しAレコードで指定します。

ALBはHTTPSで公開します。NLBからALBに向ける際には80->443に変換できないため内部向けもHTTPSで公開しています。 この際、ALBのサーバー証明書は当然NLBの証明書ではないため証明書エラーとなります。そこで、ALBのSNIを利用してNLB用の証明書も設定します。

動かしてみる

EC2にWebサーバーをインストールして上記構成でALBに対してHTTPリクエストを送りエラーなく返却されました。

$curl https://web.app.kktkht94.work
<html><body><h1>hello!</h1></body></html>

内部用のNLBに対してもHTTPリクエストを送り返却を確認しました。

$curl https://internal.app.kktkht94.work
<html><body><h1>hello!</h1></body></html>

OpenSSLで検証も成功しました。

# ALB経由
$ openssl s_client -connect web.app.kktkht94.work:443  -servername web.app.kktkht94.work | grep CN=
depth=2 C = US, O = Amazon, CN = Amazon Root CA 1
verify return:1
depth=1 C = US, O = Amazon, CN = Amazon RSA 2048 M03
verify return:1
depth=0 CN = web.app.kktkht94.work
verify return:1
 0 s:/CN=web.app.kktkht94.work
   i:/C=US/O=Amazon/CN=Amazon RSA 2048 M03
 1 s:/C=US/O=Amazon/CN=Amazon RSA 2048 M03
   i:/C=US/O=Amazon/CN=Amazon Root CA 1
 2 s:/C=US/O=Amazon/CN=Amazon Root CA 1
   i:/C=US/ST=Arizona/L=Scottsdale/O=Starfield Technologies, Inc./CN=Starfield Services Root Certificate Authority - G2
subject=/CN=web.app.kktkht94.work
issuer=/C=US/O=Amazon/CN=Amazon RSA 2048 M03

# NLB経由
$ openssl s_client -connect internal.app.kktkht94.work:443  -servername internal.app.kktkht94.work | grep CN=
depth=2 C = US, O = Amazon, CN = Amazon Root CA 1
verify return:1
depth=1 C = US, O = Amazon, CN = Amazon RSA 2048 M02
verify return:1
depth=0 CN = internal.app.kktkht94.work
verify return:1
 0 s:/CN=internal.app.kktkht94.work
   i:/C=US/O=Amazon/CN=Amazon RSA 2048 M02
 1 s:/C=US/O=Amazon/CN=Amazon RSA 2048 M02
   i:/C=US/O=Amazon/CN=Amazon Root CA 1
 2 s:/C=US/O=Amazon/CN=Amazon Root CA 1
   i:/C=US/ST=Arizona/L=Scottsdale/O=Starfield Technologies, Inc./CN=Starfield Services Root Certificate Authority - G2
subject=/CN=internal.app.kktkht94.work
issuer=/C=US/O=Amazon/CN=Amazon RSA 2048 M02

証明書を複数管理する必要はありますが、別途リバースプロキシを用意しなくていいのは利点になりそうです。 古いサーバによってはHTTPSが使えない場合があるため、HTTPで通信したい場合はALB側に別途80ポートのリスナーを用意するなど工夫が必要そうですが未検証です。

今回の用途上、特定のパスのみNLB経由のみでアクセス可能する用途も含まれると思います。これを実現するためにはALBのリスナールールで設定するかサーバ側、WAF等でアクセス制限設定をいれることになりそうですが実用上問題ないのか。