Nginx Web Server Reverse Proxy - nginx

I try to configure my Nginx load balancer. My configuration works but there is a behavior i can't understand.
As we can read i Nginx doc's:
"By default, NGINX redefines two header fields in proxied requests, “Host” and “Connection”..."
So, why Ngnix redefines this two headers and don't pass them by default?
I feel that it can be important behavior to understand but i don't know where to find an answer :)
To understand why Nginx redefines "host" and "connection" headers and don't pass them by default.

Related

Confusing on Forwarded header

The new standard for headers (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded) is confusing to me. I also tried reading the specification (https://datatracker.ietf.org/doc/html/rfc7239#section-4) and it's equally as confusing.
I have a basic configuration like this:
client -> ingress (load balancer) -> reverse proxy -> service
The Forwaded header defines four fields as follows:
by - The interface where the request came in to the proxy server.
for - The client that initiated the request and subsequent proxies in a chain of proxies.
host - The Host request header field as received by the proxy.
proto - Indicates which protocol was used to make the request (typically "http" or "https").
What would each of these be set to in my case (excluding proto, that one is obvious)? The "for" seems to just be the client host, but then then I don't understand what it means by a "chain of proxies". I don't think it applies in my example, but I still want to understand.
My proxy has a registry that looks up all of my services, so as of now, I set this header inside the proxy. Is that where it is intended to be set? Thanks to anyone who can answer in advance.
I am not aware of any Kubernetes Ingress Controller that implements this header. X-Forwarded-For and X-Forwarded-Proto are what basically everything uses.

What is the correct way to render absolute URLs behind a reverse proxy?

I have a web application running on a server (let's say on localhost:8000) behind a reverse proxy on that same server (on myserver.example:80). Because of the way the reverse proxy works, the application sees an incoming request targeted at localhost:8000 and the framework I'm using therefore tries to generate absolute URLs that look like localhost:8000/some/ressource instead of myserver.example/some/ressource.
What would be "the correct way" of generating an absolute URL (namely, determining what hostname to use) from behind a proxy server like that? The specific proxy server, framework and language don't matter, I mean this more in an HTTP sense.
From my initial research:
RFC7230 explicitly says that proxies MUST change the Host header when passing the request along to make it look like the request came from them, so it would look like using Host to determine what hostname to use for the URL, yet in most places where I have looked, the general advice seems to be to configure your reverse proxy to not change the Host header (counter to the spec) when passing the request along.
RFC7230 also says that "request URI reconstruction" should use the following fields in order to find what "authority component" to use, though that seems to also only apply from the point-of-view of the agent that emitted that request, such as the proxy:
Fixed URI authority component from the server or outbound gateway config
The authority component from the request's firsr line if it's a complete URI instead of a path
The Host header if it's present and not empty
The listening address or hostname, alongside with the incoming port number if it's not the default one for the protocol
HTTP 1.0 didn't have a Host header at all, and that header was added for routing purposes, not for URL authority resolution.
There are headers that are made specifically to let proxies to send the old value of Host after routing, such as Via, Forwarded and the unofficial X-Forwarded-Host, which some servers and frameworks will check, but not all, and it's unclear which one should even take priority given how there's 3 of them.
EDIT: I also don't know whether HTTPS would work differently in that regard, given that the headers are part of the encrypted payload and routing has to be performed another way because of this.
In general I find it’s best to set the real host and port explicitly in the application rather than try to guess these from the incoming request.
So for example Jira allows you to set the Base URL through which Jira will be accessed (which may be different to the one that it is actually run as). This means you can have Jira running on port 8080 and have Apache or Nginx in front of it (on the same or even a different server) on port 80 and 443.

nginx Configuration to Modify Response Header Links

We are using nginx for load balancing and handling SSL of an API. Requests are forwarded to Tomcat instances. Since Tomcat does not use SSL, all hyperlinks that are provided by Tomcat use http rather than https.
We use module ngx_http_sub_module to modify all hyperlinks in the response body and replace http by https. This is working already.
However, all hyperlinks in the response header, for example in the Location or Link headers are not replaced.
Is there any other module that can be used for this purpose?
See the proxy_redirect directive. For more complicated proxying, getting this setting correct gets difficult, but for simpler cases their provided examples should prove illuminating.
I still haven't found a way to handle Link: headers reliably.

Atlasssian Crucible through AWS ELB with HTTPS

I've recently setup a Crucible instances in AWS connected via a HTTPS ELB. I have a nginx reverse proxy setup on the instance as well to redirect HTTP requests to HTTPS.
This partially works. However Crucible itself doesn't know it's running over HTTPS so serves up mixed content, and ajax queries often break due to HTTP -> HTTPS conflicts.
I've found documentation for installing a certificate in Crucible directly...
https://confluence.atlassian.com/fisheye/fisheye-ssl-configuration-298976938.html
However I'd really rather not have to do it this way. I want to have the HTTPS terminated at the ELB, to make it easier to manage centrally through AWS.
I've also found documentation for using Crucible through a reverse proxy...
https://confluence.atlassian.com/kb/proxying-atlassian-server-applications-with-apache-http-server-mod_proxy_http-806032611.html
However this doesn't specifically deal with HTTPS.
All I really need is a way to ensure that Crucible doesn't serve up content with hard coded internal HTTP references. It needs to either leave off the protocol, or set HTTPS for the links.
Setting up the reverse proxy configuration should help accomplish this. Under Administration >> Global Settings >> Server >> Web Server set the following:
Proxy scheme: https
Proxy host: elb.hostname.com
Proxy port: 443
And restart Crucible.
Making configuration on UI is one way. You can also change config.xml in $FISHEYE_HOME:
<web-server site-url="https://your-public-crucible-url">
<http bind=":8060" proxy-host=“your-public-crucible-url" proxy-port="443" proxy-scheme="https"/>
</web-server>
Make sure to shutdown FishEye/Crucible before making this change.
AFAIK, this configuration is the only way to tell internal Jetty of FishEye/Crucible to be aware of the reversed proxy in front of them.

Nginx Reverse Proxy to Remote Server

Okay, so I know there is a lot of questions about Nginx Reverse Proxy but I don't understand any of the answers. I read the documentation on Nginx's website and I kind of get it but need some help.
So here is what I want.
Visitor ---> Nginx Reverse Proxy ---> Nginx Server (Website)
I know that you can get the reverse proxy to listen to a remote server, but I can't find the configuration files that I want. I also want to show a static html page when passing through the Nginx Reverse Proxy. So like a page that says "Hosted by this company", like Cloudflare does. I asked someone and they told me if I put the html file on the reverse proxy server then it'll show up when the visitor goes through the server, but I don't understand that concept, how do I get that static html to show up? And what will be the correct configuration be for this? I imagine it'll be different from a normal remote server configuration.
Thanks in advance!
In Nginx reverse proxy configuration it is possible to make some urls to be served from reverse proxy itself without going to source server.
Take a look at the following article: https://www.cevapsepeti.com/how-to-setup-nginx-as-reverse-proxy-for-wordpress/
In this article you can see in virtual.conf lines 51-55 that error_pages are served directly from reverse proxy, while other assets are fetched from source server first. Cloudflare employs the same concept. I hope this helps.

Resources