🌟

Application Gatewayでバックエンドを自己署名証明書でHTTPS構成してみた

に公開

Application Gatewayでバックエンドを自己署名証明書でHTTPS構成してみた

この記事は部分的に生成AIを利用して作成しています。

はじめに

Azure Application Gatewayは、Azureが提供するL7ロードバランサーサービスです。
通常、セキュリティを高めるためには、クライアント〜Application Gateway間も、Application Gateway〜バックエンド間もHTTPS接続にすべきですが、本記事ではバックエンド間のHTTPS通信にフォーカスをあて、できるだけコストを抑えた構成で検証してみました。

Application GatewayからバックエンドVMまでは自己署名証明書によるHTTPS通信を行い、ロードバランサー内部の通信も暗号化できるメリットを紹介します。


構成図

alt text

  • Application Gateway: Standard_v2 SKU (最小サイズ、ゾーン冗長無しでコスト最小化)
  • バックエンドVM: B1sインスタンス (最安VM、スポット使用可)
  • Nginxコンテナ: 自己署名証明書を使用してHTTPSリッスン
  • ネットワーク: 最小構成のVNet+Subnet

なぜバックエンドHTTPSが重要なのか?

通常、クラウド環境ではロードバランサーとバックエンド間はプライベートネットワーク上にあります。しかし、仮に悪意ある内部攻撃者や設定ミスが発生した場合、平文HTTP通信では盗聴されるリスクが残ります。

バックエンド間もHTTPSにすることで、Application Gatewayとバックエンド間の通信内容を暗号化でき、セキュリティが一段向上します。


実際の構築手順

1. バックエンドVMの作成

Azure PortalまたはCLIで最小構成のLinux VMを作成します。

az vm create `
  --resource-group <Resource Group> `
  --name backend-vm `
  --image Ubuntu2204 `
  --size Standard_B1s `
  --admin-username azureuser `
  --generate-ssh-keys `
  --vnet-name <VNet> `
  --subnet <Subnet> `
  --nsg <NSG> `
  --public-ip-sku Basic `
  --os-disk-size-gb 30 `
  --storage-sku StandardSSD_LRS `
  --location japaneast `
  --no-wait

2. Azure DNS

  • プライベートホストゾーンを作成(例:backend.private)
  • ホスト名とAzure VMのIPアドレスでAレコードを作成する
  • VNET統合を忘れないこと(VNETのリソースから名前解決できるようにする)
  • xxxx.localはなるべく避ける。(Azureの裏側で使っているのか、名前解決ができない場合がある)

3. Nginxコンテナのセットアップ

VMにSSH接続して、Dockerをインストールし、自己署名証明書を使ったNginxコンテナを起動します。

# Dockerインストール
sudo apt update
sudo apt install -y docker.io
sudo systemctl start docker
sudo systemctl enable docker

# 自己署名証明書を作成
mkdir ~/certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout ~/certs/nginx-selfsigned.key \
  -out ~/certs/nginx-selfsigned.crt \
  -subj "/CN=backend.private"

# Nginx用Dockerfile作成
mkdir ~/nginx
cat <<EOF > ~/nginx/Dockerfile
FROM nginx:alpine
COPY nginx.conf /etc/nginx/nginx.conf
COPY certs /etc/nginx/certs
EOF

# Nginx設定ファイル
cat <<EOF > ~/nginx/nginx.conf
events {}
http {
  server {
    listen 443 ssl;
    ssl_certificate /etc/nginx/certs/nginx-selfsigned.crt;
    ssl_certificate_key /etc/nginx/certs/nginx-selfsigned.key;
    location / {
      return 200 'Hello from HTTPS backend!';
    }
  }
}
EOF

# コンテナビルド・起動
cd ~/nginx
docker build -t mynginx-https .
docker run -d -p 443:443 mynginx-https

これでVM上でHTTPSサーバーが立ち上がります。

4. Application Gatewayの作成

次に、Application Gatewayを作成します。ポイントは以下。

  • FrontendはHTTP
  • BackendはHTTPSポート(443)
  • バックエンドの自己署名証明書を信頼された証明書としてアップロードする

Application Gateway作成はPortalでもCLIでも可能ですが、ここでは簡単なPortal手順を記載します。

  • Frontend IP: パブリック
  • Listener: HTTP
  • Backend Pool: backend-vmのNICプライベートIPを登録
  • Backend Settings:
    • ポート: 443
    • プロトコル: HTTPS
    • "Use well known CA certificate" をNoに設定(ここが重要)
    • Nginxに使用しているサーバ証明書をローカルにダウンロードしてきたら、拡張子をCRTからCERに変更してそのままコンソール経由でアップロード

5. 正常性プローブの設定

Application Gatewayのカスタムプローブを作成します。

  • プローブ対象のポート: 443
  • プロトコル: HTTPS

テスト接続をすると失敗してしまいますが、サポートに問い合わせたところ仕様とのことでした…
詳しくはわかりませんが、テスト接続の場合は信頼した証明書は使わずに素で見に行くんでしょうかね。
テスト接続で失敗しても保存はできるので保存した後に、バックエンドの正常性確認で「正常」と表示されていれば設定は成功です。


まとめ

今回のポイントは次の通りです。

  • Azure DNSのプライベートホストゾーンを使う際は、名前に.localとつくものは避ける
  • Application GatewayからバックエンドVM間の通信もHTTPSにできると、内部通信まで暗号化されセキュリティが向上する
  • 自己署名証明書を使って簡単にHTTPSバックエンドを構成できる
  • Azureの仕様で内部テストは失敗扱いになるが、バックエンド正常なら問題ない

本番環境ではLet's Encryptなどの正式な証明書を使うことが推奨されますが、社内環境やPoC用途ではこの構成で十分実用的です。

また、こちらの記事も参考になります。
https://learn.microsoft.com/ja-jp/azure/application-gateway/self-signed-certificates

Discussion