Envoy Proxy による HTTPS Proxy
庄司です。
「WebAuthn でパスワードの無い世界へ」の記事では、AWS Fargate を使って Keycloak を起動してデモンストレーション環境を構築しました。
記事で説明した環境は、Keycloak のための AWS Fargate 以外に、ロードバランサ (ALB) など時間課金のリソースも含んでいました。
この記事では「S3 の静的 Web サイトをセキュアに Envoy でホスティング」などの記事で取り上げた Envoy Proxy を HTTPS Proxy として使用し AWS リソースの利用は Route 53 だけで、プライベートネットワーク上に HTTPS でアクセスする Keycloak 環境を構築します。
証明書
#無料の証明書という点では、自己署名証明書 (Self-signed Certificate、いわゆるオレオレ証明書) もありますが、この記事では Let's Encrypt で証明書を作成します。
準備
#Let's Encrypt で証明書を作成するために certbot をインストールして使用します。残念ながら Windows で動作する certbot は無いようです。著者は macOS を利用しました。Homebrew を使って次のコマンドでインストールできます。
brew install certbot
証明書の作成
#外部つまりインターネットからのアクセスを許可せずに証明書を作成するため、次のコマンドを使用します。
sudo certbot certonly --manual --preferred-challenges dns
Please enter in your domain name(s) (comma and/or space separated) (Enter 'c'
to cancel):
と聞かれるので、所有するドメイン名を入力します。このときワイルドカードを利用すると便利です。所有するドメイン名が example.com
だとすると、ワイルドカードを使った入力は *.example.com
となります。
ドメイン名の所有を確認するために、DNS (Route 53) にレコードの追加を求めるメッセージが表示されます。
指示に従って Route 53 に TXT レコードを追加します。
_acme-challenge.example.com TXT "<表示された値>"
このテキストレコードが認識されるまでに少し時間がかかるかもしれません、数分待って Enter キーを押します。
成功すると、/etc/letsencrypt/live/
にドメイン名のディレクトリが作成され、そのディレクトリに証明書が生成されます。example.com
の場合であれば /etc/letsencrypt/live/example.com
ディレクトリに証明書が生成されます。
Docker Compose による起動
#Envoy Proxy と Keycloak の2つのコンテナを起動するため、次の docker-compose.yml
ファイルを作成しました。
version: "3"
services:
envoy:
image: envoyproxy/envoy:v1.21-latest
volumes:
- ./front-envoy.yaml:/etc/front-envoy.yaml
- ./certs:/etc/envoy/certs
ports:
- 443:443
- 9901:9901
command: ["-c", "/etc/front-envoy.yaml", "--service-cluster", "front-proxy"]
keycloak:
image: quay.io/keycloak/keycloak
volumes:
- ./datadir:/opt/keycloak/data
command:
- start
- --proxy=edge
- --hostname-strict=false
- --http-relative-path
- auth
environment:
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: password
PROXY_ADDRESS_FORWARDING: true
/etc/letsencrypt/live/example.com/
ディレクトリに生成されたファイルは docker-compose.yml
ファイルがあるディレクトリに certs
ディレクトリを作成してコピーしてください。
docker-compose.yml
ファイルがあるディレクトリに front-envoy.yaml
ファイルも作成しました。
admin:
address:
socket_address:
address: 0.0.0.0
port_value: 9901
static_resources:
listeners:
- address:
socket_address:
address: 0.0.0.0
port_value: 443
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
codec_type: AUTO
stat_prefix: ingress_http
route_config:
name: auth_route
virtual_hosts:
- name: keycloak
domains:
- '*'
routes:
- match:
prefix: /
route:
cluster: keycloak
http_filters:
- name: envoy.filters.http.router
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
tls_certificates:
- certificate_chain:
filename: "/etc/envoy/certs/fullchain.pem"
private_key:
filename: "/etc/envoy/certs/privkey.pem"
validation_context:
trusted_ca:
filename: "/etc/envoy/certs/cert.pem"
clusters:
- name: keycloak
type: LOGICAL_DNS
load_assignment:
cluster_name: keycloak
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: keycloak
port_value: 8080
上記の設定で、外部からのアクセスを HTTPS で受ける listeners 設定のポイントは次のとおりです。
- socket_address で
port_value: 443
を設定します。 - filter_chains で
transport_socket
を設定して、証明書ファイルパスを設定します。
起動
#起動は docker compose up -d
です。停止は docker compose down
です。
DNS レコードの登録
#Route 53 に Keycloak を起動する PC の IP アドレスの A レコードを作成します。例えば、PC の IP アドレスが 192.168.1.2
の場合 keycloak.example.com
でアクセスするようにしたい場合は次の通りです。
keycloak.example.com A 192.168.1.2
Route 53 へのレコードの登録の反映には少し時間がかかるかもしれません。数分待って、iPad 等の Safari で上の例の場合では https://keycloak.example.com/auth
にアクセスしてください。Keycloak の Welcome 画面が表示されます。
Keycloak へのアクセスで使用する端末に PC を使う場合は、ここで説明したような DNS レコードではなく /etc/hosts
ファイルの使用も可能です。この記事では iPad、iPhone、Android 等の /etc/hosts
ファイルの編集ができない/困難な端末の使用を想定しているため、Route 53 にレコードを追加しています。
まとめ
#プライベートネットワークに HTTPS で提供するアプリケーションは、証明書として自己署名証明書を利用する方法、プロキシを使用せずアプリケーション自体に証明書をインストールする方法、プロキシに Nginx や HAProxy 等を利用する方法など、多くの選択肢があります。この記事では、証明書に Let's Encrypt を使い、プロキシに Envoy Proxy を利用する方法を説明しました。
この記事で説明した方法を使えば、Keycloak を任意の Web アプリケーションに代えて HTTPS アクセスに対応させることができ、特に開発中や試行中に AWS などのクラウドにかかるコストを抑制することが可能になります。
この記事で説明した docker-compose.yml
などのコードの全体は GitHub リポジトリ にあります。
次回 は構築したパスワードレス認証基盤をアプリケーションで使用するサンプル実装を説明します。