I have problem with normalizing Accept-Encoding, during tests express server getting correctly normalized Accept-Encoding from nginx, but nginx didn't respect "Vary: Accept-Encoding" and when I send request with e.g. "Accept-Encoding: gzip, br" and "Accept-Encoding: gzip" I got 2 requests to express server, it should be only 1 request
nginx
proxy_cache_path /tmp/express_cache keys_zone=express_cache:10m levels=1:2 inactive=600s max_size=100m;
map $http_accept_encoding $pwa_normalized_encoding {
default "";
"~*gzip" "gzip";
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
set $pass_access_scheme $scheme;
set $pass_server_port $server_port;
set $best_http_host $http_host;
set $pass_port $pass_server_port;
location /express {
proxy_set_header Host $best_http_host;
proxy_set_header X-Forwarded-Host $best_http_host;
proxy_set_header X-Forwarded-Port $pass_port;
proxy_set_header X-Forwarded-Proto $pass_access_scheme;
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Scheme $pass_access_scheme;
proxy_set_header X-Original-Forwarded-For $http_x_forwarded_for;
proxy_cache express_cache;
proxy_cache_lock on;
proxy_cache_background_update on;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_min_uses 1;
proxy_set_header Accept-Encoding $pwa_normalized_encoding;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://localhost:5000/;
}
}
express server
app.get('/', (req, res) => {
console.log("encoding:", new Date().toISOString(), (req.get("Accept-Encoding")));
res.setHeader("Cache-Control", "public, max-age=30");
res.setHeader('Content-Type', 'application/json')
res.setHeader("Vary", "Accept-Encoding");
setTimeout(() => {
res.json({date: new Date().toISOString()})
}, 300)
})
Related
I got the next 2 errors in console:
Access to XMLHttpRequest at 'https://api.domain1.com/rest/v1/reviews' from origin 'https://domain1.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
GET https://api.domain1.com/rest/v1/reviews net::ERR_FAILED 200
Network tab of Chrome's inspector shows a list of requests, but just 2 requests are relevant to my issue:
Name: reviews; Method: Options; Status 200; Type: preflight.
Name: reviews; Method: GET + Preflight; Status: CORS error; Type: xhr
My Nginx config:
proxy_cache_path /tmp/backend_cache levels=1:2 keys_zone=backend_cache:250m max_size=250m inactive=2d use_temp_path=off;
proxy_cache_key "$scheme$request_method$http_domain$host$request_uri";
proxy_cache_background_update on;
proxy_cache_lock on;
proxy_cache_lock_age 30s;
proxy_cache_revalidate on;
proxy_cache_valid 200 302 30m;
proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504;
upstream fastapi {
ip_hash;
server backend-fastapi:80;
}
server {
listen 80 default_server;
server_name api.domain1.com api.domain2.com;
charset utf-8;
keepalive_timeout 5;
location / {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 1m;
proxy_connect_timeout 1m;
proxy_pass http://fastapi;
proxy_cache backend_cache;
}
}
Preflight happens because I have custom header.
If I remove the line proxy_cache backend_cache; everything works without problem. Is there a way to use cache and avoid error?
the nginx config below the server
28081 always return 502, i config the proxy_next_upstream, but the request does not passed to next node (28082)
nginx version:1.19.3
upstream boot-server {
server 172.17.112.90:28081 weight=9;
server 172.17.112.90:28082 weight=1;
}
server {
listen 80 ;
server_name some.domain.com;
root /home/
location /v3/ {
proxy_pass http://boot-server;
proxy_next_upstream http_502 non_idempotent;
proxy_read_timeout 7200;
proxy_connect_timeout 5;
proxy_set_header Host $Host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Content-Type "application/json";
}
}
It seems that out of the box ngx_http_core_module should log request_body if it's part of the log_format.
However, Im not seeing this working for anything that includes auth_request in location block. Im not entirely sure what causes it. It appears to work fine for location blocks that do not include auth_request directive.
Typical the generated location block would look like,
server {
server_name test-api.dummy.co ;
listen 80 ;
listen 443 ssl http2 ;
set $proxy_upstream_name "-";
ssl_certificate_by_lua_block {
certificate.call()
}
proxy_pass_request_body on;
access_log /var/log/nginx/access.log custom_api_log;
location ~* "^/api/v2/management/customer/[a-zA-Z0-9-]+/" {
set $namespace "control";
set $ingress_name "apps-public-gateway-api-ig-auth";
set $service_name "istio-ingressgateway";
set $service_port "80";
set $location_path "/api/v2/management/customer/[a-zA-Z0-9-]+/";
rewrite_by_lua_block {
lua_ingress.rewrite({
force_ssl_redirect = true,
ssl_redirect = true,
force_no_ssl_redirect = false,
use_port_in_redirects = false,
})
balancer.rewrite()
plugins.run()
}
# be careful with `access_by_lua_block` and `satisfy any` directives as satisfy any
# will always succeed when there's `access_by_lua_block` that does not have any lua code doing `ngx.exit(ngx.DECLINED)`
# other authentication method such as basic auth or external auth useless - all requests will be allowed.
#access_by_lua_block {
#}
header_filter_by_lua_block {
lua_ingress.header()
plugins.run()
}
body_filter_by_lua_block {
}
log_by_lua_block {
balancer.log()
monitor.call()
plugins.run()
}
port_in_redirect off;
set $balancer_ewma_score -1;
set $proxy_upstream_name "control-istio-ingressgateway-80";
set $proxy_host $proxy_upstream_name;
set $pass_access_scheme $scheme;
set $pass_server_port $server_port;
set $best_http_host $http_host;
set $pass_port $pass_server_port;
set $proxy_alternative_upstream_name "";
# this location requires authentication
auth_request /_external-auth;
auth_request_set $auth_cookie $upstream_http_set_cookie;
add_header Set-Cookie $auth_cookie;
auth_request_set $authHeader0 $upstream_http_authorization;
proxy_set_header 'Authorization' $authHeader0;
# Cors Preflight methods needs additional options and different Return Code
if ($request_method = 'OPTIONS') {
more_set_headers 'Access-Control-Allow-Origin: https://test-portal.dummy.co';
more_set_headers 'Access-Control-Allow-Credentials: true';
more_set_headers 'Access-Control-Allow-Methods: GET, PUT, POST, DELETE, PATCH, OPTIONS';
more_set_headers 'Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
more_set_headers 'Access-Control-Max-Age: 3600';
more_set_headers 'Content-Type: text/plain charset=UTF-8';
more_set_headers 'Content-Length: 0';
return 204;
}
more_set_headers 'Access-Control-Allow-Origin: https://test-portal.dummy.co';
more_set_headers 'Access-Control-Allow-Credentials: true';
more_set_headers 'Access-Control-Allow-Methods: GET, PUT, POST, DELETE, PATCH, OPTIONS';
more_set_headers 'Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
client_max_body_size 1m;
proxy_set_header Host $best_http_host;
# Pass the extracted client certificate to the backend
# Allow websocket connections
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Request-ID $req_id;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $full_x_forwarded_proto;
proxy_set_header X-Forwarded-Host $best_http_host;
proxy_set_header X-Forwarded-Port $pass_port;
proxy_set_header X-Scheme $pass_access_scheme;
# Pass the original X-Forwarded-For
proxy_set_header X-Original-Forwarded-For $http_x_forwarded_for;
# mitigate HTTPoxy Vulnerability
# https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/
proxy_set_header Proxy "";
# Custom headers to proxied server
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_buffering off;
proxy_buffer_size 4k;
proxy_buffers 4 4k;
proxy_max_temp_file_size 1024m;
proxy_request_buffering on;
proxy_http_version 1.1;
proxy_cookie_domain off;
proxy_cookie_path off;
# In case of errors try the next upstream server before returning an error
proxy_next_upstream error timeout;
proxy_next_upstream_timeout 0;
proxy_next_upstream_tries 3;
proxy_pass http://upstream_balancer;
proxy_redirect http://test-api.dummy.co https://test-api.dummy.co;
}
}
Is this achievable via a Lua script perhaps if we cannot achieve this out of the box ?
And how to go about logging the response body without having a custom template for ingress-nginx controller ?
Thanks in advance.
I used Nginx as a reverse proxy and when I access the url from the browser (Chrome, Firefox) it will show 504 gateway timeout. But when I use curl or wget to access the url, it works fine. It is really a weird issue, can anyone give me some help?
Following is my configuration: https://pastebin.com/fZHEtRGa
The upstream configuration is:
upstream default-nginx-z-80 {
# Load balance algorithm; empty for round robin, which is the default
least_conn;
keepalive 32;
server 10.1.228.195:80 max_fails=0 fail_timeout=0;
}
The server configuration is
server {
server_name z-ingress.mixhub.cn ;
listen 80;
listen [::]:80;
set $proxy_upstream_name "-";
location / {
port_in_redirect off;
set $proxy_upstream_name "default-nginx-z-80";
set $namespace "default";
set $ingress_name "nginx-z";
set $service_name "";
client_max_body_size "1m";
proxy_set_header Host $best_http_host;
# Pass the extracted client certificate to the backend
proxy_set_header ssl-client-cert "";
proxy_set_header ssl-client-verify "";
proxy_set_header ssl-client-dn "";
# Allow websocket connections
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "";
proxy_set_header X-Real-IP $the_real_ip;
proxy_set_header X-Forwarded-For $the_real_ip;
proxy_set_header X-Forwarded-Host $best_http_host;
proxy_set_header X-Forwarded-Port $pass_port;
proxy_set_header X-Forwarded-Proto $pass_access_scheme;
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Scheme $pass_access_scheme;
# Pass the original X-Forwarded-For
proxy_set_header X-Original-Forwarded-For $http_x_forwarded_for;
# mitigate HTTPoxy Vulnerability
# https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/
proxy_set_header Proxy "";
# Custom headers to proxied server
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_redirect off;
proxy_buffering off;
proxy_buffer_size "4k";
proxy_buffers 4 "4k";
proxy_request_buffering "on";
proxy_http_version 1.1;
proxy_cookie_domain off;
proxy_cookie_path off;
# In case of errors try the next upstream server before returning an error
proxy_next_upstream error timeout invalid_header http_502 http_503 http_504;
proxy_pass http://default-nginx-z-80;
}
}
I've set up an Elasticsearch server with Kibana to gather some logs.
Elasticsearch is behind a reverse proxy by Nginx, here is the conf :
server {
listen 8080;
server_name myserver.com;
error_log /var/log/nginx/elasticsearch.proxy.error.log;
access_log off;
location / {
# Deny Nodes Shutdown API
if ($request_filename ~ "_shutdown") {
return 403;
break;
}
# Pass requests to ElasticSearch
proxy_pass http://localhost:9200;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
# For CORS Ajax
proxy_pass_header Access-Control-Allow-Origin;
proxy_pass_header Access-Control-Allow-Methods;
proxy_hide_header Access-Control-Allow-Headers;
add_header Access-Control-Allow-Headers 'X-Requested-With, Content-Type';
add_header Access-Control-Allow-Credentials true;
}
}
Everything works well, I can curl -XGET "myserver.com:8080" to check, and my logs come in.
But every minute or so, in the nginx error logs, I get that :
2014/05/28 12:55:45 [error] 27007#0: *396 connect() failed (111: Connection refused) while connecting to upstream, client: [REDACTED_IP], server: myserver.com, request: "POST /_bulk?replication=sync HTTP/1.1", upstream: "http://[::1]:9200/_bulk?replication=sync", host: "myserver.com"
I can't figure out what it is, is there any problem in the conf that would prevent some _bulk requests to come through ?
Seems like upstream and a different keepalive is necessary for the ES backend to work properly, I finally had it working using the following configuration :
upstream elasticsearch {
server 127.0.0.1:9200;
keepalive 64;
}
server {
listen 8080;
server_name myserver.com;
error_log /var/log/nginx/elasticsearch.proxy.error.log;
access_log off;
location / {
# Deny Nodes Shutdown API
if ($request_filename ~ "_shutdown") {
return 403;
break;
}
# Pass requests to ElasticSearch
proxy_pass http://elasticsearch;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
# For CORS Ajax
proxy_pass_header Access-Control-Allow-Origin;
proxy_pass_header Access-Control-Allow-Methods;
proxy_hide_header Access-Control-Allow-Headers;
add_header Access-Control-Allow-Headers 'X-Requested-With, Content-Type';
add_header Access-Control-Allow-Credentials true;
}
}