タイトル: SSL化
SEOタイトル: サイト SSL/TLS 化 (HTTPS) 完全ガイド(Let's Encrypt / ACM / Cloudflare / HSTS)
この本文には実行可能なタグ等が含まれるため、安全のためHTMLソースとして表示しています。本文データは変更していません。
<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;background:#fffbea;border:1px solid #f4c430;margin:1em 0;width:100%"><tr><td style="background:#f4c430;color:#000;font-weight:bold;padding:8px">この記事の要点</td></tr><tr><td style="padding:10px"><ul><li><strong>Let's Encrypt</strong> の無料証明書 + <strong>Certbot</strong> が個人サイトの定番(90 日有効、cron で自動更新)</li><li>AWS なら <strong>ACM (AWS Certificate Manager)</strong> が無料 + 自動更新(ALB / CloudFront 用)</li><li><strong>Cloudflare</strong> をプロキシ前段に置けば<strong>SSL 終端を Cloudflare 側</strong>で無料化</li><li><strong>Mixed Content</strong> 警告: HTTPS ページ内に http リソースがあるとブロック → <code>//</code> or <code>https://</code> で参照</li><li><strong>HSTS</strong> ヘッダ: <code>Strict-Transport-Security: max-age=31536000; includeSubDomains; preload</code></li><li><strong>SEO 効果</strong>: Google は HTTPS をランキング要因に明言(2014 ~)</li></ul></td></tr></table>
<h2>なぜ SSL/TLS 化(HTTPS 化)が必要か</h2>
<ul>
<li><strong>通信内容の盗聴防止</strong>: パスワード / クレジットカード / Cookie の保護</li>
<li><strong>改ざん検知</strong>: 中間者攻撃で広告挿入 / 偽ページ表示を防止</li>
<li><strong>SEO ランキング要因</strong>: Google は HTTPS をプラスシグナルと公言</li>
<li><strong>ブラウザ警告回避</strong>: Chrome / Firefox は HTTP サイトに「保護されていない通信」表示</li>
<li><strong>HTTP/2 / HTTP/3 利用条件</strong>: 主要ブラウザは HTTPS のみで HTTP/2 を有効化</li>
<li><strong>新ブラウザ API の動作条件</strong>: Service Worker / WebRTC / Geolocation 等は HTTPS 必須</li>
</ul>
<h2>証明書の選択肢</h2>
<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>種類</th><th>料金</th><th>用途</th><th>備考</th></tr></thead>
<tbody>
<tr><td><a href="https://letsencrypt.org/" target="_blank" rel="noopener">Let's Encrypt</a> (DV)</td><td>無料</td><td>個人 / 中小サイト</td><td>90 日有効、自動更新前提</td></tr>
<tr><td><a href="https://aws.amazon.com/jp/certificate-manager/" target="_blank" rel="noopener">AWS Certificate Manager</a></td><td>無料</td><td>ALB / CloudFront / API Gateway</td><td>EC2 直接利用は不可</td></tr>
<tr><td>Cloudflare</td><td>無料</td><td>Cloudflare 経由のサイト全般</td><td>Cloudflare がプロキシ</td></tr>
<tr><td>Google Trust Services</td><td>無料</td><td>GCP Load Balancer</td><td>Google Managed Certificate</td></tr>
<tr><td>有料 DV 証明書(Sectigo / GeoTrust 等)</td><td>年 ¥1,000~</td><td>企業 / 補償付き</td><td>1〜2 年有効、サポート付</td></tr>
<tr><td>OV 証明書</td><td>年 ¥3 万〜</td><td>組織実在証明</td><td>会社情報を証明書に</td></tr>
<tr><td>EV 証明書</td><td>年 ¥10 万〜</td><td>銀行・大手 EC</td><td>かつての緑バー、現代は廃止</td></tr>
</tbody>
</table>
<h2>パターン1: Let's Encrypt + Certbot(Nginx / Apache)</h2>
<p>Linux サーバに直接 Web サーバを立てている場合の定番。</p>
<h3>Ubuntu + Nginx の例</h3>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-bash"># Certbot インストール
sudo apt update
sudo apt install -y certbot python3-certbot-nginx
# 証明書取得 + Nginx 設定自動反映
sudo certbot --nginx -d example.com -d www.example.com
# 対話形式で:
# - メールアドレス入力
# - 利用規約同意
# - HTTP → HTTPS リダイレクト (推奨: 2)
# 自動更新の動作確認(dry-run)
sudo certbot renew --dry-run
# 自動更新は systemd timer / cron で既に設定されている
sudo systemctl status certbot.timer</code></pre>
<h3>Apache の例</h3>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-bash">sudo apt install -y certbot python3-certbot-apache
sudo certbot --apache -d example.com
# 確認
curl -I https://example.com
# HTTP/2 200
# strict-transport-security: max-age=15552000</code></pre>
<h2>パターン2: AWS ACM + ALB / CloudFront</h2>
<p>AWS で運用している場合、ACM 発行証明書を ALB(Application Load Balancer)や CloudFront にアタッチ。</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-bash"># AWS CLI でリクエスト
aws acm request-certificate \
--domain-name example.com \
--subject-alternative-names www.example.com \
--validation-method DNS \
--region us-east-1
# ※ CloudFront 用は必ず us-east-1(バージニア北部)
# DNS 検証用 CNAME を Route 53 に追加
# → ACM コンソールから「Route 53 で作成」ボタン一発
# → 数分で「発行済み」に</code></pre>
<p>ALB / CloudFront の HTTPS Listener にこの証明書を設定 → 自動更新(人手不要)。<strong>ACM は EC2 に直接アタッチできない</strong>点に注意。EC2 で直接 SSL 終端するなら Let's Encrypt か有料証明書。</p>
<h2>パターン3: Cloudflare をプロキシ</h2>
<ol>
<li>Cloudflare に無料アカウント作成</li>
<li>ドメインを追加(DNS 移管)</li>
<li>各 DNS レコードを<strong>オレンジ雲(プロキシ ON)</strong>に</li>
<li>SSL/TLS 設定で「<strong>Full (strict)</strong>」を選択</li>
<li>「Edge Certificates」で Cloudflare 発行証明書が自動有効化</li>
</ol>
<p>これだけで <code>https://example.com</code> が即利用可能。<strong>オリジンサーバ側も自己署名証明書 or Cloudflare Origin CA を入れて HTTPS 化</strong>するのが推奨(Full strict)。</p>
<h2>Mixed Content の解消</h2>
<p>HTTPS ページ内で <code>http://</code> の画像 / CSS / JS を読み込むと、<strong>ブラウザがブロック</strong>します:</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-html"><!-- ❌ NG: HTTPS ページから http のリソース -->
<img src="http://example.com/logo.png">
<script src="http://cdn.example.com/lib.js"></script>
<!-- ✅ OK: すべて https に -->
<img src="https://example.com/logo.png">
<script src="https://cdn.example.com/lib.js"></script>
<!-- ✅ OK: スキーマ相対 (現代では https 推奨) -->
<img src="//example.com/logo.png">
<!-- ✅ OK: 相対パス -->
<img src="/images/logo.png"></code></pre>
<h3>一括変換: Content-Security-Policy</h3>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-text"># レスポンスヘッダで http → https に自動アップグレード
Content-Security-Policy: upgrade-insecure-requests
# Nginx
add_header Content-Security-Policy "upgrade-insecure-requests";
# Apache
Header set Content-Security-Policy "upgrade-insecure-requests"</code></pre>
<h2>HSTS (HTTP Strict Transport Security)</h2>
<p>「<strong>このサイトには今後 HTTPS だけで来てください</strong>」とブラウザに通知するヘッダ。一度設定すると、URL に <code>http://</code> と打っても自動 HTTPS 化。</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-text"># Nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# Apache
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# パラメータ
# max-age=31536000 ← 1 年間 HTTPS 強制
# includeSubDomains ← サブドメインにも適用
# preload ← Chrome 等の HSTS Preload List に登録申請可</code></pre>
<p><strong>注意</strong>: preload 設定後は<strong>HTTPS 化を取り消せなくなる</strong>(最大 1 年)。テストで <code>max-age=300</code> 等から始めて段階的に伸ばす。</p>
<h2>TLS バージョンと Cipher Suite</h2>
<p>古い TLS 1.0 / 1.1 は<strong>2020 年に主要ブラウザで廃止</strong>。現代は <strong>TLS 1.2 + TLS 1.3</strong> のみ有効化:</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-nginx"># Nginx の推奨設定(Mozilla Modern + 互換性)
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# TLS 1.2 / 1.3 のみ
ssl_protocols TLSv1.2 TLSv1.3;
# Cipher Suite(Mozilla Intermediate 推奨)
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# セッション再利用
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
# HSTS
add_header Strict-Transport-Security "max-age=63072000" always;
}</code></pre>
<p>設定生成は <a href="https://ssl-config.mozilla.org/" target="_blank" rel="noopener">Mozilla SSL Configuration Generator</a> が便利。</p>
<h2>動作確認・診断ツール</h2>
<ul>
<li><a href="https://www.ssllabs.com/ssltest/" target="_blank" rel="noopener">SSL Labs Server Test</a> — A+ を目標に</li>
<li><a href="https://securityheaders.com/" target="_blank" rel="noopener">Security Headers</a> — HSTS / CSP 等のヘッダ点検</li>
<li><strong>Lighthouse</strong>(Chrome DevTools)— HTTPS / Mixed Content 警告</li>
<li><code>curl -I https://example.com</code> — ヘッダ確認</li>
<li><code>openssl s_client -connect example.com:443 -servername example.com</code> — 証明書詳細</li>
</ul>
<h2>HTTP から HTTPS への 301 リダイレクト</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-nginx"># Nginx
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}</code></pre><pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-apache"># Apache .htaccess
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]</code></pre>
<h2>自動更新(Let's Encrypt)</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-bash"># Certbot は systemd timer で自動更新が既定有効
sudo systemctl list-timers | grep certbot
# certbot.timer Mon 2026-06-23 03:00:00 UTC
# cron に手動登録する場合
sudo crontab -e
# 毎日 3:30 に更新試行(期限 30 日切ったら更新)
30 3 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx"
# 動作確認
sudo certbot renew --dry-run</code></pre>
<h2>SEO 効果</h2>
<ul>
<li>Google 検索順位の<strong>軽いプラス要因</strong>(2014 から公式)</li>
<li>同点同士の場合 HTTPS 側が優位</li>
<li>Search Console は HTTP と HTTPS を別サイト扱い → <strong>HTTPS 版を登録</strong></li>
<li><strong>サイトマップ URL も HTTPS</strong> に更新</li>
<li>外部リンクの参照元情報(Referrer)が HTTP→HTTPS で送信されない問題 → <code>Referrer-Policy: strict-origin-when-cross-origin</code></li>
</ul>
<h2>FAQ</h2>
<p><strong>Q: Let's Encrypt の信頼性は?</strong><br />
A: <strong>主要ブラウザ・OS 全てで信頼</strong>されています。証明書の<strong>暗号化強度自体は有料証明書と同じ</strong>。違いは保証金・サポート・組織認証のみ。</p>
<p><strong>Q: ワイルドカード証明書は無料で取れる?</strong><br />
A: Let's Encrypt で取得可能(<code>certbot --manual --preferred-challenges dns -d *.example.com</code>)。DNS 認証必須。</p>
<p><strong>Q: 共有レンタルサーバで SSL 化したい</strong><br />
A: さくら / エックスサーバー / ロリポップ等は<strong>無料 SSL(Let's Encrypt ベース)</strong>を管理画面から 1 クリックで有効化できます。</p>
<p><strong>Q: 証明書が期限切れになった</strong><br />
A: ブラウザに「危険サイト」警告が出ます。即更新(<code>sudo certbot renew --force-renewal</code>)。再発予防に<strong>監視(Datadog / UptimeRobot で証明書期限監視)</strong>を入れる。</p>