CLBでのHTTPS/TLSのターミネーション設定について

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、「どうやって直すのか?」 という具体的な修復手順(コンソール、AWS CLI、Terraformなど)まで、分かりやすく解説します。

この記事では、Classic Load Balancer (CLB) のリスナーがHTTPSまたはTLSターミネーションで設定されていない状態について、リスクと対策を解説します。

ポリシーの説明

Elastic Load Balancing の Security Hub コントロール – AWS Security Hub

このコントロールは、Classic Load Balancer リスナーがフロントエンド (クライアントからロードバランサー) 接続に HTTPS または TLS プロトコルを使用するよう設定されているかどうかをチェックします。このコントロールは、Classic Load Balancer にリスナーが有効な場合に適用されます。Classic Load Balancer にリスナーが設定されていない場合、コントロールは結果を報告しません。

リスク

Amazon Elastic Load Balancing (ELB) のClassic Load Balancer (CLB) は、ウェブトラフィックを分散するための基本的なロードバランサーですが、リスナーがHTTPS/TLS(Transport Layer Security)ターミネーションで設定されていない場合、以下のような重大なセキュリティリスクが発生します。

  • 中間者攻撃 (Man-in-the-Middle Attack) の可能性: HTTPリスナーのみを使用している場合、クライアントとCLB間の通信は暗号化されません。これにより、攻撃者は通信内容を傍受し、機密情報(ユーザー名、パスワード、個人情報など)を盗聴したり、データを改ざんしたりする可能性があります。
  • データ漏洩のリスク: 送信されるデータが暗号化されていないため、ネットワーク上のどこかでデータが傍受された場合、顧客情報やビジネスデータなどの機密情報が露呈する可能性があります。
  • コンプライアンス違反: 多くの業界規制やデータプライバシー法(例: PCI DSS, HIPAA, GDPR)では、機密データの転送における暗号化が義務付けられています。HTTPS/TLSを使用しない場合、これらの規制に違反し、法的な問題や高額な罰金につながる可能性があります。
  • ユーザーからの信頼失墜: 現代のウェブサイトではHTTPSの使用が標準となっており、ブラウザはHTTP接続に対して「安全でない」警告を表示することがあります。これにより、ユーザーはサイトの利用をためらい、ビジネスの信頼性やブランドイメージが損なわれる可能性があります。
  • 機能制限: HTTP/2や、最新のTLSプロトコルバージョンなど、HTTPS/TLS接続に関連する多くのパフォーマンスやセキュリティ機能は、HTTPリスナーでは利用できません。

対策

Classic Load BalancerのリスナーをHTTPSまたはTLSターミネーションで設定することは、データ通信のセキュリティを確保し、ユーザーの信頼を得るために不可欠です。

  • HTTPS/TLSリスナーの有効化: CLBのリスナー設定で、HTTP (ポート80) ではなく HTTPS (ポート443) または TLS を使用するように設定します。
  • SSL/TLS証明書のインストール: HTTPS/TLSリスナーにはSSL/TLS証明書が必要です。AWS Certificate Manager (ACM) で証明書をプロビジョニングし、それをCLBにアタッチするのが最も簡単な方法です。ACMは無料でパブリック証明書を発行・更新します。
  • セキュアなポリシーの選択: CLBは、事前定義されたセキュリティポリシー(SSLポリシー)を提供します。最新のTLSプロトコルバージョンと強力な暗号スイートを含むポリシーを選択し、古い脆弱なプロトコルや暗号化アルゴリズムを無効化します。
  • バックエンドインスタンスへの通信: CLBからバックエンドのEC2インスタンスへの通信は、通常、VPC内部で行われるため暗号化は必須ではありませんが、セキュリティ要件に応じてHTTPS/TLSを使用することも可能です。ただし、CLBが暗号化と復号化を行うため、通常はバックエンドインスタンスではHTTPで処理されます(これが「TLSターミネーション」の意味です)。
  • HTTPからHTTPSへのリダイレクト: HTTP (ポート80) へのリクエストをHTTPS (ポート443) へ自動的にリダイレクトするよう、アプリケーションまたはCLBのルールを設定することを検討してください。これにより、ユーザーが誤ってHTTPでアクセスした場合でも、安全な接続に誘導されます。

修復方法

AWSコンソールでの修復手順

AWSコンソールを使用して、Classic Load BalancerにHTTPS/TLSリスナーを設定します。

  1. EC2サービスへ移動:
    • AWSコンソールにログインし、EC2サービスを開きます。
  2. ロードバランサーの選択:
    • 左側のナビゲーションペインで「ロードバランサー」を選択します。
    • HTTPS/TLSリスナーを設定したい「Classic Load Balancer」を選択します。
  3. リスナーの追加または編集:
    • ロードバランサーの詳細ページで、「リスナー」タブを選択します。
    • 新しいリスナーを追加する場合は、「リスナーの追加」をクリックします。既存のHTTPリスナーを編集する場合は、そのリスナーを選択して「編集」をクリックします。
  4. HTTPS/TLSリスナーの設定:
    • プロトコルとポート:
      • 「ロードバランサーのプロトコル」で「HTTPS」または「SSL」を選択します。
      • 「ロードバランサーのポート」で「443」を選択します。
      • 「インスタンスのプロトコル」は「HTTP」または「HTTPS」(バックエンドとの通信も暗号化する場合)を選択し、「インスタンスのポート」を適切なポート(例: 80または443)に設定します。
    • SSL証明書:
      • 「SSL証明書」セクションで、AWS Certificate Manager (ACM) にインポートまたは発行済みの証明書を選択します。または、IAMにアップロード済みの証明書を選択します。
    • SSLセキュリティポリシー:
      • 「SSLセキュリティポリシー」で、最新かつ最も安全なポリシー(例: ELBSecurityPolicy-2016-08ELBSecurityPolicy-TLS13-xxxx など)を選択します。
  5. 設定の保存:
    • 設定を確認し、「追加」(新規リスナーの場合)または「保存」(既存リスナーの場合)をクリックして変更を適用します。

