2026年10月1日

2026年10月1日

サブドメインをリダイレクトする方法|DNS・Webサーバー・CDN・WordPressでの設定と確認

サブドメイン(例:old.example.com)を別のURLへ転送するには、DNS でサブドメインをどこかの Web サーバー(または CDN)に向けたうえで、そのサーバー側で HTTP の 301 リダイレクトを返す、という2段階が必要です。DNS のレコードだけでは URL の転送はできません。この記事では、方法ごとの設定例と、HTTPS・パスの引き継ぎ・ループといったつまずきやすい点、そして curl での確認方法までを説明します。

まず押さえたい仕組み

ブラウザが old.example.com を開くとき、最初に DNS で IP アドレスを調べ、次にそのサーバーへ HTTP(S) で接続します。リダイレクトは、この2段目でサーバーが「Location: の先へ移動してください」と応答することで起こります。

よくある誤解が「CNAME レコードで転送できる」というものです。CNAME は名前の別名を定義するだけで、ブラウザのアドレスバーの URL は変わりません。old.example.com に CNAME で new.example.net を指定しても、相手のサーバーは old.example.com という名前でアクセスを受けるため、設定がなければエラーや別サイトの表示になります。

そのため手順は次の順番になります。

  1. サブドメインの DNS レコード(A / AAAA / CNAME)を、リダイレクトを返すサーバーに向ける
  2. そのサーバーで、サブドメイン用の HTTPS 証明書を用意する
  3. サーバー(または CDN)にリダイレクトの規則を書く
  4. curl とブラウザで動作を確かめる

DNS の変更は TTL の分だけ反映に時間がかかります。作業前に TTL を短くしておくと、間違えたときの戻しが早くなります。

リダイレクトの種類を選ぶ

  • 301(恒久的な移動):サブドメインを廃止して新しい URL に統合する場合の基本です。検索エンジンは転送先を正規の URL として扱うよう処理を進めます。
  • 302 / 307(一時的な移動):メンテナンス中だけ別ページに逃がす場合など、いずれ元に戻すときに使います。
  • 308:301 と同じ恒久的な移動ですが、POST などのリクエスト方式を変えずに転送します。フォーム送信先やAPIを移す場合に向いています。

301 はブラウザに強くキャッシュされるため、規則を間違えて公開すると、修正後も手元のブラウザでは古い転送が続くことがあります。最初は 302 で動作を確かめ、問題がなければ 301 に切り替えると安全です。

方法1:Nginx で転送する

サブドメイン専用の server ブロックを用意し、return で転送します。パスとクエリを引き継ぐには $request_uri を付けます。

server {
    listen 80;
    listen 443 ssl;
    http2 on;
    server_name old.example.com;

    ssl_certificate     /etc/letsencrypt/live/old.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/old.example.com/privkey.pem;

    # /blog/post?id=1 → https://www.example.com/blog/post?id=1
    return 301 https://www.example.com$request_uri;
}

http2 on; は Nginx 1.25.1 以降の書き方です。それより古いバージョンでは listen 443 ssl http2; と書きます(2026年10月現在)。トップページだけにまとめたい場合は $request_uri を外しますが、旧 URL のページがすべてトップに飛ぶと利用者にも検索エンジンにも分かりにくくなるため、対応するページがあるならパスを引き継ぐほうが無難です。

変更後は sudo nginx -t で構文を確かめてから sudo systemctl reload nginx で反映します。

方法2:Apache で転送する

VirtualHost を分けられるなら、Redirect ディレクティブが最も簡単です。

<VirtualHost *:443>
    ServerName old.example.com
    SSLEngine on
    SSLCertificateFile    /etc/letsencrypt/live/old.example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/old.example.com/privkey.pem

    # パスは自動で引き継がれる(/a/b → https://www.example.com/a/b)
    Redirect permanent / https://www.example.com/
</VirtualHost>

共用サーバーでサブドメインとメインドメインが同じドキュメントルートを共有している場合は、.htaccess でホスト名を条件にします。WordPress のリライト規則より前に置くのがポイントです。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^old\.example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
</IfModule>

# BEGIN WordPress
# (WordPress が書き込む規則はこの下に残す)

