この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:5
ページ更新者:T
更新日時:2026-06-11 07:12:00

タイトル: 常時SSL化
SEOタイトル: 常時 SSL 化(HTTPS リダイレクト)の完全ガイド(Apache / Nginx / Laravel /

この記事の要点
  • 常時 SSL 化 = 全ての HTTP アクセスを HTTPS にリダイレクトする運用。SEO(Google が HTTPS を優遇)と機密性のため必須
  • Apache: .htaccessRewriteCond %{HTTPS} off + RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
  • Nginx: return 301 https://$host$request_uri; を 80 番ポートのサーバブロックに
  • Laravel: URL::forceScheme("https")AppServiceProvider::boot() に追加。config/session.phpsecure も true
  • HSTS ヘッダー Strict-Transport-Security: max-age=31536000; includeSubDomains でブラウザに HTTPS 強制を覚えさせる。SSL 証明書は Let's Encrypt (Certbot) で無料取得可能

常時 SSL 化(HTTPS リダイレクト)とは

ウェブサイト全体の通信を HTTPS にし、HTTP でアクセスされても自動的に HTTPS に転送する設定。SEO・セキュリティ・PWA / Service Worker の利用条件として必須です。Google Chrome は HTTP サイトに「保護されていない通信」と警告を出します。

Apache (.htaccess)

# .htaccess の先頭に
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# ロードバランサ(ALB / CloudFront)配下の場合は X-Forwarded-Proto を見る
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# HSTS ヘッダー(HTTPS で配信する設定にも追加)
<IfModule mod_headers.c>
  Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</IfModule>

Apache (httpd.conf / VirtualHost)

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.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

    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</VirtualHost>

Nginx

# /etc/nginx/sites-available/example.com
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    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;

    # 推奨設定
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
    ssl_prefer_server_ciphers off;

    # HSTS
    add_header Strict-Transport-Security &quot;max-age=31536000; includeSubDomains&quot; always;

    root /var/www/html;
    index index.php index.html;

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        include fastcgi_params;
    }
}

Laravel での常時 SSL 化

<?php
// app/Providers/AppServiceProvider.php
namespace App\Providers;

use Illuminate\Support\Facades\URL;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        // 本番のみ HTTPS 強制
        if (config('app.env') === 'production') {
            URL::forceScheme('https');
        }
    }
}

セッション Cookie と CSRF Cookie も HTTPS のみに:

<?php
// config/session.php
return [
    // ...
    'secure' => env('SESSION_SECURE_COOKIE', true),  // HTTPS のみ送信
    'http_only' => true,
    'same_site' => 'lax',
];

// .env
APP_ENV=production
APP_URL=https://example.com
SESSION_SECURE_COOKIE=true

// ロードバランサ配下なら TrustProxies ミドルウェアも
// app/Http/Middleware/TrustProxies.php
protected $proxies = '*';  // ALB / CloudFront 信頼
protected $headers =
    Request::HEADER_X_FORWARDED_FOR |
    Request::HEADER_X_FORWARDED_HOST |
    Request::HEADER_X_FORWARDED_PORT |
    Request::HEADER_X_FORWARDED_PROTO;

Let's Encrypt で無料 SSL 証明書取得

# Ubuntu / Debian
sudo apt install certbot python3-certbot-nginx
# または Apache
sudo apt install certbot python3-certbot-apache

# Nginx 用に取得 + 自動設定
sudo certbot --nginx -d example.com -d www.example.com

# Apache 用
sudo certbot --apache -d example.com

# 証明書のみ取得(手動設定する場合)
sudo certbot certonly --standalone -d example.com

# 自動更新の確認(cron に登録済)
sudo certbot renew --dry-run
sudo systemctl list-timers | grep certbot

HSTS(HTTP Strict Transport Security)

ブラウザに「このドメインは絶対 HTTPS で来い」と覚えさせるヘッダー。一度送ると、以降ブラウザは HTTP リクエスト自体を発行しません:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

# max-age: 31536000 = 1年(秒)
# includeSubDomains: サブドメインも含む
# preload: Chrome の HSTS Preload List に登録申請可能
#   https://hstspreload.org/

注意: HSTS を有効にすると、その期間中 HTTP に戻せません。証明書切れで全アクセス不能になる事故が起きるので、最初は max-age=300(5分)で試して、問題なければ伸ばします。

混在コンテンツ (Mixed Content) の解消

HTTPS ページの中で http:// のリソース(img / script / iframe)を読むと、ブラウザがブロックします:

<!-- NG -->
<img src="http://example.com/img.jpg">
<script src="http://cdn.example.com/lib.js"></script>

<!-- OK: プロトコル相対 or 明示的 https -->
<img src="//example.com/img.jpg">
<script src="https://cdn.example.com/lib.js"></script>

<!-- 全部一括で https に書き換える(HTML / CSS を grep -->
<!-- src="http://  → src="https:// -->

古い記事や CMS で http リンクが残っている場合、DB レベルで一括置換:

-- WordPress 等の例
UPDATE wp_posts
SET post_content = REPLACE(post_content, 'http://example.com', 'https://example.com');

UPDATE wp_options
SET option_value = REPLACE(option_value, 'http://example.com', 'https://example.com');

確認ツール

  • SSL Labs (ssllabs.com/ssltest/) - 証明書 / 設定の評価。A+ が目標
  • Why No Padlock? (whynopadlock.com) - 混在コンテンツ検査
  • Chrome DevTools - Security タブで詳細表示
  • HSTS Preload List (hstspreload.org) - ブラウザ組み込みリスト

SEO 観点での注意

  • 必ず 301 リダイレクト(恒久)を使う(302 は SEO 評価が継承されない)
  • Google Search Console に https 版のプロパティを別途登録
  • サイトマップ / canonical / hreflang / OGP も全部 https に更新
  • http 版 → https 版へ被リンクを保つため、リダイレクトを永続的に維持

FAQ

Q: 自己署名証明書でも常時 SSL 化できる?
A: 技術的に可能ですがブラウザが警告を出します。Let's Encrypt で無料の正規証明書を取得してください。

Q: 内部ネットワーク (社内) も HTTPS にすべき?
A: するべき。社内 CA を立てて配布するか、Cloudflare Origin CA 等を利用。

Q: ロードバランサで TLS 終端し、内部は HTTP の場合
A: 一般的構成。アプリ側で X-Forwarded-Proto を見て https と判定するように設定(Laravel の TrustProxies など)。