nginx removes content length http header after proxy_pass - http

I have a problem that nginx removes the content-length header after the proxy pass. the application back-end sends a gzip stream but specifies the content length. NGINX changes the type content-type to chunked and removes the content length header. This is not acceptable for the app since it is read not by the browser but by an proprietary app that requires the content-legth to be specified.
After specified chunked_transfer_encoding off; it stops adding the content type header but still removes the content length. How to disable any header modifications in nginx?
The confing:
upstream backend {
server 127.0.0.1:9090;
}
server {
root /usr/share/nginx/www;
index index.html index.htm;
chunked_transfer_encoding off;
location / {
proxy_pass http://backend;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering 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;
}
}

This was a known bug in nginx in the past. Update to the latest build.
http://forum.nginx.org/read.php?2,216085,216085#msg-216085

Related

Nginx isn't storing cache

I'm trying to allow nginx caching in the simplest form. But for some reason it's not working. I'm currently using nginx with gunicorn and flask on an ec2 instance.
This is my /etc/nginx/nginx.conf file:
user nginx;
...
proxy_cache_path /var/cache/nginx keys_zone=mycache:10m;
proxy_cache_methods GET HEAD POST;
server {
listen 80;
access_log /var/log/nginx/agori.access.log main;
error_log /var/log/nginx/agori.error.log;
location / {
proxy_set_header Host $http_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_cache mycache;
proxy_cache_valid any 48h;
proxy_buffering on;
proxy_pass http://unix:/home/ec2-user/src/project.sock;
}
}
when check the /var/cache/nginx folder, it's empty. These are the folders permissions:
drwxrwxrwx 2 nginx root 6 May 13 14:03 nginx
This is the request and respond headers:
PS: This is on mobile(ios)
It sounds to me that something in your Nginx config might not be correct (syntax error or not supported by your Nginx version). In most of the case I encountered so far that was the case for me.
You probably know Nginx' reverse proxy example which features the following configuration
http {
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=STATIC:10m inactive=24h max_size=1g;
server {
location / {
proxy_pass http://1.2.3.4;
proxy_set_header Host $host;
proxy_buffering on;
proxy_cache STATIC;
proxy_cache_valid 200 1d;
proxy_cache_use_stale error timeout invalid_header updating
http_500 http_502 http_503 http_504;
}
}
}
I tried to compare that with your configuration file and I my debugging approach would be:
Does nginx log your requests in access_log?
Try to remove whether the example configuration file works after minimal modifications.
Replace the any with a 200 for a start and see whether that works.
If that works, put in step by step all additional config lines like the proxy_cache_methods line.

How to make Jenkins accessible by hostname?

I created an Ubuntu 19.10 VirtualBox VM and installed installed there OpenJDK 8, Nginx 1.16.1, and Jenkins 2.222.1. I can access via HTTP IP address, like http://{IP_OF_THE_VM}:8080. Now I want also to be able to access it by the hostname like https://jenkins.ciserver.loc/.
Here is the VHost file /etc/nginx/sites-available/jenkins.ciserver.loc:
upstream jenkins {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name jenkins.ciserver.loc;
access_log /var/log/nginx/jenkins.access.log;
error_log /var/log/nginx/jenkins.error.log;
proxy_buffers 16 64k;
proxy_buffer_size 128k;
location / {
proxy_pass http://jenkins;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
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 https;
}
}
When I request http://ci.ciserver.loc in the browser, "This site can’t be reached" and the request end up in a ERR_SOCKET_NOT_CONNECTED.
How to configure Jenkins and/or Nginx correctly to make Jenkins accessible by the hostname?
SOLVED
It was a stupid typo... I set server_name to jenkins.ciserver.loc, but was all the time trying to request ci.ciserver.loc. Now I corrected the requested URL to http://jenkins.ciserver.loc -- and it started working.

Nginx: rewrite port in url from reverse proxie'd app

