2026年11月12日

2026年11月12日

Настройка Cloudflare для WordPress: DNS, SSL, реальный IP, WAF

Эта статья — локализованная версия японского оригинала. Читать японский оригинал

Подключение Cloudflare к WordPress выполняется в таком порядке: (1) добавьте сайт в Cloudflare и смените серверы имён домена; (2) переключите режим шифрования SSL/TLS на Full (strict); (3) восстановите на сервере реальный IP посетителя; (4) защитите страницу входа пользовательским правилом WAF. Даже на бесплатном тарифе доступны CDN, SSL, защита от DDoS и пользовательские правила (до 5 штук).

В статье разобраны все эти настройки и то, что нужно проверить после переключения. Названия и расположение элементов в интерфейсе Cloudflare со временем меняются, поэтому материал написан по официальной документации (developers.cloudflare.com) по состоянию на ноябрь 2026 года.

Что нужно решить до начала

  • Управление DNS перейдёт к Cloudflare. Регистратор домена не изменится, но DNS-записи вы будете редактировать в интерфейсе Cloudflare.
  • DNS-записи почты (MX и т. п.) не проксируются. Через Cloudflare идёт только веб-трафик (HTTP/HTTPS).
  • На origin-сервере (где расположен WordPress) должен быть действующий SSL-сертификат. Если HTTPS уже работает, например через Let's Encrypt, ничего менять не нужно.
  • Если у регистратора включён DNSSEC, отключите его до смены серверов имён. Оставшаяся старая DS-запись приведёт к сбоям разрешения имён.

Шаг 1: добавьте сайт и смените серверы имён

  1. Создайте учётную запись Cloudflare и добавьте домен в панели управления (Dashboard). Можно выбрать тариф Free.
  2. Cloudflare считывает текущие DNS-записи и выводит их списком; проверьте, ничего ли не потеряно. Некоторые записи считать не удаётся, поэтому сверьте список с текущей панелью управления DNS и недостающее добавьте вручную.
  3. Для записей A (или AAAA, CNAME) веб-сайта включите проксирование (оранжевое облако). Для MX и записей A почтового сервера отключите его (только DNS, серое облако).
  4. Cloudflare покажет два имени сервера имён вида 〇〇.ns.cloudflare.com, назначаемых каждой учётной записи отдельно. Используйте те два имени, что показаны на вашем экране, а не имена из других статей.
  5. В панели управления регистратора домена замените серверы имён на эти два.

Проверить, произошло ли переключение, можно следующими командами. Изменения могут применяться несколько часов.

# Указаны ли два сервера имён Cloudflare
dig NS example.com +short

# Идёт ли трафик через Cloudflare (возвращаются server: cloudflare и cf-ray)
curl -sI https://example.com | grep -iE '^(server|cf-ray):'

Когда в Cloudflare статус домена станет «Активен» (Active), переключение завершено.

Шаг 2: переключите SSL/TLS на Full (strict)

В настройках SSL/TLS Cloudflare есть режимы, определяющие, как шифруется соединение между посетителем и Cloudflare и между Cloudflare и origin-сервером.

Режим Между Cloudflare и origin-сервером Как относиться в WordPress
Off Без шифрования Не использовать
Flexible HTTP (без шифрования) Не использовать. Вызывает циклы перенаправлений и смешанное содержимое
Full HTTPS (сертификат не проверяется) Временный вариант, пока не готов сертификат
Full (strict) HTTPS (сертификат проверяется) Выбирайте его

