1. ネットワーク構成図
本構成で使用する4つのコンポーネントとその通信経路を示します。
graph TD
Browser["クライアント (ブラウザ)"]
subgraph AWS["AWS (us-east-1)"]
direction LR
Ansible["Ansible Controller
Ubuntu 22.04"]
IIS["Windows Server 2022
IIS 10 + OpenSSH"]
R53["DNS
example.com"]
end
subgraph DigiCert["DigiCert ONE (SaaS)"]
direction LR
ACME["ACME Endpoint
one.digicert.com"]
TLM["Trust Lifecycle Manager"]
CA["CA Manager"]
ACME --- TLM --- CA
end
Browser -- "HTTPS (443/tcp)" --> IIS
Ansible -- "SSH (22/tcp) certreq制御" --> IIS
Ansible -- "HTTPS (443/tcp) DNS API" --> R53
Ansible -- "HTTPS (443/tcp) ACME" --> ACME
ACME -. "DNS-01 検証 (TXTレコード確認)" .-> R53
R53 -. "DNS解決 (Aレコード / TXT _acme-challenge)" .-> IIS
style AWS fill:#fff3e0,stroke:#f57c00
style DigiCert fill:#e8f4fd,stroke:#0174c3
style Ansible fill:#c8e6c9,stroke:#388e3c
style IIS fill:#bbdefb,stroke:#1976d2
style R53 fill:#fff9c4,stroke:#f9a825
style ACME fill:#e1f5fe,stroke:#0288d1
style TLM fill:#e1f5fe,stroke:#0288d1
style CA fill:#e1f5fe,stroke:#0288d1
style Browser fill:#f3e5f5,stroke:#7b1fa2
通信ポート一覧
| 送信元 |
宛先 |
ポート/プロトコル |
用途 |
認証方式 |
| Ansible Controller |
Windows Server (IIS) |
SSH 22/tcp |
certreq制御、証明書転送、IIS設定 |
EC2キーペア (公開鍵認証) |
| Ansible Controller |
DigiCert ONE (ACME) |
HTTPS 443/tcp |
ACMEアカウント作成、オーダー、証明書取得 |
EAB (External Account Binding) |
| Ansible Controller |
AWS Route 53 API |
HTTPS 443/tcp |
DNS-01チャレンジTXTレコード作成/削除、Aレコード管理 |
AWS SSO (IAM Role) |
| DigiCert ONE |
Route 53 (DNS) |
DNS 53/udp |
DNS-01チャレンジ検証 (TXTレコード確認) |
なし (公開DNS問合せ) |
| クライアント |
Windows Server (IIS) |
HTTPS 443/tcp |
Webアクセス |
TLS (DigiCert OV証明書) |
セキュリティグループ (sg-08fff29a5369cc980):
SSH(22), HTTP(80), HTTPS(443), RDP(3389), WinRM(5985-5986) を許可。
秘密鍵はWindowsサーバーの証明書ストア (cert:\LocalMachine\REQUEST → cert:\LocalMachine\My) に保管され、ネットワークを通過しない。
2. 証明書発行フロー (Step 0 -- Step 3)
4つのステップを時系列で示すシーケンス図です。各ステップは独立したPlaybook/スクリプトとして実装されています。
sequenceDiagram
autonumber
participant Ops as 運用者
participant Ansible as Ansible Controller
(Ubuntu EC2)
participant Win as Windows Server
(IIS + certreq)
participant R53 as DNS
participant ACME as DigiCert ONE
(ACME Endpoint)
rect rgb(255, 243, 224)
Note over Ops,R53: Step 0: インフラ構築 (setup_windows_iis.sh)
Ops->>Ansible: bash step0_infra/setup_windows_iis.sh
Ansible->>Win: EC2 RunInstances (UserData: IIS + SSH)
Ansible->>R53: UPSERT A webserver.example.com
R53-->>Ansible: ChangeInfo (変更ID)
Note right of Win: 自己証明書HTTPS + OpenSSH 起動
end
rect rgb(200, 230, 201)
Note over Ops,Win: Step 1: CSR生成 (generate_csr.yml)
Ops->>Ansible: ansible-playbook step1
Ansible->>Win: SSH: win_copy (INFファイル配置)
Ansible->>Win: SSH: certreq -new
Note right of Win: 秘密鍵 → cert:\LocalMachine\REQUEST
CSR → C:\ssl\*.csr
Win-->>Ansible: fetch (CSRファイル取得)
Note left of Ansible: data/csr/*.csr に保存
end
rect rgb(187, 222, 251)
Note over Ops,ACME: Step 2: ACME証明書発行 (issue_certificate.yml)
Ops->>Ansible: ansible-playbook step2
Ansible->>Ansible: ACMEアカウント鍵生成
Ansible->>ACME: POST /newAccount (EAB認証)
ACME-->>Ansible: Account URL
Ansible->>ACME: POST /newOrder (CSR送信)
ACME-->>Ansible: Authorization + Challenge
Ansible->>R53: route53: TXT _acme-challenge.
webserver.example.com
R53-->>Ansible: レコード作成完了
Note over Ansible: DNS伝播待機 (30秒)
Ansible->>ACME: POST challenge (検証要求)
ACME->>R53: DNS問合せ (TXTレコード確認)
R53-->>ACME: TXTレコード値
ACME-->>Ansible: Authorization: valid
Ansible->>ACME: POST /finalize (CSR確定)
ACME-->>Ansible: 証明書 (PEM)
Ansible->>R53: route53: TXT削除 (クリーンアップ)
Note left of Ansible: data/certs/*.pem + 台帳CSV + current.json
end
rect rgb(243, 229, 245)
Note over Ops,Win: Step 3: IISデプロイ (deploy_certificate.yml)
Ops->>Ansible: ansible-playbook step3
Ansible->>Win: SSH: エビデンス取得 (変更前)
Ansible->>Win: win_copy (証明書PEM転送)
Ansible->>Win: SSH: certreq -accept
Note right of Win: REQUEST鍵と照合 → cert:\LocalMachine\My
Ansible->>Win: SSH: IIS HTTPSバインディング更新
Ansible->>Win: SSH: Restart-Service W3SVC
Win-->>Ansible: エビデンス取得 (変更後)
Note left of Ansible: evidence/ に before/after 保存
end
ステップ別サマリ -- Windows (IIS)
| ステップ |
実行コマンド |
主要モジュール |
成果物 |
| Step 0 |
bash windows/step0_infra/setup_windows_iis.sh |
Terraform, aws route53 |
EC2 (Windows), Aレコード |
| Step 1 |
ansible-playbook windows/step1_csr_gen/generate_csr.yml |
win_shell (certreq -new), fetch |
秘密鍵 (ストア内), CSR |
| Step 2 |
AWS_PROFILE=AWSPowerUserAccess-123456789012 ansible-playbook windows/step2_issue_cert/issue_certificate.yml |
acme_account, acme_certificate, route53 |
証明書PEM, チェーン, 台帳CSV |
| Step 3 |
ansible-playbook windows/step3_deploy_cert/deploy_certificate.yml |
win_shell (certreq -accept), win_service |
IIS HTTPSバインディング, エビデンス |
ステップ別サマリ -- Linux (Apache)
| ステップ |
実行コマンド |
主要モジュール |
成果物 |
| Step 0 |
bash linux/step0_infra/setup_linux_apache.sh |
Terraform, aws route53 |
EC2 (Ubuntu), Aレコード |
| Step 1 |
ansible-playbook linux/step1_csr_gen/generate_csr.yml |
openssl_privatekey, openssl_csr, fetch |
秘密鍵 (/opt/ssl/), CSR |
| Step 2 |
AWS_PROFILE=AWSPowerUserAccess-123456789012 ansible-playbook linux/step2_issue_cert/issue_certificate.yml |
acme_account, acme_certificate, route53 |
証明書PEM, チェーン, 台帳CSV |
| Step 3 |
ansible-playbook linux/step3_deploy_cert/deploy_certificate.yml |
copy, Apache VirtualHost, service |
Apache SSL設定, エビデンス |
3. データフロー図 -- 秘密鍵・CSR・証明書の流れ
秘密鍵がネットワークを通過しないことを示すデータフロー図です。
graph LR
subgraph WinServer["Windows Server (webserver)"]
PrivKey["秘密鍵
cert:\LocalMachine\REQUEST"]
CSR_Win["CSR ファイル
C:\ssl\*.csr"]
CertPEM["証明書PEM
C:\ssl\*.pem"]
CertStore["証明書ストア
cert:\LocalMachine\My"]
IISBind["IIS HTTPS
バインディング"]
PrivKey -->|"certreq -new
(秘密鍵はストア内に留まる)"| CSR_Win
CertPEM -->|"certreq -accept
秘密鍵と照合"| CertStore
CertStore -->|"Thumbprint参照"| IISBind
end
subgraph Controller["Ansible Controller"]
CSR_Local["CSR コピー
data/csr/*.csr"]
Cert_Local["証明書 PEM
data/certs/*.pem"]
Ledger["台帳CSV
certificate_ledger.csv"]
Meta["メタデータ
current.json"]
Evidence["エビデンス
evidence/before & after"]
end
subgraph External["外部サービス"]
ACME_Svc["DigiCert ACME"]
R53_Svc["Route 53"]
end
CSR_Win -->|"fetch (SSH)
公開情報のみ"| CSR_Local
CSR_Local -->|"ACME オーダー
(HTTPS)"| ACME_Svc
ACME_Svc -->|"証明書発行
(HTTPS)"| Cert_Local
Cert_Local -->|"win_copy (SSH)
公開情報のみ"| CertPEM
Cert_Local --> Ledger
Cert_Local --> Meta
Controller -.->|"SSH"| Evidence
CSR_Local -.->|"DNS-01 チャレンジ"| R53_Svc
R53_Svc -.->|"TXT検証"| ACME_Svc
style PrivKey fill:#ffcdd2,stroke:#c62828,stroke-width:2px
style CSR_Win fill:#fff9c4,stroke:#f9a825
style CSR_Local fill:#fff9c4,stroke:#f9a825
style CertPEM fill:#c8e6c9,stroke:#388e3c
style CertStore fill:#c8e6c9,stroke:#388e3c
style Cert_Local fill:#c8e6c9,stroke:#388e3c
style IISBind fill:#bbdefb,stroke:#1976d2
style Ledger fill:#e1bee7,stroke:#7b1fa2
style Meta fill:#e1bee7,stroke:#7b1fa2
style Evidence fill:#e1bee7,stroke:#7b1fa2
style ACME_Svc fill:#e1f5fe,stroke:#0288d1
style R53_Svc fill:#fff9c4,stroke:#f9a825
🔍 クリックで拡大表示
秘密鍵の保護:
赤色で示した秘密鍵は、Windows証明書ストア (cert:\LocalMachine\REQUEST) 内で生成・保管され、
ネットワークを一度も通過しません。Ansible経由で転送されるのは CSR と証明書(いずれも公開情報)のみです。
certreq -accept 実行時に、REQUEST ストア内の秘密鍵と受信した証明書を照合し、
cert:\LocalMachine\My に秘密鍵付き証明書として配置します。