OPNsense Forum

Archive => 23.7 Legacy Series => Topic started by: oleg on December 09, 2023, 04:27:19 PM

Title: Nginx -> HTTP server -> Real IP Source
Post by: oleg on December 09, 2023, 04:27:19 PM
Cannot disable setting of special Forward headers for Nginx -> HTTP server ->  Real IP Source.
Even if to choose None, they are still present.

I'm talking about these ones:

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_set_header X-Forwarded-Port $server_port;                             
proxy_set_header X-Forwarded-Host $host;   


My goal is to set my own values, but i cannot override them, because any `proxy_set_header` direcitve which is set in `GUID_post/*.conf` just adds new header, not override it.
This inability brakes my proxy logic. Maybe I miss something, or it is just isn't possible, but (I repeat myself) parameter 'None' for 'Real IP Source' does'n disable 'X-Real-IP' and 'X-Forwarded-' headers.

Is there a possibility to set own headers (or values) for the ones mentioned before?
Title: Re: Nginx -> HTTP server -> Real IP Source
Post by: Fright on December 09, 2023, 09:02:33 PM
Quoteparameter 'None' for 'Real IP Source' does'n disable 'X-Real-IP' and 'X-Forwarded-' headers
Real IP Source field defines 'real_ip_header' directive value. not the 'proxy_set_header'
https://github.com/opnsense/plugins/blob/d714e8fc24b233c93556c16c33ac17f26b2cfde1/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/http.conf#L152-L159


