Для простоты предположим, что у меня есть веб-сервер, на котором запущен nginx, обслуживающий один файл php (с сообщением «hello world») через php5-fpm.
Предположим, что сервер находится за облачной вспышкой, и все запросы к моему серверу поступают через облачную вспышку.
При почти стандартной конфигурации все IP-адреса, о которых сообщает nginx, являются IP-адресами cloudflare, поэтому мы используем realip_module и следуем эта ссылка установить реальный ip от cloudflare.
Мой следующий шаг - ограничить как подключения, так и запросы к этому файлу php до 1 запроса в секунду для каждого IP-адреса пользователя (но разрешить неограниченное количество запросов от самих облачных вспышек).
В соответствии с этот ответ безопасно использовать $binary_remote_addr
для обеспечения соблюдения ограничений, потому что после использования realip_module, nginx перепишет IP-адрес на любой IP-адрес, указанный на CF-Connecting-IP
заголовок.
Итак, я начинаю эту конфигурацию:
limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=1r/s;
limit_conn conn_limit_per_ip 1;
limit_req zone=req_limit_per_ip burst=1 nodelay;
Это означает, что я разрешаю только 1 HTTP-соединение и 1 запрос в секунду, с одним дополнительным запросом в течение этой секунды (я чувствую себя здесь щедрым).
я знаю это $binary_remote_addr
включает IP-адрес пользователя, как сообщает cloudflare, но все соединения и запросы все еще поступают на сервер через cloudflare (следовательно, я не могу использовать для этого iptables).
Мое понимание limit_conn
и limit_req
в том, что он будет показывать страницу статуса 503 любому пользователю, который превышает эти ограничения.
Случай 1:
Чтобы упростить задачу, предположим, что 300 пользователей в одном регионе и с использованием одного и того же периферийного местоположения Cloudflare получают доступ к сайту за одну секунду.
Поскольку cloudflare сообщает разные IP-адреса для всех, и каждый делает один запрос, никто никогда не увидит, что 503 страница состояния и 300 запросов будут разрешены через cloudflare.
Случай 2:
Допустим, за эту секунду к моей странице обращаются 3 человека. Из них 2 пользователя выполнили 1 единичный запрос, а третий пользователь использует ab (тест apache) для выполнения 10 одновременных запросов.
Поскольку cloudflare сообщает разные IP-адреса для всех, я могу предположить, что первые 2 пользователя увидят мою страницу без проблем, в то время как третий человек запросит мою страницу дважды (потому что я использую burst + nodelay), а затем получит страницу состояния 503 для остальные запросы в течение этой секунды. В следующую секунду он повторит то же самое, фактически ограничив количество запросов до 2 запросов в секунду.
Проблемы:
Поскольку все эти 503 запроса по-прежнему обслуживаются через cloudflare, начнут ли другие пользователи видеть сообщения cloudflare о том, что источник недоступен (нажмите здесь, чтобы повторить попытку кнопки живой версии), потому что предыдущие запросы не удались?
Я знаю, что если сервер не работает (нет сети), сообщения Cloudflare будут показаны всем, и потребуется несколько секунд, чтобы они исчезли, даже когда сервер снова заработает.
Будут ли показываться пользователям сообщения "server offline" от cloudflare, когда мой nginx начнет отвечать с ошибкой 503 этому конкретному плохому пользователю?
HTML (который является выводом PHP) - это не кешируется по умолчанию, поэтому они увидят ответ на свой запрос, если вы не кешируете на nginx. Чтобы быть уверенным, настройте правило страницы, которое определяет «стандартное кеширование», или, если вы хотите быть параноиком, вы можете установить его без кеширования, но тогда вы должны быть осторожны с соответствующим шаблоном, иначе CSS / JS не кешируется .
Я не верю, что 503 будут показаны другим пользователям. Вы можете попросить их поддержки - они достаточно отзывчивы даже на бесплатных планах.