# BEGIN WordPress から # END WordPress の間は WordPress が書き換えることがあるため、独自の規則はその外側に書きます。編集前に .htaccess のバックアップを取ってください。

方法3:CDN やレジストラの転送機能を使う

サーバーを用意したくない場合は、CDN やレジストラの機能で転送できます。

  • Cloudflare:DNS をプロキシ有効(オレンジの雲)にしたうえで、リダイレクト用のルール機能で「ホスト名が old.example.com なら転送」と設定します。転送用のサブドメインには、プロキシを通すためのダミーのレコードが必要になる場合があります。機能名や設定画面は変わることがあるため、Cloudflare の公式ドキュメントで現在の手順を確認してください。
  • レジストラの URL 転送:国内の多くのレジストラが「URL転送」のような名前の機能を提供しています。手軽ですが、HTTPS に対応していない、パスを引き継げない、フレームで表示する方式しか選べない、といった制約があるサービスもあります。HTTPS での転送とステータスコードを確認してから使ってください。

方法4:WordPress 側で転送する

サブドメインがすでに WordPress の動いているサーバーを向いており、そこで処理したい場合は、プラグインや mu-plugin でも転送できます。WordPress.org で公開されている Redirection プラグインは URL 単位の転送に広く使われていますが、ホスト名を条件にした転送は設定方法がバージョンで異なるため、プラグインの説明を確認してください。

コードで書く場合は、子テーマではなく mu-plugin(wp-content/mu-plugins/ に置く PHP ファイル)にすると、テーマ変更の影響を受けません。

<?php
/*
 * Plugin Name: Subdomain Redirect
 */
add_action( 'template_redirect', function () {
    $host = isset( $_SERVER['HTTP_HOST'] ) ? strtolower( sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) ) : '';
    if ( 'old.example.com' !== $host ) {
        return;
    }
    $path = isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '/';
    // 転送先は固定のホストに限定し、入力値をホスト名に使わない
    wp_redirect( 'https://www.example.com' . esc_url_raw( $path ), 301 );
    exit;
} );

転送先のホストはコード内で固定し、リクエストの値をそのまま転送先のホスト名に使わないことが大切です(オープンリダイレクトの原因になります)。ただし WordPress まで処理が届く分、サーバー設定での転送より負荷も応答時間も増えます。マルチサイトのサブドメイン型では、サブドメインごとにサイトが割り当てられているため、この方法は使わずネットワーク設定側で整理してください。

動作を確認する

ブラウザはキャッシュの影響を受けるので、まず curl で応答を見ます。

# 1回目の応答(ステータスと Location)
curl -sI https://old.example.com/blog/post?id=1 | grep -iE '^(HTTP|location)'

# 最終的な行き先までたどる
curl -sIL -o /dev/null -w '%{http_code} %{url_effective}\n' http://old.example.com/

確認したいのは次の4点です。

  • http:// と https:// の両方で転送されるか
  • パスとクエリが意図どおり引き継がれるか
  • 転送が1回で終わるか(http → https → www → 本来の URL と何段も挟まると遅くなります)
  • 証明書のエラーが出ないか

curl で証明書エラーになる場合は、サブドメイン用の証明書が無い状態です。HTTPS のアクセスは、リダイレクト規則より前に TLS の接続で失敗するため、転送元のサブドメインにも有効な証明書が必要です。また、メインドメインで HSTS を includeSubDomains 付きで有効にしていると、ブラウザは http への接続を許さないので、なおさら証明書を用意しておく必要があります。

まとめ

  • DNS だけではリダイレクトできません。サブドメインをサーバーや CDN に向け、そこで 301 などを返します。
  • Nginx は return 301、Apache は Redirect permanent または .htaccess のホスト名条件で設定でき、パスの引き継ぎも指定できます。
  • CDN やレジストラの転送機能は手軽ですが、HTTPS 対応とパス引き継ぎの可否を確認してから使います。
  • WordPress 側で転送するなら mu-plugin で、転送先ホストを固定します。
  • 最初は 302 で試し、curl でステータス・行き先・転送回数・証明書を確かめてから 301 にします。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