Режим меняется на странице обзора SSL/TLS (Overview) в панели управления Cloudflare. Значение по умолчанию «Automatic SSL/TLS» автоматически выбирает безопасный режим в пределах возможностей origin-сервера. Если вы сами выберете Full (strict), сайт не окажется в непредусмотренном режиме. В качестве сертификата origin-сервера подойдёт сертификат публичного удостоверяющего центра (например, Let's Encrypt) или сертификат Origin CA, выпущенный Cloudflare.

Причина, по которой следует избегать Flexible, такая. В режиме Flexible запросы доходят до origin-сервера по HTTP, поэтому WordPress или сервер отвечают «пришло по HTTP — перенаправляем на HTTPS», а Cloudflare снова идёт на origin по HTTP, и так по кругу (браузер покажет ERR_TOO_MANY_REDIRECTS). В режиме Full (strict) запросы идут и до origin-сервера по HTTPS, поэтому дополнительный код на стороне WordPress, который смотрит на X-Forwarded-Proto и переписывает $_SERVER['HTTPS'], не нужен.

Заодно убедитесь, что в разделе «Настройки» (Settings) → «Общие» (General) значения «Адрес WordPress (URL)» и «Адрес сайта (URL)» начинаются с https://. Если изображения и другие файлы остались с http://, см. как исправить смешанное содержимое.

Шаг 3: восстановите реальный IP посетителя

При работе через Cloudflare источником соединения, доходящего до сервера (REMOTE_ADDR), становится IP-адрес Cloudflare. Из-за этого журнал доступа, IP в комментариях, плагины, ограничивающие попытки входа, и т. п. считают всех посетителей клиентами с IP Cloudflare. Cloudflare передаёт IP посетителя в заголовке CF-Connecting-IP, поэтому настройте сервер так, чтобы доверять этому заголовку только когда соединение пришло с Cloudflare.

Если подменять REMOTE_ADDR значением заголовка, не проверив источник, то любой, кто обратится к origin-серверу напрямую, минуя Cloudflare, сможет выдать себя в заголовке за произвольный IP. Поэтому не используйте код из старых статей, который просто присваивает REMOTE_ADDR значение HTTP_CF_CONNECTING_IP, если оно есть.

Список IP-адресов Cloudflare опубликован на странице https://www.cloudflare.com/ips/. Он может меняться, поэтому периодически пересматривайте его.

Для Nginx

Используйте ngx_http_realip_module. В блоке http или server перечислите все диапазоны Cloudflare.

# Диапазоны IP Cloudflare (на ноябрь 2026 г.; актуальные смотрите на cloudflare.com/ips)
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;

real_ip_header CF-Connecting-IP;
sudo nginx -t && sudo systemctl reload nginx

Для Apache (Debian / Ubuntu)

Используйте mod_remoteip. Создайте файл /etc/apache2/conf-available/remoteip.conf и перечислите диапазоны Cloudflare в RemoteIPTrustedProxy.

RemoteIPHeader CF-Connecting-IP
RemoteIPTrustedProxy 173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22
RemoteIPTrustedProxy 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20
RemoteIPTrustedProxy 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13
RemoteIPTrustedProxy 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22
RemoteIPTrustedProxy 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32
RemoteIPTrustedProxy 2405:8100::/32 2a06:98c0::/29 2c0f:f248::/32
sudo a2enmod remoteip
sudo a2enconf remoteip
sudo apache2ctl configtest
sudo systemctl restart apache2

Чтобы в журнале доступа выводился реальный IP, в LogFormat (combined) файла /etc/apache2/apache2.conf замените %h на %a.

Если настройки сервера менять нельзя (wp-config.php)

Если вы не можете менять настройки веб-сервера, например на арендованном хостинге, ту же проверку можно сделать в wp-config.php. Разместите код выше строки require_once ABSPATH . 'wp-settings.php';. Значение CF-Connecting-IP (оно должно быть корректным IP-адресом) используется только если соединение пришло из диапазона Cloudflare.

<?php
// Только при доступе через Cloudflare используем CF-Connecting-IP как IP посетителя
$cf_ranges = [
    '173.245.48.0/20', '103.21.244.0/22', '103.22.200.0/22', '103.31.4.0/22',
    '141.101.64.0/18', '108.162.192.0/18', '190.93.240.0/20', '188.114.96.0/20',
    '197.234.240.0/22', '198.41.128.0/17', '162.158.0.0/15', '104.16.0.0/13',
    '104.24.0.0/14', '172.64.0.0/13', '131.0.72.0/22',
    '2400:cb00::/32', '2606:4700::/32', '2803:f800::/32', '2405:b500::/32',
    '2405:8100::/32', '2a06:98c0::/29', '2c0f:f248::/32',
];

function cf_ip_in_range(string $ip, string $cidr): bool
{
    [$net, $bits] = explode('/', $cidr);
    $ip_bin  = inet_pton($ip);
    $net_bin = inet_pton($net);
    if ($ip_bin === false || $net_bin === false || strlen($ip_bin) !== strlen($net_bin)) {
        return false;
    }
    $bits  = (int) $bits;
    $bytes = intdiv($bits, 8);
    if ($bytes > 0 && substr($ip_bin, 0, $bytes) !== substr($net_bin, 0, $bytes)) {
        return false;
    }
    $rest = $bits % 8;
    if ($rest === 0) {
        return true;
    }
    $mask = (0xFF << (8 - $rest)) & 0xFF;
    return (ord($ip_bin[$bytes]) & $mask) === (ord($net_bin[$bytes]) & $mask);
}

if (!empty($_SERVER['HTTP_CF_CONNECTING_IP']) && !empty($_SERVER['REMOTE_ADDR'])) {
    foreach ($cf_ranges as $range) {
        if (cf_ip_in_range($_SERVER['REMOTE_ADDR'], $range)) {
            $visitor = filter_var($_SERVER['HTTP_CF_CONNECTING_IP'], FILTER_VALIDATE_IP);
            if ($visitor !== false) {
                $_SERVER['REMOTE_ADDR'] = $visitor;
            }
            break;
        }
    }
}

В wp-config.php тег <?php уже есть в начале, поэтому не копируйте <?php из первой строки, а вставьте код со второй строки. Перед вставкой сделайте резервную копию wp-config.php.

Шаг 4: защитите страницу входа пользовательским правилом WAF

На бесплатном тарифе в пользовательских правилах WAF Cloudflare можно создать до 5 правил, и для них доступны все действия, кроме Log (Block, Managed Challenge и др.). Создаются они на странице Security rules панели управления: нажмите «Create rule», выберите «Custom rules», задайте условие (Field, Operator, Value) и действие и нажмите «Deploy».

Пример 1: открыть страницу входа и админ-панель только с вашего IP

Пример для случая, когда у вас дома или в офисе есть статический IP. В виде выражения это выглядит так (203.0.113.10 и 198.51.100.0/24 замените своими IP).

(http.request.uri.path eq "/wp-login.php" or starts_with(http.request.uri.path, "/wp-admin/"))
and http.request.uri.path ne "/wp-admin/admin-ajax.php"
and not ip.src in {203.0.113.10 198.51.100.0/24}

В качестве действия выберите Block. /wp-admin/admin-ajax.php исключён из условия: его могут вызывать без входа в систему функции публичных страниц, например формы обратной связи и бесконечная прокрутка.

Пример 2: если статического IP нет, ограничьте по стране с Managed Challenge

(http.request.uri.path eq "/wp-login.php" or http.request.uri.path eq "/xmlrpc.php")
and not ip.src.country in {"JP"}

Для определения страны используется ip.src.country (двухбуквенный код ISO 3166-1). Устаревшее поле ip.geoip.country из старых статей применять не рекомендуется. В качестве действия сначала выберите Managed Challenge, посмотрите в событиях безопасности, не попадает ли под правило законный трафик, и только потом при необходимости переключите на Block. Документация Cloudflare тоже советует действовать так. xmlrpc.php используется, если вы публикуете записи через Jetpack или мобильное приложение, поэтому прежде чем включать его в условие, проверьте, нужен ли он вам.

Ограничение по странам — вспомогательная мера, которую обходят через VPN и подобные средства. Сочетайте её с двухфакторной аутентификацией и ограничением числа попыток входа. Как определять страну на стороне Nginx, описано в статье «Как ограничить доступ по странам через GeoIP2 в Nginx».

Шаг 5: как кеширует Cloudflare по умолчанию и очистка при публикации

По умолчанию Cloudflare не кеширует HTML. Кешируются статические файлы, определяемые по расширению: изображения, CSS, JavaScript, шрифты. Не кешируются и ответы с заголовком Set-Cookie. Поэтому, пока вы ничего не настраивали, админ-панель и страница входа Cloudflare не кеширует.

Если вы хотите кешировать и HTML, расширьте область действия через Cache Rules, но тогда нужно исключить из неё /wp-admin/, /wp-login.php, предпросмотр и страницы для вошедших в систему пользователей. Если исключить неправильно, страницы для администраторов могут показываться посторонним, так что при сомнениях лучше оставить значения по умолчанию.

Если вы заменили CSS или изображения, а на сайте ничего не изменилось, очистите кеш (purge) в настройках кеша панели управления. Если нужна автоматическая очистка при каждой публикации или обновлении записи, обращайтесь к API Cloudflare. Сначала создайте в Cloudflare API-токен только с правом «Cache Purge» и вместе с ID зоны (он показан на странице обзора домена) запишите его константами в wp-config.php.

define( 'CF_ZONE_ID', 'ID_зоны' );
define( 'CF_API_TOKEN', 'API_токен' );

Следующий код поместите в functions.php дочерней темы или в небольшой собственный плагин (подойдёт и Code Snippets).

<?php
// При публикации или обновлении записи удаляем из кеша Cloudflare эту запись и главную страницу
function cf_purge_urls(array $urls): bool
{
    if (!defined('CF_ZONE_ID') || !defined('CF_API_TOKEN')) {
        return false;
    }

    $response = wp_remote_post(
        'https://api.cloudflare.com/client/v4/zones/' . CF_ZONE_ID . '/purge_cache',
        [
            'headers' => [
                'Authorization' => 'Bearer ' . CF_API_TOKEN,
                'Content-Type'  => 'application/json',
            ],
            'body'    => wp_json_encode(['files' => array_values($urls)]),
            'timeout' => 15,
        ]
    );

    if (is_wp_error($response)) {
        error_log('Cloudflare purge failed: ' . $response->get_error_message());
        return false;
    }

    $result = json_decode(wp_remote_retrieve_body($response), true);
    return !empty($result['success']);
}

add_action('publish_post', function (int $post_id): void {
    if (wp_is_post_revision($post_id) || wp_is_post_autosave($post_id)) {
        return;
    }
    cf_purge_urls([get_permalink($post_id), home_url('/')]);
});

Хук publish_post срабатывает при публикации записи и при обновлении уже опубликованной записи. В purge_cache API помимо files, где указываются URL, есть и purge_everything, удаляющий всё, но полная очистка заставляет заново получать и статические файлы, поэтому при каждой публикации записи её не используют.

Что проверить после переключения

  • В выводе curl -sI есть server: cloudflare и cf-ray, а в браузере отображается значок замка
  • Вы можете войти в админ-панель, сохранить запись и загрузить медиафайл
  • В новых комментариях и журнале доступа записывается IP посетителя, а не IP Cloudflare
  • Письма из формы обратной связи доходят (запись MX не проксируется)
  • Если вы создали пользовательское правило WAF, откройте wp-login.php с подключения, которому доступ не разрешён (например, из мобильной сети смартфона) и убедитесь, что появляется блокировка или проверка

Частые проблемы

Появляется ERR_TOO_MANY_REDIRECTS

Проверьте, не выбран ли режим SSL/TLS Flexible. Установите сертификат на origin-сервер и переключите режим на Full (strict), и проблема исчезнет.

Не удаётся войти в админ-панель

Возможно, в условии пользовательского правила WAF не учтён ваш IP или ваша страна. Временно отключите правило в панели управления Cloudflare, выясните в событиях безопасности, какое правило сработало, и поправьте выражение.

Все запросы выглядят как приходящие с одного IP

Не выполнено восстановление реального IP из шага 3. В Nginx проверьте диапазоны set_real_ip_from и real_ip_header, в Apache — включён ли remoteip.

Итоги

  • Смените серверы имён на два, назначенных вашей учётной записи, а почтовые записи, такие как MX, не проксируйте
  • SSL/TLS — Full (strict). Flexible вызывает циклы перенаправлений и смешанное содержимое
  • Реальный IP восстанавливайте через CF-Connecting-IP, доверяя заголовку только когда соединение пришло из диапазона Cloudflare
  • Страницу входа ограничивайте по IP или стране правилом WAF, сначала выставив Managed Challenge и понаблюдав
  • HTML по умолчанию не кешируется. Очистку при публикации делайте через API-токен только с правом «Cache Purge»

Похожие статьи

Источники: Restoring original visitor IPs (Cloudflare), Encryption modes (Cloudflare), Custom rules (Cloudflare WAF), Default cache behavior (Cloudflare)

Есть вопросы по WordPress? Издатель сайта находится в Японии и отвечает по-японски. Связаться (по-японски)

お気軽にご相談ください

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