Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHRAS-3588 implement NGNIX http request quota #4560

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,22 @@ GATEWAY_ALLOWED_IPS=
GATEWAY_DENIED_IPS=
GATEWAY_USERS=

# activate and manage http incoming request limits
# this feature is based on ip adresses and need PHRASEANET_TRUSTED_PROXIES
# defined to get real_ip
# @run
GLOBAL_REQUEST_LIMIT_ACTIVATE=0 # switch to 1 to enable limiting http requests using parameters below
GLOBAL_REQUEST_LIMIT_MEMORY=10m # For Exemple 16,000 IP addresses takes 1 megabyte, so our zone can store about 160,000 addresses.
GLOBAL_REQUEST_LIMIT_RATE=10r/s # Sets the maximum request rate. By default here the rate cannot exceed 10 requests per second
GLOBAL_REQUEST_LIMIT_BURST=20 # The burst parameter defines how many requests a client can make in excess of the rate specified by the zone
GLOBAL_REQUEST_LIMIT_NODELAY=1 # With the nodelay parameter, NGINX still allocates slots in the queue according to the burst parameter and imposes the configured rate limit. if not extra request queues waits 2 seconds to be forwarded

API_REQUEST_LIMIT_ACTIVATE=0 # switch to 1 to enable limiting api requests using parameters below
API_REQUEST_LIMIT_MEMORY=10m # For Exemple 16,000 IP addresses takes 1 megabyte, so our zone can store about 160,000 addresses.
API_REQUEST_LIMIT_RATE=10r/s # Sets the maximum request rate. By default here the rate cannot exceed 10 requests per second
API_REQUEST_LIMIT_BURST=20 # The burst parameter defines how many requests a client can make in excess of the rate specified by the zone
API_REQUEST_LIMIT_NODELAY=1 # With the nodelay parameter, NGINX still allocates slots in the queue according to the burst parameter and imposes the configured rate limit. if not extra request queues waits 2 seconds to be forwarded

# https and reverse proxy (on/off)
# set to on in the case : https behind a proxy
# @run
Expand Down
20 changes: 20 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ services:
- GATEWAY_DENIED_IPS
- GATEWAY_USERS
- GATEWAY_CSP
- GLOBAL_REQUEST_LIMIT_ACTIVATE
- GLOBAL_REQUEST_LIMIT_MEMORY
- GLOBAL_REQUEST_LIMIT_RATE
- GLOBAL_REQUEST_LIMIT_BURST
- GLOBAL_REQUEST_LIMIT_NODELAY
- API_REQUEST_LIMIT_ACTIVATE
- API_REQUEST_LIMIT_MEMORY
- API_REQUEST_LIMIT_RATE
- API_REQUEST_LIMIT_BURST
- API_REQUEST_LIMIT_NODELAY
ports:
- ${PHRASEANET_APP_PORT}:80
networks:
Expand Down Expand Up @@ -70,6 +80,16 @@ services:
- GATEWAY_USERS
- GATEWAY_FASTCGI_HTTPS
- GATEWAY_CSP
- GLOBAL_REQUEST_LIMIT_ACTIVATE
- GLOBAL_REQUEST_LIMIT_MEMORY
- GLOBAL_REQUEST_LIMIT_RATE
- GLOBAL_REQUEST_LIMIT_BURST
- GLOBAL_REQUEST_LIMIT_NODELAY
- API_REQUEST_LIMIT_ACTIVATE
- API_REQUEST_LIMIT_MEMORY
- API_REQUEST_LIMIT_RATE
- API_REQUEST_LIMIT_BURST
- API_REQUEST_LIMIT_NODELAY
networks:
- internal
labels:
Expand Down
32 changes: 32 additions & 0 deletions docker/nginx/root/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ fi
#GATEWAY_DENIED_IPS="172.1.0.1,172.1.0.2"
#GATEWAY_USERS="user1(password1),user2(password2)
touch /etc/nginx/restrictions
touch /etc/nginx/apirestrictions
touch /etc/nginx/.htpasswd

if [[ ! -z $GATEWAY_ALLOWED_IPS ]] || [[ ! -z $GATEWAY_DENIED_IPS ]] || [[ ! -z $GATEWAY_USERS ]]; then
Expand All @@ -81,6 +82,37 @@ if [[ ! -z $GATEWAY_ALLOWED_IPS ]] || [[ ! -z $GATEWAY_DENIED_IPS ]] || [[ ! -z
echo "deny all;" >> /etc/nginx/restrictions
fi
fi

echo "limit_req_status 429;" > /etc/nginx/conf.d/limits.conf

if [[ ! -z $GLOBAL_REQUEST_LIMIT_ACTIVATE ]] && [[ "$GLOBAL_REQUEST_LIMIT_ACTIVATE" = "1" ]]; then
echo "limit_req_zone \$binary_remote_addr zone=globaliplimits:$GLOBAL_REQUEST_LIMIT_MEMORY rate=$GLOBAL_REQUEST_LIMIT_RATE;" >> /etc/nginx/conf.d/limits.conf
if [[ ! -z $GLOBAL_REQUEST_LIMIT_BURST ]]; then
if [ "$GLOBAL_REQUEST_LIMIT_NODELAY" = "on" ] || [ "$GLOBAL_REQUEST_LIMIT_NODELAY" = "1" ];then
export GLOBAL_REQUEST_LIMITS="limit_req zone=globaliplimits burst=$GLOBAL_REQUEST_LIMIT_BURST nodelay;"
else
export GLOBAL_REQUEST_LIMITS="limit_req zone=globaliplimits burst=$GLOBAL_REQUEST_LIMIT_BURST;"
fi
else
export GLOBAL_REQUEST_LIMITS="limit_req zone=globaliplimits;"
fi
echo $GLOBAL_REQUEST_LIMITS >> /etc/nginx/restrictions
fi

if [[ ! -z $API_REQUEST_LIMIT_ACTIVATE ]] && [[ "$API_REQUEST_LIMIT_ACTIVATE" = "1" ]]; then
echo "limit_req_zone \$binary_remote_addr zone=apiiplimits:$API_REQUEST_LIMIT_MEMORY rate=$API_REQUEST_LIMIT_RATE;" >> /etc/nginx/conf.d/limits.conf
if [[ ! -z $API_REQUEST_LIMIT_BURST ]]; then
if [ "$API_REQUEST_LIMIT_NODELAY" = "on" ] || [ "$API_REQUEST_LIMIT_NODELAY" = "1" ];then
export API_REQUEST_LIMITS="limit_req zone=apiiplimits burst=$API_REQUEST_LIMIT_BURST nodelay;"
else
export API_REQUEST_LIMITS="limit_req zone=apiiplimits burst=$API_REQUEST_LIMIT_BURST;"
fi
else
export API_REQUEST_LIMITS="limit_req zone=apiiplimits;"
fi
echo $API_REQUEST_LIMITS >> /etc/nginx/apirestrictions
fi

unset GATEWAY_USERS
unset GATEWAY_DENIED_IPS
unset GATEWAY_ALLOWED_IPS
Expand Down
1 change: 1 addition & 0 deletions docker/nginx/root/nginx.conf.sample
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ server {
if (-f /var/alchemy/Phraseanet/datas/nginx/maintenance.html) {
return 401;
}
include apirestrictions;
rewrite ^(.*)$ /api.php/$1 last;
}

Expand Down
Loading