at the moment, the mentioned headers are hardcoded and uses widely used values (it is not clear from the question whether it is worth making a request to change this)
https://github.com/opnsense/plugins/blob/d714e8fc24b233c93556c16c33ac17f26b2cfde1/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/location.conf#L163-L167
Title: Re: Nginx -> HTTP server -> Real IP Source
Post by: oleg on December 09, 2023, 09:54:15 PM
The use case is quite simple. Just try to make NAT forwarding to the nginx. And you receive wrong Port or/and IP.
This is just my case. My backend server use that headers for dynamic modifications of sources' URI's.
It would be nice to have a possibility (at least using a pre/post configs) to handle the situation when you need to change the hardcoded values.
Title: Re: Nginx -> HTTP server -> Real IP Source
Post by: Fright on December 09, 2023, 09:59:32 PM
became clearer but only partially  ;)
What values do you set for these headers in this case (and how do you get the real IP)?
Title: Re: Nginx -> HTTP server -> Real IP Source
Post by: oleg on December 11, 2023, 09:18:05 AM
e.g. nginx listens on 127.0.0.1:1443, but the real IP and PORT the request is come to is 10.x.x.x:433 (over the NAT).
And for such a case i set OUTER ip/port -- X-Forwarded-Port : 443, and for ip something like
X-Forwarded-For 10.x.x.x, $proxy_add_x_forwarded_for;
Title: Re: Nginx -> HTTP server -> Real IP Source
Post by: Fright on December 11, 2023, 07:01:36 PM
Ah! I think this is an incorrect use of the XFF header (intended to convey the client address)
but you can try to use the headers-more module directives (https://github.com/openresty/headers-more-nginx-module#more_set_input_headers) in _post-hooks to replace 'standard' headers.
Headers More module should be enabled at Global HTTP Settings for this
Title: Re: Nginx -> HTTP server -> Real IP Source
Post by: oleg on January 09, 2024, 12:47:24 PM
> I think this is an incorrect use of the XFF header (intended to convey the client address)

I try to transfer not the client address, but the correct server address to the underlying backend.
I also tried headers-more module.
I is enabled in Nginx -> General Settings -> Global HTTP settings.
Then i found UUID in /usr/local/etc/nginx/nginx.conf for my server.

Part of config

server {                                                                       
  listen 127.0.0.1:1080;                                                     
  server_name  my.server.address;
 
  include feecb877-0831-4efa-8005-e26b0dde555f_pre/*.conf;

location  / {                                                                   
     BasicRule wl:19;                                                           
     DeniedUrl "/waf_denied.html";                                               
     autoindex off;                                                             
     http2_push_preload on;                                                     
     proxy_set_header Host $host;                                               
     proxy_http_version 1.1;                                                     
     proxy_set_header Upgrade $http_upgrade;                                     
     proxy_set_header Connection $connection_upgrade;                           
     proxy_buffer_size 8k;                                                       
     proxy_buffers 8 8k;                                                         
     proxy_busy_buffers_size 32k;                                               
     proxy_set_header X-TLS-Cipher $ssl_cipher;                                 
     proxy_set_header X-TLS-Protocol $ssl_protocol;                             
     proxy_set_header X-TLS-SNI-Host $ssl_server_name;                           
     # proxy headers for backend server                                         
     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_set_header X-Forwarded-Port $server_port;                             
     proxy_set_header X-Forwarded-Host $host;                                   
     proxy_set_header X-TLS-Client-Intercepted $tls_intercepted;                 
     proxy_read_timeout 10s;                                                     
     proxy_send_timeout 10s;                                                     
     proxy_ignore_client_abort on;                                               
     proxy_request_buffering on;                                                 
     proxy_max_temp_file_size 1024m;                                             
     proxy_buffering on;                                                         
     proxy_pass http://upstream5fa240aef8aa4a9f895a4959a40bbbbb;                 
     proxy_hide_header X-Powered-By;                                             
     include 9370ea92-2ab9-45b4-b244-ceb86baa2887_post/*.conf;                   
   }     
  include feecb877-0831-4efa-8005-e26b0dde555f_post/*.conf;
}


I created files:

/usr/local/etc/nginx/feecb877-0831-4efa-8005-e26b0dde555f_pre/myheaders.conf
/usr/local/etc/nginx/9370ea92-2ab9-45b4-b244-ceb86baa2887_post/myheaders.conf
/usr/local/etc/nginx/feecb877-0831-4efa-8005-e26b0dde555f_post/myheaders.conf


The content is quite simple -- one line:

more_set_input_headers 'X-Forwarded-Port: 80';


Then I restarted nginx and tried simple request via curl. Aaaand it doesn't work. I still continue to receive X-Forwarded-Port: 1080.
Title: Re: Nginx -> HTTP server -> Real IP Source
Post by: oleg on January 09, 2024, 01:25:22 PM
I think it would be better to allow to set/override the values for X-Forwarded- header over GUI at least in config.
For now it doesn't work.
Title: Re: Nginx -> HTTP server -> Real IP Source
Post by: Fright on January 26, 2024, 07:05:28 PM
ah, sorry. my bad.
'more_set_input_headers' will not work in this case, since XFF not arrived from upstream proxy. but set by nginx instance itself.. oops
in this case, I see the only way out is to use a truly custom X- header (say, X-Requested-IP) and set it via hooks or configure the whole location via server _post-hook?
Title: Re: Nginx -> HTTP server -> Real IP Source
Post by: oleg on February 02, 2024, 02:38:26 PM
It will work only if you have the full control over the server code in order to change it behavior so that it starts working with the new header.
But all ready products use the standard headers.

I don't know the actual architecture of opnsense, but I don't understand what is the core problem to add the possibility for configuration X-Forwarded headers. Let it be some checkbox -- use default behavior / use custom behavior (over pre/post files)
Title: Re: Nginx -> HTTP server -> Real IP Source
Post by: oleg on February 08, 2024, 11:40:02 PM
It would be nice to have some  working approach that can survive system reboots and configuration updates via GUI.
Maybe some of OPNsense developers have an idea?
Title: Re: Nginx -> HTTP server -> Real IP Source
Post by: Fright on March 12, 2024, 02:41:15 PM
I'll answer again in this thread so as not to interfere in a new one (https://forum.opnsense.org/index.php?topic=39391.0).
-in my opinion, this is an incorrect use of de-facto standard headers (and imho there are other ways to achieve the desired result without violating the standards)
-you could use your own headers for this setup
-a request for such changes has little chance of being merged imho
-you always have the option to use a completely hand-written Location (with the desired headers) and use it withe GUI-configured server via server _post-hook
Title: Re: Nginx -> HTTP server -> Real IP Source
Post by: oleg on May 28, 2024, 03:45:44 PM
to Fright
I didn't agree with some parts of your conclusions:

- this is an incorrect use of de-facto standard headers
These headers are intended to show the client where the original server/proxy resides in a heterogeneous systems. I don't have anything super special. Just a NUT with port forwarding.

-you could use your own headers for this setup
No, I can't. You are talking about some abstract suggestion, that 3rd party product somehow should handle non-standard headers. While we already have the de-facto standard headers for this purpose.

-you always have the option to use a completely hand-written Location (with the desired headers) and use it withe GUI-configured server via server _post-hook
Does it survive the update/upgrade of OPNsense? I mean -- is this a standard way for OPNsense?

-a request for such changes has little chance of being merged imho
What are the changes your are talking? Maybe we look at this problem from different points?
My suggestion is just give a possibility to the user switch on/off the logic of OPNsense, where it adds these headers. Just on/off -- no more.


Title: Re: Nginx -> HTTP server -> Real IP Source
Post by: Fright on May 28, 2024, 06:01:26 PM
Hi.
-These headers are intended to show the client where the original server/proxy resides in a heterogeneous systems
I still don't understand why you think using an XFF header in the '<arbitrary_external_server_address>, $proxy_add_x_forwarded_for' format satisfies the standard way if it assumes the '<client>, <proxy1>, <proxy2>' format.
if there was no NAT in front of the nginx, the external address of the plugin would also not be included in this header

-No, I can't. You are talking about some abstract suggestion..
It would be more accurate to say not a non-standard header, but non-standard requirements?

-Does it survive the update/upgrade of OPNsense? I mean -- is this a standard way for OPNsense?
This is certainly not the preferred method (preferably all settings are available in the UI) but it is included in the plugin templates. and yes, it will survive the reboot\update\upgrade.

I'm not a plugin maintainer, so feel free to ignore my assumptions  :) I just believe that changes requests should be motivated and I understand that I would not come up with enough justification for the maintainer to accept my arguments in this case
Title: Re: Nginx -> HTTP server -> Real IP Source
Post by: Monviech (Cedrik) on May 28, 2024, 06:42:23 PM
Maybe the os-caddy plugin fits your needs. You can manipulate the up and downstream headers in any way you wish from the GUI.

https://github.com/opnsense/plugins/blob/master/www/caddy/src/opnsense/mvc/app/controllers/OPNsense/Caddy/forms/dialogHeader.xml

Any amount of these custom header manipulations can be set per location.
Title: Re: Nginx -> HTTP server -> Real IP Source
Post by: oleg on June 06, 2024, 11:58:12 AM
To Fright
Quote
I still don't understand why you think using an XFF header in the '<arbitrary_external_server_address>, $proxy_add_x_forwarded_for' format satisfies the standard way if it assumes the '<client>, <proxy1>, <proxy2>' format.
if there was no NAT in front of the nginx, the external address of the plugin would also not be included in this header

Look at this from the point of usage. If this is the only behavior that is intended, then why give the option of configuration at all for these headers? Right? They can be nailed to one option then.
"You can buy a car of any color as long as it is black." (ะก)  ;)

Anyway -- the flexibility is ensured by configurability.
Title: Re: Nginx -> HTTP server -> Real IP Source
Post by: oleg on June 06, 2024, 12:12:15 PM
To Monviech
Quote
Maybe the os-caddy plugin fits your needs.

Did I undrestand correct, that it require from me to move all the configuration from nginx to the new http-server? It sounds quite complex task, because I use nginx not only on OPNsense side but in my local environment too.
I think it worth considering, but also requires to weigh everything -- it may take time and effort for migration.
Anyway, thanks for suggestion.
Title: Re: Nginx -> HTTP server -> Real IP Source
Post by: Monviech (Cedrik) on June 06, 2024, 12:46:42 PM
A plugin can evolve over time, at some point it can become so complex that changes that are considered small can take an immense effort to implement.

In caddy, I could choose between "configuring headers with a checkbox" or "offering maximum freedom with headers".

Since I have seen that headers are one of the number one topics anywhere in reverse proxies and http servers, I have opted for maximum flexibility approach.

Plugins like nginx might not have this chance anymore that I had here while creating a new plugin based on a different webserver.

Though, other parts in os-caddy might lack the freedom of os-nginx. There is no one gui to rule them all.

Complaining too much (at os-nginx) won't change much here. It needs contributers since it is community maintained.