Коротко: ошибка Cloudflare 522 «Connection timed out» означает, что Cloudflare не смог установить TCP-соединение с вашим сервером, который в терминах Cloudflare называется origin. 19 секунд он отправлял SYN-пакеты, а SYN-ACK так и не пришёл. Реже соединение открылось, но сервер не подтвердил запрос в течение 90 секунд. Браузер посетителя и Cloudflare в порядке, поэтому проблема на вашем сервере или перед ним. На практике это одно из четырёх: файрвол отбрасывает IP-диапазоны Cloudflare, DNS-запись указывает на неверный IP, сервер лежит или слишком загружен, чтобы принимать соединения, либо fail2ban или ограничение частоты запросов забанили адреса Cloudflare.
# 1. С вашего компьютера: отвечает ли origin, если обойти Cloudflare?
# 203.0.113.10 = IP вашего сервера, example.com = ваш домен
curl -sk --connect-timeout 10 -o /dev/null -w 'connect=%{time_connect}s code=%{http_code}\n' \
--resolve example.com:443:203.0.113.10 https://example.com/
# Режим SSL/TLS Flexible? Cloudflare подключается к порту 80, проверяйте его:
# --resolve example.com:80:203.0.113.10 http://example.com/
# 2. На сервере: слушает ли веб-сервер порты 80 и 443?
sudo ss -tlnp '( sport = :80 or sport = :443 )'
# 3. На сервере: приходят ли SYN и уходят ли обратно SYN-ACK?
sudo tcpdump -ni any 'tcp[tcpflags] & tcp-syn != 0 and (port 80 or port 443)'
# 4. Файрвол и баны
sudo ufw status verbose
sudo nft list ruleset | grep -iE 'drop|reject'
sudo fail2ban-client banned--resolve отправляет запрос прямо на IP вашего сервера с правильным именем хоста, и вы видите origin без Cloudflare на пути. -k отключает проверку сертификата — это нужно, если на origin стоит сертификат Cloudflare Origin CA. Используйте этот флаг только для такой проверки. code=200 (или любой настоящий статус) значит, что у вас сервер работает, — тогда виновато что-то, что обращается с Cloudflare иначе, чем с вами. Зависание, которое заканчивается connect=0.000000s code=000, значит, что до сервера не может достучаться никто, и искать нужно на самом сервере. Если файрвол уже пускает только диапазоны Cloudflare, эта проверка зависнет намеренно — переходите сразу к шагу 3.
Что значит ошибка 522 и чем она отличается от 520, 521, 523 и 524
Cloudflare — обратный прокси, поэтому соединений два: от посетителя до Cloudflare и от Cloudflare до вашего сервера. Каждая ошибка 52x описывает сбой на втором из них. Номер показывает, как далеко зашло соединение:
| Ошибка | Что увидел Cloudflare | Обычная причина на origin |
|---|---|---|
| 520 | Соединение открылось, но ответ пустой, сброшен или некорректен | Падение посреди запроса, return 444 в nginx, слишком большие заголовки |
| 521 | Origin отклонил соединение сбросом (RST) | Веб-сервер не запущен, файрвол настроен на reject |
| 522 | Нет SYN-ACK за 19 с или нет ACK на запрос за 90 с | Файрвол отбрасывает Cloudflare, неверный IP в DNS, сервер лежит или перегружен |
| 523 | До IP origin вообще нет маршрута | Неверный или немаршрутизируемый адрес, проблема маршрутизации у вышестоящих сетей |
| 524 | Подключился и отправил запрос, но не получил ответа за 125 с | Медленный запрос или перегруженное приложение |
Лимиты в 19 и 90 секунд Cloudflare называет ненастраиваемыми. Увеличить их нельзя, поэтому решение всегда одно: добиться, чтобы origin отвечал. Если сравнить с ошибкой 521 (англ.), получается удобное правило: файрвол, который отклоняет (reject) пакеты Cloudflare, обычно даёт 521, а тот, что молча их отбрасывает (drop), — 522.
Причина 1: файрвол отбрасывает IP-диапазоны Cloudflare
Cloudflare называет эту причину самой частой. Каждый запрос приходит на ваш сервер с адреса пограничного узла Cloudflare, а не от посетителя. Значит, файрвол должен пропускать опубликованные диапазоны Cloudflare на те порты, которые Cloudflare использует: порт 80 в режиме SSL/TLS Flexible и порт 443 в режимах Full и Full (strict), когда посетитель заходит по HTTPS. Классическая ошибка — переключить режим на Full, когда файрвол по-прежнему открывает только порт 80. Тогда по тайм-ауту отваливается каждый HTTPS-запрос.
Подтвердите это через tcpdump на сервере, пока обновляете страницу сайта:
- SYN (
Flags [S]) приходят с адресов Cloudflare, но обратно не уходит ни одногоFlags [S.]: их отбрасывает файрвол на сервере. tcpdump видит пакеты раньше файрвола, поэтому картина здесь такая однозначная. - Не приходит вообще ничего: пакеты не доходят до сервера. Проверьте DNS-запись (причина 2) и всё, что фильтрует трафик перед сервером (причина 6).
[S]приходят,[S.]уходят: сейчас рукопожатие проходит. Смотрите на нагрузку (причина 4) или на баны, которые то появляются, то снимаются (причина 3).
Чтобы пропустить Cloudflare через ufw, пройдитесь циклом по официальным спискам. Cloudflare публикует их простым текстом, по одному диапазону в строке:
for net in $(curl -s https://www.cloudflare.com/ips-v4) $(curl -s https://www.cloudflare.com/ips-v6); do
sudo ufw allow proto tcp from "$net" to any port 80,443 comment 'Cloudflare'
done
sudo ufw status numbered | grep Cloudflare # по правилу на диапазон, v4 и v6С nftables или iptables ищите цепочку с policy drop без разрешающего правила для 80 и 443. Учтите, что nft list ruleset показывает и правила, созданные iptables-nft и Docker. Если origin должен принимать веб-трафик только от Cloudflare, добавьте правила выше и удалите все правила вида «разрешить 80/443 откуда угодно», например профиль Nginx Full в ufw. SSH не трогайте. В каком порядке безопасно менять правила на работающем сервере, описано в руководстве по ufw (англ.).
Причина 2: DNS-запись указывает на неверный IP
Проксируемые записи скрывают IP вашего origin от dig — он показывает только адреса Cloudflare. Поэтому сравните запись в панели Cloudflare (DNS → Records) с адресами, которые на сервере есть на самом деле:
ip -4 -br addr show scope global
ip -6 -br addr show scope globalТакое случается после переезда, после замены сервера или когда в записи остался старый IP машины, которой больше нет. Адрес, за которым нет хоста, ничего не отвечает, и результат — 522 или 523 (англ.), если адрес вообще не маршрутизируется. С AAAA-записями так: если у имени есть и A, и AAAA, Cloudflare предпочитает IPv4. Устаревшая AAAA-запись бьёт в основном по именам, у которых только AAAA. Там IPv6-адрес должен быть верным, а файрвол должен пропускать и IPv6-диапазоны Cloudflare. Как настроить записи с нуля, описано в статье Как направить домен на VPS (англ.).
Причина 3: fail2ban или лимит запросов забанили Cloudflare
Эту причину легко пропустить, потому что у большинства посетителей сайт работает. Когда сайт стоит за Cloudflare, nginx и Apache пишут в лог в качестве клиента адрес пограничного узла Cloudflare, если вы не восстановили настоящий IP посетителя. Джейл, который следит за веб-логами, например nginx-limit-req или nginx-botsearch, банит тогда адрес Cloudflare за чужой трафик. Посетители, которых маршрутизируют через этот адрес, получают 521, если бан отклоняет пакеты, — так работают стандартные действия fail2ban для iptables, nftables и ufw. А если бан пакеты отбрасывает, как действие, переключённое на drop, и большинство самописных лимитов, они получают 522. Остальные видят сайт, поэтому жалобы могут касаться лишь нескольких локаций Cloudflare. Страница ошибки называет дата-центр, который её отдал.
curl -s https://www.cloudflare.com/ips-v4 -o /tmp/cf-ips.txt
sudo fail2ban-client banned | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | python3 -c '
import sys, ipaddress
nets = [ipaddress.ip_network(l.strip()) for l in open("/tmp/cf-ips.txt") if l.strip()]
for line in sys.stdin:
ip = ipaddress.ip_address(line.strip())
if any(ip in n for n in nets):
print("banned Cloudflare IP:", ip)'
sudo fail2ban-client unban 162.158.10.20 # разбаньте каждый адрес из выводаРазбан убирает только сегодняшний симптом. Надёжное решение состоит из трёх частей. Во-первых, восстановите настоящие IP посетителей, чтобы логи называли правильного клиента. В nginx это делает модуль realip, который в Debian и Ubuntu встроен в сборку:
{
for net in $(curl -s https://www.cloudflare.com/ips-v4) $(curl -s https://www.cloudflare.com/ips-v6); do
echo "set_real_ip_from $net;"
done
echo "real_ip_header CF-Connecting-IP;"
} | sudo tee /etc/nginx/conf.d/cloudflare-realip.conf
sudo nginx -t && sudo systemctl reload nginxВ Apache включите mod_remoteip командой sudo a2enmod remoteip и задайте ему RemoteIPHeader CF-Connecting-IP плюс по одной строке RemoteIPTrustedProxy на каждый диапазон. Во-вторых, добавьте диапазоны Cloudflare в ignoreip в /etc/fail2ban/jail.local, чтобы адрес пограничного узла больше никогда не попал в бан. Эта команда печатает строку, которую можно вставить под [DEFAULT]:
echo "ignoreip = 127.0.0.1/8 ::1" $(curl -s https://www.cloudflare.com/ips-v4) $(curl -s https://www.cloudflare.com/ips-v6)В-третьих, примите как факт: бан настоящего IP посетителя в локальном файрволе ничего не даёт для проксируемого трафика, потому что эти пакеты всё равно приходят от Cloudflare. Если веб-джейлы должны кого-то блокировать, используйте действие fail2ban cloudflare-token: оно ставит бан на стороне Cloudflare через его API. То же относится к самописным лимитам соединений на источник (connlimit или hashlimit в iptables, отслеживание соединений в защитных комплексах). Несколько адресов Cloudflare несут трафик тысяч посетителей, поэтому первыми упираются в любой лимит на IP.
Причина 4: сервер лежит или слишком загружен, чтобы принимать соединения
Сервер, который упал, завис при загрузке или как раз перезагружается, снаружи выглядит точно так же, как файрвол с drop. Сначала откройте консоль. На VPS VMHeaven VNC-консоль в личном кабинете открывается прямо в браузере и доступна, даже когда сеть сервера лежит или закрыта файрволом. Если машина жива, проверьте, может ли она ещё принимать новые соединения. Когда у nginx заканчиваются worker_connections или заняты все воркеры Apache, очередь accept в ядре заполняется, и новые SYN отбрасываются. Cloudflare сообщает об этом как о 522.
uptime; free -h
nstat -az TcpExtListenOverflows TcpExtListenDrops # запустите дважды с интервалом в минуту
sudo ss -ltn '( sport = :80 or sport = :443 )' # Recv-Q близко к Send-Q = очередь заполнена
sudo dmesg -T | grep -iE 'conntrack|syn flooding'
sudo grep -i 'worker_connections are not enough' /var/log/nginx/error.log
sudo grep -i 'MaxRequestWorkers' /var/log/apache2/error.log- Счётчики переполнения продолжают расти или
Recv-Qдержится на размере backlog: веб-сервер не успевает принимать соединения. Прежде чем поднимать лимиты, найдите, что держит воркеры: медленный PHP, заблокированная база данных, своп. nf_conntrack: table full, dropping packet: таблица отслеживания соединений в ядре заполнена, и каждое новое соединение отбрасывается, пока записи не истекут. Сравнитеsysctl net.netfilter.nf_conntrack_countсnet.netfilter.nf_conntrack_max.- Высокая нагрузка и CPU около 100%: найти процесс поможет статья высокая нагрузка на CPU на VPS (англ.). Если нагрузка — это реальный трафик, а не вышедшая из-под контроля задача, сервер мал для сайта.
Увеличение worker_connections, MaxRequestWorkers или pm.max_children в PHP-FPM помогает, только если для дополнительных воркеров есть память. Иначе вы меняете 522 на OOM killer. В nginx значение worker_connections выше лимита открытых файлов воркеров требует ещё и worker_rlimit_nofile, иначе под нагрузкой воркеры падают с Too many open files (англ.). Если сайт просто перерос сервер, подбирайте следующий под характер нагрузки: Standard KVM даёт больше vCore и памяти на тариф для множества параллельных воркеров, а Hi-CPU KVM рассчитан на задачи, которые упираются в одно-два ядра, а не в их количество.
Причина 5: на origin выключен keep-alive
Это самый маловероятный пункт списка, но Cloudflare его называет. Cloudflare переиспользует открытые соединения с вашим origin вместо нового TCP-рукопожатия на каждый запрос, и его страница о лимитах соединений просит держать HTTP keep-alive включённым. Без keep-alive каждому запросу нужно новое рукопожатие, и под нагрузкой это накапливается. nginx по умолчанию держит соединения открытыми 75 секунд, у Apache по умолчанию стоит KeepAlive On. Ищите, не выключил ли это кто-нибудь:
sudo nginx -T 2>/dev/null | grep -n keepalive_timeout # "keepalive_timeout 0;" выключает его
sudo grep -RniE '^\s*KeepAlive\s' /etc/apache2/ # "KeepAlive Off" выключает егоПричина 6: пакеты теряются до вашего сервера
Если DNS-запись верна, файрвол на сервере пропускает Cloudflare, а tcpdump ничего не видит, пока посетители получают 522, трафик теряется ещё до машины. Виноват может быть сетевой файрвол провайдера, группа безопасности или фильтр перед сервером, а может быть и проблема маршрутизации между Cloudflare и вашей сетью. Это исправляет провайдер. Cloudflare советует передать ему:
- код ошибки, точное время с часовым поясом и полный URL;
- Ray ID со страницы ошибки;
- MTR от origin до адреса Cloudflare, который раньше подключался. Такой адрес найдётся в access-логе за период до восстановления настоящих IP или в выводе
ss -tn.
sudo apt install -y mtr-tiny
mtr -rwc 50 162.158.1.1 # замените на IP Cloudflare из своих логовЧасть ошибок 522 вызывает не origin, а настройка на стороне Cloudflare. Worker на Custom Domain, который делает fetch собственного имени хоста, возвращает 522. Так же ведут себя Origin Rule, указывающее на имя, которое не резолвится, и проект Pages, чей CNAME не указывает на его собственный домен Pages. Если вы поменяли порт в Origin Rule, этот порт тоже должен быть открыт в файрволе.
Как не допустить повторения ошибки 522
- Автоматизируйте белый список Cloudflare и запускайте скрипт раз в неделю из cron, чтобы новые диапазоны были разрешены до того, как с них пойдёт трафик.
- Восстановите настоящие IP до включения любых веб-джейлов и держите диапазоны Cloudflare в
ignoreip. - Используйте Full (strict) и откройте 443, чтобы порт, на который подключается Cloudflare, совпадал с портом, открытым в файрволе.
- Следите за origin, а не только за пограничными узлами: Origin Analytics в Cloudflare показывает сбои TCP-соединений по путям, а страница HTTP Traffic фильтрует по коду ответа пограничного узла и origin. Внешняя проверка, которая регулярно запрашивает health-check URL, предупредит вас раньше посетителей.
- Оставляйте запас: origin, который при обычном трафике работает у предела соединений, начнёт отдавать 522 при первом же всплеске.
Если вы только заходите на сайт, который показывает 522, ни причина, ни решение не на вашей стороне. Очистка кеша браузера и смена сети не помогут. Повторите попытку через несколько минут, а если ошибка не уходит, сообщите владельцу сайта. Страница ошибки показывает, что ваш браузер и Cloudflare работают, а хост не отвечает.
Частые вопросы
Чем ошибка 521 отличается от 522 в Cloudflare?
В обоих случаях Cloudflare не смог подключиться к вашему серверу. 521 — сервер сразу отклонил соединение: обычно веб-сервер не запущен или файрвол отвечает Cloudflare отказом (reject). 522 — за 19 секунд не ответил никто: файрвол молча отбрасывает (drop) диапазоны Cloudflare, в DNS-записи неверный IP или сервер перегружен либо выключен.
Сколько Cloudflare ждёт, прежде чем показать ошибку 522?
19 секунд на TCP-рукопожатие с вашим сервером; за это время Cloudflare несколько раз повторяет SYN. Если соединение открылось, но сервер не подтвердил запрос за 90 секунд, это тоже 522. Оба лимита Cloudflare называет ненастраиваемыми, поэтому чинить нужно сервер, а не тайм-ауты.
Можно ли исправить ошибку 522 со стороны посетителя?
Нет. Ошибка 522 значит, что сервер сайта не отвечает Cloudflare, поэтому очистка кеша браузера или смена сети не помогут. Повторите попытку позже или сообщите владельцу сайта: исправлять нужно сервер или его файрвол.