Terraformでの修復手順

TerraformでClassic Load BalancerのリスナーをHTTPSまたはTLSターミネーションで設定するには、aws_elb リソースの listener ブロックで lb_protocol"HTTPS" または "SSL" に設定し、ssl_certificate_id および policies を指定します。

# AWS Certificate Manager (ACM) で証明書をプロビジョニング済みであることを前提とします。
# 既存のACM証明書を参照するデータソース
data "aws_acm_certificate" "example_certificate" {
  domain = "your.domain.com" # あなたのドメイン名に置き換えてください
  statuses = ["ISSUED"]
}

# Classic Load Balancer (CLB) の定義
resource "aws_elb" "my_clb" {
  name               = "my-secure-classic-load-balancer"
  security_groups    = [aws_security_group.clb_sg.id]
  subnets            = [aws_subnet.public_a.id, aws_subnet.public_c.id] # あなたのサブネットIDに置き換え
  internal           = false # 内部ロードバランサーの場合 true

  # HTTPS/TLSリスナーの設定
  listener {
    instance_port     = 80               # バックエンドインスタンスのポート (HTTPで受け取る場合)
    instance_protocol = "HTTP"           # バックエンドインスタンスとのプロトコル
    lb_port           = 443              # ロードバランサーの公開ポート
    lb_protocol       = "HTTPS"          # ロードバランサーのプロトコルをHTTPSに設定
    ssl_certificate_id = data.aws_acm_certificate.example_certificate.arn # ACM証明書のARNを指定

    # 最新かつ推奨されるSSLセキュリティポリシーを選択
    # 利用可能なポリシーはAWSドキュメントを参照:
    # <https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-security-policy-options.html>
    policies = ["ELBSecurityPolicy-TLS13-Ext-2021-06"] # 最新のTLS 1.3サポートポリシーなど
  }

  # (オプション) HTTPからHTTPSへのリダイレクトが必要な場合は、Webサーバーレベルで設定するか、
  # ALBを使用することを検討してください。CLBでは直接リダイレクト機能はありません。
  # 例: 80番ポートも開けて、Webサーバー側でリダイレクトする場合
  listener {
    instance_port     = 80
    instance_protocol = "HTTP"
    lb_port           = 80
    lb_protocol       = "HTTP"
  }

  health_check {
    healthy_threshold   = 2
    unhealthy_threshold = 2
    timeout             = 3
    target              = "HTTP:80/" # バックエンドのヘルスチェックパス
    interval            = 30
  }

  connection_draining         = true
  connection_draining_timeout = 300

  tags = {
    Name = "MySecureClassicLoadBalancer"
  }
}

# 関連リソースの定義例 (VPC, Subnet, Security Group など)
# これらのリソースは、あなたの環境に合わせて定義または参照してください。

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "main-vpc"
  }
}

resource "aws_subnet" "public_a" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "ap-northeast-1a" # あなたのリージョンに合わせて変更
  tags = {
    Name = "public-subnet-a"
  }
}

resource "aws_subnet" "public_c" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.2.0/24"
  availability_zone = "ap-northeast-1c" # あなたのリージョンに合わせて変更
  tags = {
    Name = "public-subnet-c"
  }
}

resource "aws_security_group" "clb_sg" {
  name        = "clb-security-group-https"
  description = "Allow HTTPS traffic to CLB"
  vpc_id      = aws_vpc.main.id

  ingress {
    from_port   = 443 # HTTPSポート
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"] # 適切なIP範囲に制限してください
  }
  ingress {
    from_port   = 80 # HTTPリダイレクト用またはテスト用
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"] # 適切なIP範囲に制限してください
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  tags = {
    Name = "clb-sg-https"
  }
}

最後に

上記のTerraformコードでは、aws_elb リソースの listener ブロックで、lb_protocol = "HTTPS"lb_port = 443ssl_certificate_id、そして適切な policies を指定しています。data "aws_acm_certificate" を使用して、事前にACMで発行された証明書を参照しています。

your.domain.com やサブネットIDなどのプレースホルダーは、実際の環境に合わせて修正してください。

この問題の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。

運用が非常に楽に出来る製品になっていますので、ぜひ興味がある方はお問い合わせお待ちしております。

最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです

この記事をシェアする

クラウドセキュリティ対策実践集一覧へ戻る

貴社の利用状況に合わせた見積もりを作成します。

料金プランを詳しく見る