タイトル: 常時SSL化
SEOタイトル: 常時 SSL 化(HTTPS 強制リダイレクト)の実装方法と HSTS / Mixed Content 対策
| この記事の要点 |
|
常時 SSL 化とは
サイトの全ページ・全リソースを HTTPS(TLS)で配信し、HTTP アクセスを HTTPS に強制リダイレクトする運用方式です。「Always-on SSL」「HTTPS Everywhere」とも呼ばれます。
導入メリット:
- 通信の盗聴 / 改ざん防止(中間者攻撃対策)
- SEO 評価: Google が HTTPS をランキング要因として明言(2014 年〜)
- Chrome / Firefox の「保護されていない通信」警告を回避
- HTTP/2 / HTTP/3 はブラウザ実装上 HTTPS 必須 → 体感速度向上
- Service Worker / Geolocation / Camera API など最新 Web API は HTTPS 必須
Apache: .htaccess での HTTPS リダイレクト
# .htaccess(最も一般的)
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# X-Forwarded-Proto を見るパターン(ロードバランサ / CDN 配下)
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# www へ統一して HTTPS
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
VirtualHost で書く場合
# /etc/httpd/conf.d/example.com.conf
<VirtualHost *:80>
ServerName example.com
Redirect permanent / https://example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www/html
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
# HSTS: 1 年間 HTTPS 強制 (max-age 秒)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</VirtualHost>
Nginx: HTTPS リダイレクト
# /etc/nginx/conf.d/example.com.conf
# 80 番: 全部 HTTPS に飛ばす
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
# 443 番: 本体
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
root /var/www/html;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# 推奨設定(Mozilla SSL Config 生成)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:...;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
}
HSTS (Strict-Transport-Security)
HSTS ヘッダを送ると、ブラウザは指定期間中そのドメインを必ず HTTPS で接続するようになります。HTTP リダイレクトすら省略され、中間者攻撃に対する耐性が向上します。
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
max-age=31536000 最大有効期間 (秒): 1 年
includeSubDomains サブドメインにも適用
preload Chrome HSTS Preload List へ登録申請可能
→ 初回アクセスから HTTPS 強制
注意: HSTS は取り消しが難しいです。max-age を一度長く設定すると、ブラウザがキャッシュしている間 HTTPS でしか接続できなくなります。導入時はまず短期間 (例: max-age=300) で動作確認してから延長してください。
Mixed Content(混在コンテンツ)対策
HTTPS ページから <img src="http://..."> のように HTTP リソースを読み込むとMixed Content 警告が出ます。多くは画像 / CSS / JS で発生:
<!-- ❌ 混在コンテンツ -->
<img src="http://example.com/logo.png">
<script src="http://cdn.example.com/lib.js"></script>
<!-- ✅ プロトコル相対 (今は非推奨、後述) -->
<img src="//example.com/logo.png">
<!-- ✅ HTTPS に統一 -->
<img src="https://example.com/logo.png">
<!-- ✅ 同一サイトなら絶対パス(ルート相対) -->
<img src="/images/logo.png">
大量の HTTP URL を一括で書き換える Meta タグ:
<!-- すべての http:// リクエストを https:// に強制アップグレード -->
<meta http-equiv="Content-Security-Policy"
content="upgrade-insecure-requests">
<!-- HTTP リソースをブロック(より厳格) -->
<meta http-equiv="Content-Security-Policy"
content="block-all-mixed-content">
Let's Encrypt + Certbot(無料 SSL)
# Ubuntu / Debian
sudo apt install certbot python3-certbot-apache # Apache
sudo apt install certbot python3-certbot-nginx # Nginx
# 証明書取得 + 設定自動書き換え
sudo certbot --apache -d example.com -d www.example.com
sudo certbot --nginx -d example.com -d www.example.com
# 自動更新(cron / systemd timer)
sudo certbot renew --dry-run
sudo systemctl list-timers | grep certbot
# 90 日の証明書を 60 日でリニューする運用が標準
Laravel / 各種フレームワーク
// Laravel: AppServiceProvider::boot()
public function boot(): void
{
if ($this->app->environment('production')) {
URL::forceScheme('https');
}
}
// または .env
// APP_URL=https://example.com
// CDN / ロードバランサ配下の場合は TrustProxies で
// app/Http/Middleware/TrustProxies.php
protected $proxies = '*';
protected $headers = Request::HEADER_X_FORWARDED_FOR
| Request::HEADER_X_FORWARDED_HOST
| Request::HEADER_X_FORWARDED_PORT
| Request::HEADER_X_FORWARDED_PROTO;
常時 SSL 化のチェックリスト
- SSL 証明書取得・設定(Let's Encrypt 推奨)
- HTTP → HTTPS の 301 リダイレクト設定
- サイト内の HTTP リソース URL を全て HTTPS に書き換え(画像、CSS、JS、iframe、リンク)
upgrade-insecure-requestsCSP で残った HTTP リクエストをアップグレード- HSTS ヘッダを短期間で動作確認 → 1 年に延長
- Google Search Console に HTTPS 版サイトを登録 / sitemap.xml 提出
- サードパーティタグ(Google Analytics 等)が HTTPS 対応か確認
- SSL Labs テスト で A 以上を確認:
https://www.ssllabs.com/ssltest/ - Lighthouse で「HTTPS」「Mixed Content」項目を確認
FAQ
Q: 301 と 302 のどちらでリダイレクトすべき?
A: 301 (Permanent)。検索エンジンは 301 をシグナルとして HTTPS 版をインデックスし、HTTP 版の評価を引き継ぎます。302 だと「一時的」とみなされ評価が分散します。
Q: 旧 HTTP ページのリンク評価は消える?
A: 301 リダイレクトを設定すれば、約 90% 以上の SEO 評価が新 URL に引き継がれます(Google 公式)。サイト全体の URL 変更で 1〜2 週間ランキングが変動するのは正常です。
Q: 自己署名証明書ではだめ?
A: ブラウザが警告を出すため、公開サイトでは不可。Let's Encrypt が無料・自動更新で実用上ほぼ最強です。