So I have set up a reverse proxy to tunnel my application.
Unfortunately the application thinks it is served via http and not https and gives out URLs with port 80.
How can I handle this in the nginx reverse proxy? (by rewriting maybe)
When I go on the page:
https://my.server.com
index.php loads, everything is okay
after clicking something I have a URL like this:
https://my.server.com:80/page/stuff/?redirect_to
which throws an error within the browser because my reverse proxy doesn't serve SSL on port 80.
How can I migitate this?
My current nginx ssl vhost for the site:
... ssl stuff ...
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
location / {
proxy_pass http://localhost:22228;
proxy_buffering off;
proxy_redirect off;
proxy_read_timeout 43800;
proxy_pass_request_headers on;
proxy_set_header Connection "Keep-Alive";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass_header Content-Type;
proxy_pass_header Content-Disposition;
proxy_pass_header Content-Length;
proxy_set_header X-Forwarded-Proto https;
}
(yes I know my request headers look like a christmas tree 🎄)
Also bonus points if you show where the documentation addressing this issue is and what the mechanism is called.
For rewriting response body you can use http_sub_module:
location / {
proxy_pass http://localhost:22228;
sub_filter_once off;
sub_filter_types text/css application/javascript; # in addition to text/html
sub_filter "//my.server.com:80/" "//my.server.com/";
}
Many people says (1, 2) that you need to disable compression when using sub_filter directive:
proxy_set_header Accept-Encoding "";
For me, it works fine without this line in config, but it can be a feature of OpenResty which I use instead of nginx.
If your app generates HTTP 30x redirects with explicit indication of domain:port, you can rewrite Location header value with the proxy_redirect directive:
proxy_redirect //my.server.com:80/ //my.server.com/;

Routing a subdomain to a folder on another server via AWS route53

I have an EC2 Win2008 server running an ASP.NET 4.5 site www.mysite.com.
In the same AWS zone but another separate EC2 Linux server, I have an NginX/PHP Wordpress site running blog.mysite.com.
I would like to create an AWS Route53 route so that all incoming requests to www.mysite.com/blog get silently routed to blog.mysite.com WITHOUT a redirect so that the user's web browser stays on the URL www.mysite.com/blog
How would I achieve this with Route53? If not achievable with Route53, is there any other way?
I don't want to run PHP/MySQL/WordPress on my Windows server, unless I absolutely have to.
Thanks!
Only way is to put an Apache or nginx in front of both the site that is hosting your ASP.NET 4.5 app and your Wordpress site.
Then you can setup a reverse proxy on that server that makes that /blog path point to your Wordpress site and the / path point to your ASP.NET 4.5 app.
For nginx you would have something like this:
server {
listen 80;
server_name www.yourdomain.com;
access_log /var/log/nginx/log/www.yourdomain.access.log main;
error_log /var/log/nginx/log/www.yourdomain.error.log;
location /blog {
proxy_pass http://yourblogserver;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering 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;
}
location / {
proxy_pass http://youraspnet40server;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering 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;
}
}
Keep in mind that your /blog path has to be first in the priority otherwise all the requests will get sent to just /

Routing to different servers with nginx

Is there a way to use nginx as a router while keeping the requested domain in the URL? For example, if I hit mysite.com, the nginx routing server looks at the URL and directs traffic to a particular server, all while maintaining the original requested domain in the URL.
E.g.
mysite.com/site1/params
Router -> site1.mysite.com/params
But even though behind the scenes site1.mysite.com/params is being called, the user sees mysite.com/site1/params in the URL.
I've taken a stab at the configuration, but seem to be getting 404's.
upstream site1 {
server site1.mysite.com;
}
location /site1 {
rewrite ^(.*)$ /$1 break;
proxy_pass http://site1;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering 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;
}
Use location with trailing slash, remove rewrite and use proxy_pass with / uri. Nginx will take of replacing /site1/ with /. Also, you may need to set Host header to site1.mysite.com not the $host.
location /site1/ {
proxy_pass http://site1/;
proxy_set_header Host site1.mysite.com;
...
}

Resources