0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

証明書なしでhttps通信を実装する方法(AWS)

Last updated at Posted at 2026-01-08

目的

PoCなどで、証明書を用意する手間なくhttps通信を実装する方法を調べました。
初学者のため、内容に誤りや適切ではない情報があればご指摘いただけると嬉しいです。

概要

CloudFrontのデフォルト証明書を使うことで、 *.cloudfront.net でブラウザ公的信頼のHTTPS通信を実現することができます。ただし、URLが xxxxx.cloudfront.net となるため本番環境などでは使用できません。

構成

今回はALB経由でEC2のWebサーバーに接続する構成とします。
ALBはセキュリティグループとカスタムヘッダーを使用して、CloudFrontからのアクセスのみ許可するよう設定します。
※CloudFrontのVPCオリジン機能を使うことで、ALBをPrivate Subnetに配置する構成も可能です。
名称未設定ファイル.drawio.png

手順

※VPCは事前に作成済みの想定です。

1. セキュリティグループ作成

EC2用

aws ec2 create-security-group --group-name ec2-sg --description "Security group for EC2" --vpc-id $VPC_ID
aws ec2 authorize-security-group-ingress --group-id $SG_EC2_ID --protocol tcp --port 80 --cidr 10.0.0.0/16

ALB用
CloudFrontが使用するIPアドレスのリスト(マネージドプレフィックスリスト)のIDを取得して、該当アドレスからの通信のみを許可することで、CloudFront以外からのアクセスを拒否します。

PL_ID=$(aws ec2 describe-managed-prefix-lists --query "PrefixLists[?PrefixListName=='com.amazonaws.global.cloudfront.origin-facing'].PrefixListId" --output text)

aws ec2 create-security-group --group-name alb-sg --description "Security group for ALB" --vpc-id $VPC_ID
aws ec2 authorize-security-group-ingress \
    --group-id $SG_ALB_ID \
    --ip-permissions "IpProtocol=tcp,FromPort=80,ToPort=80,PrefixListIds=[{PrefixListId=$PL_ID}]"

2. EC2(WEBサーバー)作成

※「$」で始まる変数は適切に設定が必要です

aws ec2 run-instances \
    --image-id $AMI_ID \
    --instance-type t2.micro \
    --security-group-ids $SG_EC2_ID \
    --subnet-id $SN_PRV \
    --user-data '#!/bin/bash
                 yum update -y
                 yum install -y httpd
                 systemctl start httpd
                 systemctl enable httpd
                 echo "<h1>Success! Hello via HTTPS</h1>" > /var/www/html/index.html'

3. ALB作成

※「$」で始まる変数は適切に設定が必要です
ターゲットグループ・リスナー・ALBの作成と合わせて、カスタムヘッダーに指定した文字列が含まれない場合の通信を拒否するよう設定します。そうすることで、自身が作成したCloudFront以外からのアクセスを防ぎます。

# ターゲットグループ & 登録
aws elbv2 create-target-group --name my-targets --protocol HTTP --port 80 --vpc-id $VPC_ID
aws elbv2 register-targets --target-group-arn $TG_ARN --targets Id=$INSTANCE_ID

# ALB & リスナー作成
aws elbv2 create-load-balancer --name my-alb --subnets $SN_PUB_1 $SN_PUB_2 --security-groups $SG_ALB_ID
aws elbv2 create-listener --load-balancer-arn $ALB_ARN --protocol HTTP --port 80 --default-actions Type=forward,TargetGroupArn=$TG_ARN

# カスタムヘッダーが正しくなければ拒否するよう設定
aws elbv2 create-rule \
    --listener-arn $LISTENER_ARN \
    --priority 1 \
    --conditions '{"Field":"http-header","HttpHeaderConfig":{"HttpHeaderName":"X-Custom-Header","Values":["MySecret123"]}}' \
    --actions Type=forward,TargetGroupArn=$TG_ARN
aws elbv2 modify-listener \
    --listener-arn $LISTENER_ARN \
    --default-actions '{"Type":"fixed-response","FixedResponseConfig":{"MessageBody":"Access Denied","StatusCode":"403","ContentType":"text/plain"}}'

4. CloudFront Distribution作成

カスタムヘッダーに、ALBで許可している文字列を入れるよう設定しています。

# 作成用のJSONを生成(一意のCallerReferenceが必要なのでdateコマンドを使用)
DIST_CONFIG=$(jq -n \
  --arg dns "$ALB_DNS" \
  --arg ref "ref-$(date +%s)" \
  --arg header_name "X-Custom-Header" \
  --arg header_value "MySecret123" \
  '{
    "CallerReference": $ref,
    "Aliases": {"Quantity": 0},
    "DefaultRootObject": "index.html",
    "Origins": {
      "Quantity": 1,
      "Items": [
        {
          "Id": "ALB-Origin",
          "DomainName": $dns,
          "CustomHeaders": {
            "Quantity": 1,
            "Items": [
              {
                "HeaderName": $header_name,
                "HeaderValue": $header_value
              }
            ]
          },
          "CustomOriginConfig": {
            "HTTPPort": 80,
            "HTTPSPort": 443,
            "OriginProtocolPolicy": "http-only"
          }
        }
      ]
    },
    "DefaultCacheBehavior": {
      "TargetOriginId": "ALB-Origin",
      "ForwardedValues": {
        "QueryString": false,
        "Cookies": {"Forward": "none"}
      },
      "TrustedSigners": {"Enabled": false, "Quantity": 0},
      "ViewerProtocolPolicy": "redirect-to-https",
      "MinTTL": 0
    },
    "CacheBehaviors": {"Quantity": 0},
    "Comment": "Created via CLI with Custom Header",
    "Enabled": true
  }')
  
# 作成
aws cloudfront create-distribution --distribution-config "$DIST_CONFIG"

5. アクセス確認

CloudFrontのURLにアクセスすると、https通信でEC2のWebサーバーにアクセスできていることがわかります。
image.png

まとめ

ドメインや証明書の用意が難しい状況でhttps接続が必要だったため、このような構成を試してみました。素直にドメイン・証明書を用意するのがベターかと思いますが、このような方法もあるのだと学ぶことができました。

(続き)CloudFrontへの最低限の認証の実装
 https://qiita.com/hirotaka_s/items/cbd72b0f72f4d48dccb1

(続き)Cognito認証を連携させる
 https://qiita.com/hirotaka_s/items/d3a88e11c40b7515f014

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?