📌 結論:2段階のHTTPS暗号化で安全な通信を実現
インターネット → ALB
ACM証明書を使用
無料・自動更新
ブラウザに信頼される
🔒 公的な身分証明
無料・自動更新
ブラウザに信頼される
🔒 公的な身分証明
ALB
TLS終端ポイント
証明書を管理
負荷分散を実行
🏢 ビルの受付係
証明書を管理
負荷分散を実行
🏢 ビルの受付係
ALB → EC2
自己署名証明書を使用
内部通信も暗号化
VPC内で完結
🪪 社員証での認証
内部通信も暗号化
VPC内で完結
🪪 社員証での認証
🏢 会社のビルで例えると超わかりやすい!
🏢 あなたの会社(AWSインフラ)
来客
(ユーザー)
➡️
ビル受付
(ALB)
🏛️ 公的身分証で確認
➡️
オフィス
(EC2)
🪪 社員証で確認
🎯 ポイント:
ビル受付(ALB)では公的な身分証明書(ACM証明書)で来客を確認
→ 誰でも信頼できる第三者機関が発行した証明書
オフィス内(EC2)では社員証(自己署名証明書)で通信
→ 社内だけで通用する証明書で十分!
🏗️ システム構成図
ユーザー
ブラウザ
🔒 HTTPS
➡️
ACM証明書
ALB
Application
Load Balancer
Load Balancer
🔐 HTTPS
➡️
自己署名証明書
EC2
Webサーバー
(nginx等)
(nginx等)
ACM
AWS Certificate Manager
証明書を無料発行・自動更新
証明書を無料発行・自動更新
🔐 2段階暗号化の仕組み
第1段階:外部通信
📍 区間:インターネット → ALB
🔑 証明書:ACM発行のTLS証明書
✅ 特徴:ブラウザが信頼する公的証明書
💰 費用:無料!
🏛️ 公的認証機関が保証
➡️
第2段階:内部通信
📍 区間:ALB → EC2(VPC内)
🔑 証明書:自己署名証明書
✅ 特徴:内部でも暗号化を維持
💰 費用:無料(自分で作成)
🪪 社内専用の認証
📊 ACM証明書 vs 自己署名証明書 比較
| 比較項目 | 🏛️ ACM証明書 | 🪪 自己署名証明書 |
|---|---|---|
| 🎯 使用場所 | ALB(外部公開) | EC2(内部通信) |
| 🔐 ブラウザの信頼 | ✅ 信頼される | ⚠️ 警告が出る |
| 💰 費用 | 無料(AWS提供) | 無料(自作) |
| 🔄 自動更新 | ✅ 自動 | ❌ 手動で管理 |
| ⚙️ 設定の手間 | 簡単(数クリック) | やや複雑(コマンド実行) |
| 🏢 たとえ話 | パスポート・運転免許証 | 社員証・名札 |
| ✨ 適した用途 | 外部からのアクセス | VPC内部の通信 |
🔧 設定手順ガイド
ACM証明書 + ALB設定
1
ACMで証明書をリクエスト
ACMコンソール → 証明書をリクエスト → ドメイン名を入力
2
ドメイン検証
DNS検証(推奨)またはEメール検証でドメイン所有を証明
3
ALBリスナー設定
HTTPSリスナー(443)を追加 → ACM証明書を選択
4
ターゲットグループ設定
プロトコル: HTTPS / ポート: 443 を指定
5
ヘルスチェック設定
HTTPS プロトコルでEC2の正常性を確認
EC2自己署名証明書設定
1
OpenSSLで秘密鍵を生成
RSA 2048ビット以上の秘密鍵を作成
2
自己署名証明書を生成
秘密鍵を使ってX.509証明書を作成
3
証明書を配置
/etc/ssl/certs/ 配下に証明書と秘密鍵を配置
4
nginx/Apache設定
SSL設定で証明書のパスを指定
5
Webサーバー再起動
設定を反映してHTTPSを有効化
💻 設定コード例
🔑 自己署名証明書の作成
# 1. 秘密鍵の生成(RSA 2048ビット)
openssl genrsa -out /etc/ssl/private/server.key 2048
# 2. 自己署名証明書の生成(有効期限365日)
openssl req -new -x509 \
-key /etc/ssl/private/server.key \
-out /etc/ssl/certs/server.crt \
-days 365 \
-subj "/C=JP/ST=Tokyo/L=Tokyo/O=MyCompany/CN=internal.example.com"
# 3. 権限の設定
chmod 600 /etc/ssl/private/server.key
chmod 644 /etc/ssl/certs/server.crt
🌐 nginx SSL設定
# /etc/nginx/sites-available/default
server {
listen 443 ssl;
server_name _;
# SSL証明書の設定
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/private/server.key;
# SSL設定(推奨)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root /var/www/html;
index index.html;
}
# ヘルスチェック用エンドポイント
location /health {
return 200 'OK';
add_header Content-Type text/plain;
}
}
☁️ AWS CLI(ALB設定)
# HTTPSリスナーの作成(ACM証明書を使用)
aws elbv2 create-listener \
--load-balancer-arn "arn:aws:elasticloadbalancing:..." \
--protocol HTTPS \
--port 443 \
--certificates CertificateArn="arn:aws:acm:ap-northeast-1:123456789012:certificate/xxx" \
--default-actions Type=forward,TargetGroupArn="arn:aws:elasticloadbalancing:..."
# ターゲットグループ(HTTPS/443でEC2に転送)
aws elbv2 create-target-group \
--name "my-https-targets" \
--protocol HTTPS \
--port 443 \
--vpc-id "vpc-xxx" \
--health-check-protocol HTTPS \
--health-check-path "/health"
🤔 なぜこの構成が必要なの?
エンドツーエンド暗号化
- ユーザー→ALB→EC2の全区間で暗号化
- VPC内でもデータが保護される
- コンプライアンス要件を満たせる
- 万が一の内部漏洩にも対応
コスト最適化
- ACM証明書は無料で使える
- 自己署名証明書も無料で作成
- 内部通信に高価な証明書は不要
- 自動更新で運用コスト削減
運用の効率化
- ACMは自動更新で手間いらず
- ALBでTLS終端を集中管理
- EC2の証明書管理が簡素化
- スケーリングにも対応しやすい
セキュリティ強化
- 外部にはACMの信頼性を提供
- 内部通信も暗号化で二重防御
- 中間者攻撃を防止
- 監査要件への対応
✨ ベストプラクティス
証明書の自動更新
ACMは自動更新。EC2の自己署名証明書はcronで定期更新を設定しましょう
監視の設定
CloudWatchで証明書の有効期限をモニタリング、アラートを設定
TLS 1.2以上を使用
古いTLS 1.0/1.1は無効化。TLS 1.2以上のみを許可
秘密鍵の保護
chmod 600で権限を制限。IAMロールでアクセス制御
ヘルスチェック設定
ALBのヘルスチェックはHTTPSプロトコルで実施
ログの有効化
ALBアクセスログを有効化して、通信を記録・分析
🪪 自己署名証明書 徹底解説
📜 自己署名証明書とは?
自分で発行・自分で署名したTLS/SSL証明書のことです。
認証局(CA)を介さずに、自分自身で「この証明書は正しい」と署名します。
🏛️
CA発行の証明書
パスポート・運転免許証
政府・公的機関が発行
→ 誰もが信頼できる
🪪
自己署名証明書
手書きの名刺・社員証
自分・自社で作成
→ 内部でのみ有効
🔄 CA証明書との違い(仕組み)
✅ CA証明書の場合
👤 ユーザー
↓ 「この証明書は本物?」
🏛️ 認証局(CA)に確認
↓
✅ 「はい、私が保証します」
↓ 「この証明書は本物?」
🏛️ 認証局(CA)に確認
↓
✅ 「はい、私が保証します」
⚠️ 自己署名証明書の場合
👤 ユーザー
↓ 「この証明書は本物?」
🤷 誰にも確認できない
↓
⚠️ 「自分で自分を保証してます」
↓ 「この証明書は本物?」
🤷 誰にも確認できない
↓
⚠️ 「自分で自分を保証してます」
✅ メリット
- 💰 完全無料 - コストゼロで作成可能
- ⚡ 即座に発行 - コマンド1つで数秒で作成
- 🔒 暗号化は同等 - 通信の暗号化強度はCA証明書と同じ
- 🏠 内部利用に最適 - VPC内、開発環境、テスト環境向け
- 🔧 柔軟な設定 - 有効期限や属性を自由に設定
⚠️ デメリット
- 🚫 ブラウザで警告 - 「この接続は安全ではありません」と表示
- ❌ 外部公開に不向き - ユーザーに不信感を与える
- 🔄 手動更新が必要 - 有効期限管理を自分で行う
- 🤝 第三者の保証なし - 「本当にこのサーバー?」の証明不可
- 📋 管理の手間 - 証明書の期限切れに注意が必要
🎯 使用場面ガイド
✅ 適している場面
- 🧪 開発・テスト環境
- 🔗 VPC内部の通信(ALB → EC2)
- 🏢 社内システム・イントラネット
- 🔀 マイクロサービス間通信
- 🔄 CI/CDパイプライン
- 📊 監視・管理ツールへのアクセス
❌ 適さない場面
- 🌐 本番の外部公開サイト
- 🛒 ECサイト・オンラインストア
- 💳 決済ページ・金融サービス
- 👥 ユーザーが直接アクセスするサービス
- 📱 モバイルアプリのAPI(公開)
- 🏥 医療・法的に規制されるサービス
💻 自己署名証明書の作成コマンド詳解
# 基本的な作成コマンド(1行で完結)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout server.key \
-out server.crt \
-subj "/C=JP/ST=Tokyo/L=Tokyo/O=MyCompany/CN=internal.example.com"
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout server.key \
-out server.crt \
-subj "/C=JP/ST=Tokyo/L=Tokyo/O=MyCompany/CN=internal.example.com"
-x509
自己署名証明書を作成(CSRではなく)
-nodes
パスフレーズなし(自動起動に便利)
-days 365
有効期限を365日(1年)に設定
-newkey rsa:2048
2048ビットのRSA鍵を新規作成
-keyout
秘密鍵の出力先ファイル名
-out
証明書の出力先ファイル名
# subj(サブジェクト)の各フィールド
/C=JP # Country(国コード)
/ST=Tokyo # State(都道府県)
/L=Tokyo # Locality(市区町村)
/O=MyCompany # Organization(組織名)
/CN=internal # Common Name(ドメイン名)← 最重要!
/C=JP # Country(国コード)
/ST=Tokyo # State(都道府県)
/L=Tokyo # Locality(市区町村)
/O=MyCompany # Organization(組織名)
/CN=internal # Common Name(ドメイン名)← 最重要!
🔄 証明書の自動更新(cron設定)
#!/bin/bash
# /usr/local/bin/renew-cert.sh
# 証明書を再生成
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/server.key \
-out /etc/ssl/certs/server.crt \
-subj "/CN=internal.example.com"
# 権限設定
chmod 600 /etc/ssl/private/server.key
# nginx再起動
systemctl reload nginx
# ログ出力
echo "$(date): Certificate renewed" >> /var/log/cert-renewal.log
# /usr/local/bin/renew-cert.sh
# 証明書を再生成
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/server.key \
-out /etc/ssl/certs/server.crt \
-subj "/CN=internal.example.com"
# 権限設定
chmod 600 /etc/ssl/private/server.key
# nginx再起動
systemctl reload nginx
# ログ出力
echo "$(date): Certificate renewed" >> /var/log/cert-renewal.log
📅 cron設定例(毎月1日に更新):
0 3 1 * * /usr/local/bin/renew-cert.sh
🔍 証明書の確認コマンド
📋 証明書の内容を確認
openssl x509 -in server.crt -text -noout
📅 有効期限のみ確認
openssl x509 -in server.crt -noout -dates
🔑 秘密鍵の確認
openssl rsa -in server.key -check
🔗 証明書と鍵の一致確認
openssl x509 -noout -modulus -in server.crt | md5sum
openssl rsa -noout -modulus -in server.key | md5sum
💡 Tip: 証明書と秘密鍵のmd5sumが一致していれば、ペアが正しいことを確認できます!
❓ よくある質問
🤔
なぜEC2でもACM証明書を使わないの?
ACM証明書はALB/CloudFront等のAWSサービスでのみ使用可能です。
EC2インスタンスに直接インストールすることはできません。そのため、EC2では自己署名証明書か、サードパーティの証明書を使用します。VPC内部の通信であれば、自己署名証明書で十分なセキュリティを確保できます。
EC2インスタンスに直接インストールすることはできません。そのため、EC2では自己署名証明書か、サードパーティの証明書を使用します。VPC内部の通信であれば、自己署名証明書で十分なセキュリティを確保できます。
🤔
ALB → EC2 間はHTTPじゃダメなの?
セキュリティ要件によります。
VPC内でも暗号化が必要な場合(PCI-DSS、HIPAA等のコンプライアンス要件)は、ALB→EC2間もHTTPSにする必要があります。機密性の高いデータを扱う場合は、エンドツーエンド暗号化を推奨します。
VPC内でも暗号化が必要な場合(PCI-DSS、HIPAA等のコンプライアンス要件)は、ALB→EC2間もHTTPSにする必要があります。機密性の高いデータを扱う場合は、エンドツーエンド暗号化を推奨します。
🤔
自己署名証明書の有効期限はどれくらいが適切?
1年(365日)程度が一般的です。
あまり長すぎると、セキュリティ上のリスクが高まります。cronジョブで自動更新する仕組みを作っておくと、運用が楽になります。自動化スクリプトを用意しておくことをお勧めします。
あまり長すぎると、セキュリティ上のリスクが高まります。cronジョブで自動更新する仕組みを作っておくと、運用が楽になります。自動化スクリプトを用意しておくことをお勧めします。
🤔
ALBのヘルスチェックで自己署名証明書は問題ない?
問題ありません!
ALBは自己署名証明書を使ったHTTPSエンドポイントにもヘルスチェックできます。「証明書の検証をスキップ」する設定がデフォルトで有効なので、特別な設定は不要です。
ALBは自己署名証明書を使ったHTTPSエンドポイントにもヘルスチェックできます。「証明書の検証をスキップ」する設定がデフォルトで有効なので、特別な設定は不要です。
🎓 まとめ
ユーザー
🔒➡️
ALB
ACM証明書
🔐➡️
EC2
自己署名証明書