2026年5月20日

2026年5月20日

WordPressのホットリンクを防御する方法

はじめに

ホットリンク(直リン)は、他のサイトが自分のサーバー上の画像・動画ファイルを直接URLで参照することです。自分のサーバーの帯域幅が消費されるにもかかわらず、恩恵は他サイトが受けます。適切に防御することで帯域幅の無駄遣いと著作権侵害を防げます。

症状・原因

  • アクセス解析でトラフィックが多いのにページビューが少ない
  • サーバーの転送量が異常に多く、帯域幅制限に引っかかっている
  • 画像ファイルへの直接アクセスが大量に発生している
  • 自分のサイトの画像が他サイトに無断で使用されている

解決手順

ステップ1:ホットリンクの状況を確認する

# 画像ファイルへのアクセスをRefererと一緒に確認
grep -E "\.(jpg|jpeg|png|gif|webp|svg|mp4|pdf)" /var/log/apache2/access.log | \
    awk '{print $7, $11}' | \
    grep -v '"https://example.com\|"-"' | \
    sort | uniq -c | sort -rn | head -30

# ホットリンク元のドメインをリスト
grep -E "\.(jpg|png|gif|webp)" /var/log/nginx/access.log | \
    grep -oP '"https?://[^/"]+"' | \
    grep -v "example.com" | \
    sort | uniq -c | sort -rn | head -20

# 月間転送量を確認
# Apache: awstats や GoAccess で集計
goaccess /var/log/apache2/access.log --log-format=COMBINED -o /tmp/report.html

ステップ2:Apacheでホットリンクを防ぐ(.htaccess)

# WordPress ルートの .htaccess(# BEGIN WordPress の前に追記)
<IfModule mod_rewrite.c>
    RewriteEngine On

    # ① Referer が空または自分のドメインの場合は許可
    RewriteCond %{HTTP_REFERER} !^$
    RewriteCond %{HTTP_REFERER} !^https?://(www\.)?example\.com [NC]
    RewriteCond %{HTTP_REFERER} !^https?://(www\.)?google\. [NC]
    RewriteCond %{HTTP_REFERER} !^https?://(www\.)?bing\. [NC]

    # ② 画像・動画・PDFへのアクセスをブロック
    RewriteRule \.(jpg|jpeg|png|gif|webp|svg|mp4|pdf|ico)$ - [F,L]

    # ③ ブロック時に代替画像を表示する場合
    # RewriteRule \.(jpg|jpeg|png|gif|webp)$ /images/hotlink-forbidden.png [R=301,L]
</IfModule>
# .htaccess 編集後の確認
# 自分のサイトから画像にアクセス → 表示できること
curl -I -H "Referer: https://example.com/" https://example.com/wp-content/uploads/test.jpg
# HTTP/2 200 が返れば OK

# 別サイトからのアクセスをシミュレート → ブロックされること
curl -I -H "Referer: https://other-site.com/" https://example.com/wp-content/uploads/test.jpg
# HTTP/2 403 が返れば成功

ステップ3:Nginxでホットリンクを防ぐ

# /etc/nginx/sites-available/example.com
server {
    # ... 既存の設定 ...

    # 画像・動画ファイルへのホットリンクを防ぐ
    location ~* \.(jpg|jpeg|png|gif|webp|svg|mp4|pdf|ico)$ {
        # 許可する Referer を指定
        valid_referers none blocked server_names
                       ~\.example\.com
                       ~\.google\.
                       ~\.bing\.;

        # 無効な Referer からのアクセスを拒否
        if ($invalid_referer) {
            return 403;
            # 代替画像にリダイレクトする場合:
            # return 301 https://example.com/images/hotlink-forbidden.png;
        }

        # キャッシュ設定
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
}
# Nginx 設定テストと反映
sudo nginx -t && sudo systemctl reload nginx

ステップ4:WordPress から動的に制御する

// functions.php: 画像の直接アクセスを制御

// ① 特定の画像タイプへの直接アクセスをブロック
add_action('init', function(): void {
    // 画像ファイルへの直接アクセス時に Referer を確認
    $request_uri = $_SERVER['REQUEST_URI'] ?? '';
    if (!preg_match('/\.(jpg|jpeg|png|gif|webp)$/i', $request_uri)) {
        return;
    }

    $referer = $_SERVER['HTTP_REFERER'] ?? '';
    $site_url = parse_url(get_site_url(), PHP_URL_HOST);

    // Referer がない場合または自サイト以外の場合
    if (!empty($referer)) {
        $referer_host = parse_url($referer, PHP_URL_HOST);
        $allowed_domains = [$site_url, 'www.' . $site_url, 'google.com', 'bing.com'];

        $is_allowed = false;
        foreach ($allowed_domains as $domain) {
            if (str_ends_with($referer_host ?? '', $domain)) {
                $is_allowed = true;
                break;
            }
        }

        if (!$is_allowed) {
            status_header(403);
            exit;
        }
    }
});

// ② 画像URLに署名付きトークンを追加(より高度な保護)
add_filter('wp_get_attachment_url', function(string $url): string {
    // 公開ページでは通常のURL、管理画面では署名なし
    if (is_admin() || wp_doing_ajax()) {
        return $url;
    }
    return $url;  // 署名ロジックはここに追加
});

ステップ5:Cloudflare でホットリンクを防ぐ

# Cloudflare ダッシュボード: Scrape Shield
# → Hotlink Protection を ON にするだけで完了

# 確認: Cloudflare の Hotlink Protection が有効な場合
# 他サイトの <img src="https://example.com/image.jpg"> は
# Cloudflare が自動的にブロック

# 許可するサイトを追加する場合は
# Cloudflare WAF → Custom Rules で Referer を条件に許可ルールを追加

# WP-CLI で Cloudflare 設定を確認(CF プラグイン使用時)
wp cf cache purge --type=everything

注意事項

  • RewriteCond %{HTTP_REFERER} !^$を含めることで、Refererが送信されない直接アクセス(ブックマーク・RSS・検索エンジンの直接クロール)は許可されます。これを除外するとRSSリーダーや一部のソーシャルメディアプレビューが機能しなくなる場合があります
  • Googlebot・Bingbot等の検索エンジンクローラーはRefererを送信しないため、!^$条件があれば自動的に許可されます
  • SNSシェア時のOGP画像プレビューはFacebook・Twitter等のクローラーがRefererなしでアクセスするため、ホットリンク防止後も正常に機能します

まとめ

ホットリンク防止は①アクセスログでgrep -E "\.(jpg|png)"で外部Refererを確認、②Apacheは.htaccessRewriteCond %{HTTP_REFERER}RewriteRuleを追記、③Nginxはvalid_referersディレクティブと$invalid_referer条件でreturn 403、④Cloudflareは「Scrape Shield → Hotlink Protection」をONにするだけ、⑤curl -H "Referer: https://other.com/"で403が返ることを確認します。

お気軽にご相談ください

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