This repository has been archived on 2020-03-24. You can view files and clone it, but cannot push or open issues or pull requests.
quay/conf/nginx/server-base.conf.jnj
kbrwn 92aa3cf963 issues.jboss.org/projects/PROJQUAY/issues/PROJQUAY-4
Fixes an issue encountered when attempting to pull images from Quay via podman when storage proxying is enabled. Configures nginx to clear the Authorization header to ensure that storage engine does not raise a 400
2019-11-12 13:27:05 -08:00

338 lines
9.3 KiB
Nginx Configuration File

# vim: ft=nginx
keepalive_timeout 5;
if ($host = "www.quay.io") {
return 301 $proper_scheme://quay.io$request_uri;
}
# Disable the ability to be embedded into iframes
add_header X-Frame-Options DENY;
# Proxy Headers
proxy_set_header X-Forwarded-For $proper_forwarded_for;
proxy_set_header X-Forwarded-Proto $proper_scheme;
proxy_set_header Host $host;
proxy_redirect off;
proxy_set_header Transfer-Encoding $http_transfer_encoding;
location / {
proxy_pass http://web_app_server;
}
location /push {
proxy_pass http://web_app_server;
client_max_body_size 5M;
}
location /realtime {
proxy_pass http://web_app_server;
proxy_buffering off;
proxy_request_buffering off;
}
location ~ ^/_storage_proxy/([^/]+)/([^/]+)/([^/]+)/(.+) {
include resolver.conf;
auth_request /_storage_proxy_auth;
proxy_pass $2://$3/$4$is_args$args;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $3;
proxy_set_header Authorization "";
add_header Host $3;
proxy_buffering off;
proxy_request_buffering off;
proxy_read_timeout 60s;
}
location = /_storage_proxy_auth {
proxy_pass http://web_app_server;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
proxy_read_timeout 10;
}
location ~ ^/v2/_catalog(.*)$ {
proxy_pass http://registry_app_server;
proxy_read_timeout 10;
keepalive_timeout 0; # Disables HTTP 1.1 keep-alive and forces round-robin.
{% if enable_rate_limits %}
limit_req zone=dynamicauth_heavy_http1 burst=1 nodelay;
limit_req zone=dynamicauth_heavy_http2 burst=5 nodelay;
{% endif %}
}
location /secscan/ {
proxy_pass http://jwtproxy_secscan;
}
location /secscan/_internal_ping {
proxy_pass http://secscan_app_server;
}
{% if signing_enabled %}
location ~ ^/v2/(.+)/_trust/tuf/(.*)$ {
set $upstream_tuf {{ tuf_server }};
proxy_pass $upstream_tuf$uri;
proxy_set_header Host "{{ tuf_host }}";
}
{% endif %}
location /cnr {
proxy_buffering off;
proxy_request_buffering off;
proxy_pass http://registry_app_server;
proxy_read_timeout 120;
proxy_temp_path /tmp 1 2;
{% if enable_rate_limits %}
limit_req zone=staticauth burst=5 nodelay;
{% endif %}
}
location /api/ {
proxy_pass http://web_app_server;
{% if enable_rate_limits %}
limit_req zone=dynamicauth_heavy_http1 burst=25 nodelay;
limit_req zone=dynamicauth_heavy_http2 burst=100 nodelay;
{% endif %}
keepalive_timeout 0; # Disables HTTP 1.1 keep-alive and forces round-robin.
}
location /api/suconfig {
proxy_pass http://web_app_server;
# For suconfig, set our read timeout as super large for both DB migrations
# and awaiting for secrets to be updated.
proxy_read_timeout 2000;
}
# This block handles blob requests, and will receive a high volume of traffic, so we set the burst
# much higher.
location ~ /v2/([^/]+)\/[^/]+/blobs/ {
# If we're being accessed via v1.quay.io, pretend we don't support v2.
if ($host = "v1.quay.io") {
return 404;
}
# NOTE: We disable gzip for HEAD requests because Docker issues them to determine the Content
# Length of a blob. Unfortunately, nginx, seeing an empty body, overwrites the header with
# a length of 0, which breaks this functionality.
if ($request_method = HEAD) {
gzip off;
}
proxy_buffering off;
proxy_request_buffering off;
proxy_read_timeout 2000;
proxy_temp_path /tmp 1 2;
client_max_body_size {{ maximum_layer_size }};
# Setting ANY header clears all inherited proxy_set_header directives
proxy_set_header X-Forwarded-For $proper_forwarded_for;
proxy_set_header X-Forwarded-Proto $proper_scheme;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_pass http://registry_app_server;
set $namespace $1;
{% if enable_rate_limits %}
limit_req zone=namespaced_dynamicauth_light_http1 burst=50 nodelay;
limit_req zone=namespaced_dynamicauth_light_http2 burst=100 nodelay;
{% endif %}
keepalive_timeout 0; # Disables HTTP 1.1 keep-alive and forces round-robin.
}
# This block handles tags endpoint requests, for which we want to restrict traffic due to how
# heavy an operation it can be
location ~ /v2/([^/]+)\/[^/]+/tags/ {
# If we're being accessed via v1.quay.io, pretend we don't support v2.
if ($host = "v1.quay.io") {
return 404;
}
# Setting ANY header clears all inherited proxy_set_header directives
proxy_set_header X-Forwarded-For $proper_forwarded_for;
proxy_set_header X-Forwarded-Proto $proper_scheme;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_pass http://registry_app_server;
set $namespace $1;
{% if enable_rate_limits %}
limit_req zone=namespaced_dynamicauth_heavy_http1 burst=2 nodelay;
limit_req zone=namespaced_dynamicauth_heavy_http2 burst=2 nodelay;
{% endif %}
keepalive_timeout 0; # Disables HTTP 1.1 keep-alive and forces round-robin.
}
# This block handles manifests endpoint requests, for which we want to restrict traffic heavier than
# the generic V2 operations, as it handles pushes and pulls.
location ~ /v2/([^/]+)\/[^/]+/manifests/ {
# If we're being accessed via v1.quay.io, pretend we don't support v2.
if ($host = "v1.quay.io") {
return 404;
}
# Setting ANY header clears all inherited proxy_set_header directives
proxy_set_header X-Forwarded-For $proper_forwarded_for;
proxy_set_header X-Forwarded-Proto $proper_scheme;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_pass http://registry_app_server;
set $namespace $1;
{% if enable_rate_limits %}
limit_req zone=namespaced_dynamicauth_light_http1 burst=10 nodelay;
limit_req zone=namespaced_dynamicauth_light_http2 burst=50 nodelay;
{% endif %}
keepalive_timeout 0; # Disables HTTP 1.1 keep-alive and forces round-robin.
}
# This block applies to the beginning of a push or pull
location = /v2/auth {
# If we're being accessed via v1.quay.io, pretend we don't support v2.
if ($host = "v1.quay.io") {
return 404;
}
# Setting ANY header clears all inherited proxy_set_header directives
proxy_set_header X-Forwarded-For $proper_forwarded_for;
proxy_set_header X-Forwarded-Proto $proper_scheme;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_pass http://registry_app_server;
{% if enable_rate_limits %}
limit_req zone=staticauth burst=2 nodelay;
{% endif %}
keepalive_timeout 0; # Disables HTTP 1.1 keep-alive and forces round-robin.
}
# This block handles all other V2 requests, for which we can use a higher rate limit.
location ~ ^/v2 {
# If we're being accessed via v1.quay.io, pretend we don't support v2.
if ($host = "v1.quay.io") {
return 404;
}
# NOTE: We disable gzip for HEAD requests because Docker issues them to determine the Content
# Length of a blob. Unfortunately, nginx, seeing an empty body, overwrites the header with
# a length of 0, which breaks this functionality. Included here for completeness.
if ($request_method = HEAD) {
gzip off;
}
# Setting ANY header clears all inherited proxy_set_header directives
proxy_set_header X-Forwarded-For $proper_forwarded_for;
proxy_set_header X-Forwarded-Proto $proper_scheme;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_pass http://registry_app_server;
{% if enable_rate_limits %}
limit_req zone=dynamicauth_very_light_http1 burst=20 nodelay;
limit_req zone=dynamicauth_very_light_http2 burst=80 nodelay;
{% endif %}
keepalive_timeout 0; # Disables HTTP 1.1 keep-alive and forces round-robin.
}
location /v1/ {
# Setting ANY header clears all inherited proxy_set_header directives
proxy_set_header X-Forwarded-For $proper_forwarded_for;
proxy_set_header X-Forwarded-Proto $proper_scheme;
proxy_set_header Host $host;
proxy_buffering off;
proxy_request_buffering off;
proxy_http_version 1.1;
proxy_pass http://registry_app_server;
proxy_temp_path /tmp 1 2;
client_max_body_size {{ maximum_layer_size }};
{% if enable_rate_limits %}
limit_req zone=dynamicauth_heavy_http1 burst=5 nodelay;
limit_req zone=dynamicauth_heavy_http2 burst=25 nodelay;
{% endif %}
keepalive_timeout 0; # Disables HTTP 1.1 keep-alive and forces round-robin.
}
location = /v1/_ping {
add_header Content-Type text/plain;
add_header X-Docker-Registry-Version 0.6.0;
add_header X-Docker-Registry-Standalone 0;
return 200 'true';
}
location /c1/ {
proxy_buffering off;
proxy_request_buffering off;
proxy_pass http://verbs_app_server;
proxy_temp_path /tmp 1 2;
{% if enable_rate_limits %}
limit_req zone=staticauth burst=5 nodelay;
{% endif %}
}
location /static/ {
# checks for static file, if not found proxy to app
alias {{static_dir}}/;
error_page 404 /404;
}
error_page 502 {{static_dir}}/502.html;
location ~ ^/b1/controller(/?)(.*) {
proxy_pass http://build_manager_controller_server/$2;
}
location ~ ^/b1/socket(/?)(.*) {
proxy_pass http://build_manager_websocket_server/$2;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 300;
}