From 051c4970549a58139389fa38f995bac1f1f8ba10 Mon Sep 17 00:00:00 2001 From: Greg Karekinian Date: Sat, 1 Aug 2026 16:33:35 +0200 Subject: [PATCH] Rate limit requests from bots on Gitea For now this is 240 r/m (4r/s), for Claude, Sogou and Meta user agents. The values are pretty conservative, I initially had tighter limits. Let's see how it goes, this is running on Fornax and Draco and right now we're not hitting the limits. --- .../kosmos_gitea/files/rate_limits.conf | 25 +++++++++++++++++++ site-cookbooks/kosmos_gitea/recipes/nginx.rb | 8 ++++++ .../templates/default/nginx_conf_web.erb | 3 +++ 3 files changed, 36 insertions(+) create mode 100644 site-cookbooks/kosmos_gitea/files/rate_limits.conf diff --git a/site-cookbooks/kosmos_gitea/files/rate_limits.conf b/site-cookbooks/kosmos_gitea/files/rate_limits.conf new file mode 100644 index 0000000..6c147c8 --- /dev/null +++ b/site-cookbooks/kosmos_gitea/files/rate_limits.conf @@ -0,0 +1,25 @@ +# Increase if you have very long User-Agent strings +map_hash_bucket_size 256; + +# Bot user agents +map $http_user_agent $bot_name { + default ""; + ~*ClaudeBot "claude"; + ~*Sogou "sogou"; + ~*meta-externalagent "meta-externalagent"; + # add more as needed +} + +# Decide the rate-limit key (per-IP for each bot in this example) +map $bot_name $bot_limit_key { + default ""; + "claude" $binary_remote_addr; + "sogou" $binary_remote_addr; + "meta-externalagent" $binary_remote_addr; +} + +# Shared memory zone – only non-empty keys are counted +limit_req_zone $bot_limit_key zone=bots:20m rate=240r/m; # 4r/s per IP+bot + +# Status code returned when the limit is exceeded +limit_req_status 429; diff --git a/site-cookbooks/kosmos_gitea/recipes/nginx.rb b/site-cookbooks/kosmos_gitea/recipes/nginx.rb index 243e9f9..3cdc717 100644 --- a/site-cookbooks/kosmos_gitea/recipes/nginx.rb +++ b/site-cookbooks/kosmos_gitea/recipes/nginx.rb @@ -17,6 +17,14 @@ tls_cert_for domain do action :create end +# Slow down requests from bots +cookbook_file "#{node["openresty"]["dir"]}/conf.d/rate_limits.conf" do + source "rate_limits.conf" + owner "root" + group "root" + mode "0644" +end + openresty_site domain do template "nginx_conf_web.erb" variables server_name: domain, diff --git a/site-cookbooks/kosmos_gitea/templates/default/nginx_conf_web.erb b/site-cookbooks/kosmos_gitea/templates/default/nginx_conf_web.erb index 1b40b4d..f87d71c 100644 --- a/site-cookbooks/kosmos_gitea/templates/default/nginx_conf_web.erb +++ b/site-cookbooks/kosmos_gitea/templates/default/nginx_conf_web.erb @@ -20,6 +20,9 @@ server { proxy_intercept_errors on; + # Rate limit for bots. Defined in /etc/openresty/conf.d/rate_limits.conf + limit_req zone=bots burst=10; # allow a larger spike for asset bursts + location ~ ^/(avatars|repo-avatars)/.*$ { proxy_buffers 1024 8k; proxy_pass http://_gitea_web;