Cloudflare перед VPS
Cloudflare — это обратный прокси и CDN, который встаёт между посетителями и вашим VPS: запросы сначала попадают в сеть Cloudflare, и только она обращается к вашему серверу (origin). В этой статье вы добавите домен в Cloudflare, разберётесь с proxied- и DNS only-записями, включите режим SSL/TLS Full (strict) с настоящим сертификатом, настроите базовое кэширование, научитесь получать настоящий IP посетителя вместо IP Cloudflare и узнаете, что учитывать при выпуске сертификата certbot, когда домен уже проксируется. На выходе — два практических эффекта: статика отдаётся быстрее за счёт CDN, а реальный IP VPS скрыт от посетителей и большинства сканеров, что снимает часть базовых DDoS-атак ещё на edge Cloudflare.
Что понадобится
- Домен, зарегистрированный у любого регистратора, и доступ к его панели управления — там, где меняются NS-серверы.
- Работающий сайт на VPS mHost, уже доступный по HTTP(S) — например, настроенный по статьям «Nginx: установка и первый сайт» или «Apache: установка и виртуальные хосты». Если домен ещё не привязан к серверу напрямую — см. «Как привязать домен к серверу»; если нужно освежить, что такое A/AAAA/CNAME и NS-записи, — «DNS-записи: A, AAAA, CNAME и другие».
- Желательно — уже выпущенный сертификат Let's Encrypt, см. «Бесплатный SSL с Let's Encrypt (certbot)». Дальше в статье будет понятно, как он взаимодействует с Cloudflare, но начать можно и без него.
- Бесплатный аккаунт Cloudflare — всё, что описано в этой статье (проксирование, SSL/TLS, базовое кэширование, скрытие IP), доступно на тарифе Free.
- Доступ по SSH под root или пользователем с sudo — для настройки realip-модуля и, по желанию, файрвола.
Шаг 1. Добавьте домен в Cloudflare и смените NS-серверы
- Зарегистрируйтесь или войдите на dash.cloudflare.com.
- Нажмите Add a domain (в некоторых версиях панели — Onboard a domain) и введите домен без
wwwи протокола, напримерexample.com. - Выберите тариф — для всего, что описано в этой статье, достаточно Free.
- Cloudflare сам просканирует текущие DNS-записи домена и предложит их импортировать. Внимательно проверьте список — особенно почтовые записи (
MX,TXTс SPF/DKIM/DMARC): если сканер что-то пропустит или исказит, после переключения NS почта перестанет работать. Недостающие записи добавьте вручную до переключения NS. - Cloudflare выдаст два NS-адреса вида
xxxx.ns.cloudflare.com— зайдите в панель регистратора домена и замените там текущие NS-записи на эти два.
Смена NS вступает в силу не сразу — обычно от нескольких минут до 24 часов, пока обновление разойдётся по резолверам. Проверить, какие NS-серверы сейчас видны снаружи, можно командой:
dig NS example.com +shortКогда в ответе появятся два адреса вида *.ns.cloudflare.com, а в панели Cloudflare статус домена сменится на Active, — можно переходить к настройке записей.
Шаг 2. Proxied и DNS only: оранжевое и серое облако
В разделе DNS → Records у каждой записи есть переключатель-«облако»:
- Proxied (оранжевое облако) — запрос идёт через сеть Cloudflare: посетителям виден IP-адрес Cloudflare, а не настоящий IP VPS; на такую запись действуют кэширование, WAF, базовая защита от DDoS и остальные функции Cloudflare.
- DNS only (серое облако) — Cloudflare отдаёт настоящий IP из записи как обычный DNS-резолвер, без прокси; функции Cloudflare (кэш, WAF, скрытие IP) на такую запись не действуют.
Проксировать можно только записи A, AAAA и CNAME — у остальных типов (MX, TXT, NS, SRV и т. д.) переключателя вообще нет, они всегда DNS only — это ограничение самого Cloudflare.
- Основную запись сайта (
example.com,www.example.com) включите Proxied — чтобы получить CDN и скрытие IP. - Почтовые записи (
MX) и записи для почтовых сервисов (SPF/DKIM/DMARC-подобныеTXT,CNAMEдля autodiscover/autoconfig) оставьте DNS only: Cloudflare не проксирует почтовый трафик, а проксированныйCNAMEможет сломать проверку у почтового провайдера. - Служебные поддомены, к которым вы обращаетесь напрямую (например, отдельный не-HTTP сервис), тоже логично оставить DNS only.
Шаг 3. Режим SSL/TLS: включите Full (strict)
В разделе SSL/TLS → Overview выберите режим шифрования между Cloudflare и вашим origin-сервером:
- Off — вообще без шифрования, весь трафик, включая Cloudflare → origin, идёт открытым текстом. Не используйте.
- Flexible — посетитель ↔ Cloudflare может быть по HTTPS, но Cloudflare ↔ origin всегда идёт по обычному HTTP.
- Full — Cloudflare обращается к origin по тому же протоколу, что и посетитель, включая HTTPS, но не проверяет сертификат origin — подойдёт даже самоподписанный.
- Full (strict) — то же самое, но Cloudflare ещё и проверяет, что сертификат origin настоящий: выпущен публичным CA (например, Let's Encrypt) или Cloudflare Origin CA.
Cloudflare рекомендует режим Full или Full (strict), чтобы исключить незашифрованные и неаутентифицированные подключения к origin. Если на VPS уже настроен Let's Encrypt (см. «Бесплатный SSL с Let's Encrypt (certbot)»), сразу ставьте Full (strict) — это самый защищённый вариант и он ничего не стоит сверх обычного сертификата.
Если на origin ещё вообще нет сертификата, поставьте пока Full (strict проверять пока нечего) или временно переключите запись в DNS only (шаг 2) — и выпустите сертификат по шагу 4.
Шаг 4. Сертификат на origin и certbot за проксированием
Если Let's Encrypt на VPS был настроен ещё до подключения Cloudflare, на этом шаге ничего дополнительно делать не нужно — переходите к шагу 5. Ниже — что учитывать, если сертификат ещё предстоит получить или обновить для нового поддомена уже после того, как запись стала Proxied.
Certbot с HTTP-01-валидацией (--nginx/--apache/--webroot) обычно нормально работает и через проксированный домен: запрос Let's Encrypt на http://example.com/.well-known/acme-challenge/... попадает на edge Cloudflare, а тот перенаправляет его на origin по 80-му порту. Но два стандартных механизма Cloudflare могут это сломать:
- Always Use HTTPS (SSL/TLS → Edge Certificates) — редиректит на HTTPS прямо на edge, до того как запрос дойдёт до origin. Если у origin ещё нет валидного сертификата, получить новый через HTTP-01 в этот момент не выйдет.
- Cache Rule с «Cache Everything» на весь сайт — может закэшировать старый ответ по пути
/.well-known/acme-challenge/..., из-за чего повторная валидация при продлении сертификата получит устаревший токен.
Два рабочих варианта:
- Проще всего — на время выпуска или продления сертификата переключить запись обратно в DNS only (серое облако, шаг 2), выполнить
certbotкак обычно (см. статью «Бесплатный SSL с Let's Encrypt (certbot)») и включить Proxied обратно, когда сертификат готов. - Надёжнее для автопродления — переключить certbot на DNS-01-валидацию через официальный плагин
certbot-dns-cloudflare. Он подтверждает владение доменом через TXT-запись, создаваемую по API Cloudflare, и не зависит от того, проксируется запись или нет.
Чтобы настроить DNS-01, сначала создайте API-токен в Cloudflare: My Profile → API Tokens → Create Token, шаблон Edit zone DNS, в Zone Resources укажите конкретный домен, а не «все зоны». Скопируйте токен — панель показывает его только один раз.
Дальше на VPS (certbot уже должен быть установлен через snap, как в статье про Let's Encrypt):
sudo snap install certbot-dns-cloudflare
sudo snap set certbot trust-plugin-with-root=ok
sudo snap connect certbot:plugin certbot-dns-cloudflareПроверьте, что плагин подключился:
certbot pluginsВ списке должен появиться dns-cloudflare. Сохраните токен в файл, доступный на чтение только root:
sudo mkdir -p /root/.secrets/certbot
sudo tee /root/.secrets/certbot/cloudflare.ini > /dev/null <<'EOF'
dns_cloudflare_api_token = <CLOUDFLARE_API_TOKEN>
EOF
sudo chmod 600 /root/.secrets/certbot/cloudflare.iniЗамените <CLOUDFLARE_API_TOKEN> на настоящий токен из панели Cloudflare, затем запросите сертификат:
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/.secrets/certbot/cloudflare.ini \
--dns-cloudflare-propagation-seconds 60 \
-d example.com -d www.example.comРежим certonly только получает сертификат, но не правит конфигурацию веб-сервера — если вы ещё не настраивали HTTPS в nginx/Apache вручную, сделайте это по статье «Бесплатный SSL с Let's Encrypt (certbot)», указав пути /etc/letsencrypt/live/example.com/fullchain.pem и privkey.pem.
Проверьте результат после любого из двух вариантов:
curl -I https://example.com/Шаг 5. Базовое кэширование
По умолчанию, без какой-либо настройки, Cloudflare уже кэширует статику по расширению файла — изображения (jpg, png, gif, webp), видео (mp4, webm), CSS, JS, шрифты (woff, woff2), архивы. HTML и JSON по умолчанию не кэшируются — Cloudflare ориентируется на заголовки Cache-Control/Expires origin, а если их нет, применяет TTL по умолчанию (около 2 часов для успешных ответов).
Чтобы кэшировать больше — например, HTML статичных страниц или гарантировать TTL независимо от заголовков origin, — используйте Cache Rules (Rules → Overview, в некоторых версиях панели — Caching → Cache Rules; это текущая замена устаревших Page Rules):
- Задайте условие, например «URI Path starts with
/blog/» или «Hostname equalsexample.com». - В действии выберите Cache eligibility: Eligible for cache и задайте Edge TTL — например, 2 часа.
- Для полностью статичного сайта без личных кабинетов и cookies можно применить Cache Everything на весь домен — но не делайте так для сайтов с авторизацией, корзиной или другим персональным контентом: можно случайно отдать одному посетителю закэшированную страницу другого.
Дополнительно пригодятся:
- Browser Cache TTL (Caching → Configuration) — отдельная настройка: сколько ресурс хранится в кэше браузера посетителя, не путать с кэшем на edge Cloudflare.
- Development Mode (там же, Caching → Configuration) — временно, на 3 часа, отключает кэш Cloudflare; удобно при проверке изменений на origin, чтобы не ждать протухания кэша.
- Purge Cache — после деплоя обновлений на origin стоит очистить кэш («Purge Everything» или по конкретным URL), иначе часть посетителей ещё какое-то время будет видеть старую версию.
Шаг 6. Настоящий IP посетителя: заголовок CF-Connecting-IP
Как только запись стала Proxied, в логах nginx/Apache и во всех приложениях на VPS вместо реального IP посетителя будет виден IP edge-сервера Cloudflare — это ломает логи, geo-IP, rate limiting и такие инструменты, как fail2ban, которые опираются на IP-адрес.
Cloudflare добавляет к каждому проксированному запросу заголовок `CF-Connecting-IP` — он содержит ровно один настоящий IP-адрес посетителя. Есть также True-Client-IP (то же самое, но доступен только на тарифе Enterprise) и стандартный X-Forwarded-For (список через запятую, менее удобен для этой задачи) — для восстановления реального IP используйте именно CF-Connecting-IP.
Nginx: модуль ngx_http_realip_module
Модуль ngx_http_realip_module уже встроен в стандартный пакет nginx из репозиториев Ubuntu/Debian/AlmaLinux/Rocky — ничего доустанавливать не нужно (проверить можно командой nginx -V 2>&1 | grep -o http_realip_module). Сгенерируйте конфиг с актуальными диапазонами IP Cloudflare — официальный список публикуется на cloudflare.com:
{
for ip in $(curl -s https://www.cloudflare.com/ips-v4); do
echo "set_real_ip_from $ip;"
done
for ip in $(curl -s https://www.cloudflare.com/ips-v6); do
echo "set_real_ip_from $ip;"
done
echo "real_ip_header CF-Connecting-IP;"
} | sudo tee /etc/nginx/conf.d/cloudflare-realip.conf > /dev/nullПроверьте и примените конфигурацию:
sudo nginx -t && sudo systemctl reload nginxПосле этого $remote_addr в конфигурации nginx — в том числе в стандартном log_format — автоматически станет настоящим IP посетителя вместо IP Cloudflare, отдельно менять log_format не требуется.
Apache: модуль mod_remoteip
На Ubuntu/Debian модуль уже входит в пакет apache2, его достаточно включить:
{
echo "RemoteIPHeader CF-Connecting-IP"
for ip in $(curl -s https://www.cloudflare.com/ips-v4) $(curl -s https://www.cloudflare.com/ips-v6); do
echo "RemoteIPTrustedProxy $ip"
done
} | sudo tee /etc/apache2/conf-available/remoteip.conf > /dev/nullsudo a2enmod remoteip
sudo a2enconf remoteip
sudo apache2ctl configtest
sudo systemctl restart apache2По умолчанию Apache логирует IP через %h. Чтобы в логах тоже был настоящий IP, замените в LogFormat (файл /etc/apache2/apache2.conf) %h на %a.
Шаг 7. Ограничьте 80/443 только сетями Cloudflare (опционально)
Proxied-запись прячет IP VPS от обычного DNS-лукапа, но если реальный IP всё же где-то «утёк» (старый DNS-кэш, случайно оставленная DNS only запись, сканирование диапазонов хостера), защита Cloudflare — включая базовое сглаживание DDoS — просто не сработает: атакующий обратится к серверу напрямую, в обход Cloudflare. Чтобы закрыть эту дыру, разрешите на 80/443 только сети Cloudflare.
Ниже — вариант для ufw (Ubuntu/Debian). Если ufw ещё не настроен — сначала пройдите статью «Файрвол ufw»; как и она сама, этот шаг не рассматривает firewalld на AlmaLinux/Rocky — там тот же результат достигается через rich rules (firewall-cmd --add-rich-rule), но это отдельная тема со своим синтаксисом. Дальше добавьте разрешающие правила для диапазонов Cloudflare:
for ip in $(curl -s https://www.cloudflare.com/ips-v4) $(curl -s https://www.cloudflare.com/ips-v6); do
sudo ufw allow from "$ip" to any port 80,443 proto tcp
doneТеперь удалите старые широкие правила, открывавшие 80/443 для всех (80/tcp, 443/tcp, Nginx Full и подобные) — посмотрите их номера и удаляйте по одному, начиная с большего номера:
sudo ufw status numbered
sudo ufw delete <RULE_NUMBER>Этот шаг стоит повторять вместе с обновлением конфигурации realip из шага 6 — используются одни и те же диапазоны.
Что дальше
Домен работает через Cloudflare: CDN ускоряет отдачу статики по всему миру, IP VPS скрыт от обычных посетителей и сканеров, а базовые волюметрические DDoS-атаки гасятся на edge Cloudflare, не доходя до сервера. Из смежных тем: «DNS-записи: A, AAAA, CNAME и другие» и «Как привязать домен к серверу» — если нужно освежить, как работают записи без Cloudflare; «Файрвол ufw» и «Чек-лист безопасности сервера» — чтобы защитить сам VPS, а не только спрятать его за CDN.