HOWTO insert custom headers - Nginx

Started by GreenMatter, September 13, 2020, 05:48:13 PM

Previous topic - Next topic
QuoteAnyway, are there any size limits for error logs?
https://github.com/opnsense/plugins/blob/master/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/newsyslog.conf

not set.
you can edit template and add size limit (in kilobytes)
but I really think it's not about the newsyslog settings. you need to look at the log and figure out what is the reason for so many errors.

September 18, 2020, 03:46:52 PM #16 Last Edit: September 18, 2020, 03:50:18 PM by GreenMatter
Quote from: Fright on September 18, 2020, 07:20:40 AM
QuoteAnyway, are there any size limits for error logs?
you can edit template and add size limit (in kilobytes)
but I really think it's not about the newsyslog settings. you need to look at the log and figure out what is the reason for so many errors.
Does it look sensible and correct (10000k)?

root@OPNsense:/usr/local/etc/nginx # cat /usr/local/opnsense/service/templates/OPNsense/Nginx/newsyslog.conf
# logfilename                   [owner:group]   mode    count size      when    flags   [/pid_file]               [sig_num]
{% if helpers.exists('OPNsense.Nginx') %}
/var/log/nginx/*access.log   www:www     640     14       10000      @T00     GZB      /var/run/nginx.pid       30
/var/log/nginx/*error.log   www:www     640     14       10000      @T00     GZB      /var/run/nginx.pid       30
{% endif %}

And you are right, I should investigate it further, but like I said, my main task was not to loose connection :-)
Anyway, currently error log for that particular upstream/server stays empty; maybe it was just one off glitch...
OPNsense on:
Intel(R) Xeon(R) E-2278G CPU @ 3.40GHz (4 cores)
8 GB RAM
50 GB HDD
and plenty of vlans ;-)

September 18, 2020, 03:53:06 PM #17 Last Edit: September 18, 2020, 04:16:05 PM by Fright
QuoteDoes it look sensible and correct (10000k)?
yep
Quotemy main task was not to loose connection :-)
agree )

I can't solve small issue: If I need an external access, I'm used to expose services running inside LAN on router's WAN interface but using random port numbers. Such port forwarding works fine but either upstream or Nginx keep rewriting random port to standard 443 and communication is lost. I mean when I have set forwarding i.e. port 4443 to 443: page https://server.domain.com:4443 gets rewritten after typing in logon credentials to https://server.domain.com/login and of course lost comms error is displayed. When I manually amend port to 4443 and and hit enter page is opened and user is logged in. Will "port_in_redirect off" in server block be permanent a solution? Any cons?
OPNsense on:
Intel(R) Xeon(R) E-2278G CPU @ 3.40GHz (4 cores)
8 GB RAM
50 GB HDD
and plenty of vlans ;-)

QuoteWill "port_in_redirect off" in server block be permanent a solution?
dont think so
Quotegets rewritten after typing in logon credentials to https://server.domain.com/login
look at backend logs for responses after user authentication. i think that authentication form in /login page redirects user to absolute url after authentication.
if so you can try proxy_redirect directive in location block
(http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect)
(https://stackoverflow.com/questions/20254456/intercepting-backend-301-302-redirects-proxy-pass-and-rewriting-to-another-loc)

September 22, 2020, 08:47:25 PM #20 Last Edit: September 22, 2020, 09:22:15 PM by GreenMatter
Quote from: Fright on September 22, 2020, 08:43:30 AMlook at backend logs for responses after user authentication. i think that authentication form in /login page redirects user to absolute url after authentication. if so you can try proxy_redirect directive in location block (http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect) (https://stackoverflow.com/questions/20254456/intercepting-backend-301-302-redirects-proxy-pass-and-rewriting-to-another-loc)
In general, I'm confused here. Since port forwarding is done by firewall (fw 4443<->443 Nginx), thus for Nginx it's transparent. But looking at curl reply, in header there's:
location: https://server.domain.com/login


I've tried in URL rewriting to set
Source: $scheme://server.domain.com:4443/(.*)$
Destination: $scheme://$http_host/$1
Flag: Redirect
and activate it in location but that doesn't change a bit.... Does $http_host contain domain and port?


EDIT:

Since firewall/NAT forwarding is transparent for Nginx, Nginx is not aware of port, client is communicating on, so in my humble opinion there's no way to change header in location response, neither using redirect nor proxy_redirect.... Unfortunately

OPNsense on:
Intel(R) Xeon(R) E-2278G CPU @ 3.40GHz (4 cores)
8 GB RAM
50 GB HDD
and plenty of vlans ;-)

September 22, 2020, 09:56:43 PM #21 Last Edit: September 25, 2020, 05:34:19 PM by Fright
now i'm confused again. who is listening to which port. firewall? nginx? backend?
you have another firewall in front of opnsense?
if nginx listening on 443 then $scheme://server.domain.com:4443/(.*)$ makes no sense <- erroneous assumption due to misunderstanding of the network diagram
QuoteDoes $http_host contain domain and port?
yes. should
Quoteno way to change header in location response
why? it should work imho. if after users auth backend server send 307 with location: https://server.domain.com/welcome.html,  proxy_redirect  will replace loaction with https://server.domain.com:4443/welcome.html for you. then client hit the 4443 port

Quote from: Fright on September 22, 2020, 09:56:43 PM
why? it should work imho. if after users auth backend server send 307 with location: https://server.domain.com/welcome.html,  proxy_redirect  will replace loaction with https://server.domain.com:4443/welcome.html for you. then client hit the 4443 port
Ok, I'm not good at all in proxy stuff :-)
Nginx listens on 443, firewall opens WAN port 4443 and forwards traffic to Nginx port 443.
So, if it's possible, can I somehow configure such redirect in webgui or I must go for hook file? Could you show example for above case?
OPNsense on:
Intel(R) Xeon(R) E-2278G CPU @ 3.40GHz (4 cores)
8 GB RAM
50 GB HDD
and plenty of vlans ;-)

QuoteNginx listens on 443, firewall opens WAN port 4443 and forwards traffic to Nginx port 443.
ok. it remains to understand which port the backend is listening to. and is there a url changing between user request and request from nginx to backend.
if the problem is only in the absence of a port in the redirect location then you can try

proxy_redirect https://server.domain.com/ https://server.domain.com:4443/;

I think it's better to start with explicit paths. if it works, you can pick up variables ($http_host or some)
Quotecan I somehow configure such redirect in webgui or I must go for hook file?
GUI does not contain this directive. use server or location hook
ps. I haven't checked it myself

Quote from: Fright on September 23, 2020, 07:43:58 AM
ok. it remains to understand which port the backend is listening to. and is there a url changing between user request and request from nginx to backend.
if the problem is only in the absence of a port in the redirect location then you can try

proxy_redirect https://server.domain.com/ https://server.domain.com:4443/;

Backend listens on port 80.
Above proxy_redirect works in location block, but how to make "if" statement to kick in redirect only when client makes request on port 4443 which in turn is transparent for Nginx since firewall forwards such request to Nginx... So, as you mentioned it must be based on redirect code 307 or 302? Otherwise LAN clients can't login using regular https port...
Below is curl request/response, it's 302 redirect and it's the same regardless request origin (LAN/WAN):
Quote* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 302 
< server: nginx
< date: Wed, 23 Sep 2020 23:59:15 GMT
< content-type: text/html; charset=UTF-8
< content-length: 0
< cache-control: no-store, no-cache, must-revalidate
< content-security-policy: default-src 'self'; script-src 'self' style-src 'self' 'unsafe-inline'; frame-src *; img-src * data: blob:; font-src 'self' data:; media-src *; connect-src *; object-src 'none'; base-uri 'self';
< location: https://server.domain.com/login
OPNsense on:
Intel(R) Xeon(R) E-2278G CPU @ 3.40GHz (4 cores)
8 GB RAM
50 GB HDD
and plenty of vlans ;-)

September 24, 2020, 08:49:19 AM #25 Last Edit: September 24, 2020, 08:53:18 AM by Fright
Quoteclient makes request on port 4443 which in turn is transparent for Nginx since firewall forwards such request to Nginx
actually I got confused in the network diagram and said a stupid thing. nginx is aware of the initial request (if firewall only redirects the port and does not change the request). so, as I said, if an explicit directive works, you can pick up variables. in theory it should work like this
proxy_redirect https://server.domain.com/ https://$http_host/;

there are other options: make nginx listen on two SSL ports (443 and 4443) and make firewall redirect publicIP:4443<->nginxIP:4443 and insert $server_port variable.
or change the redirect location depending on the client's address (geo directive).

Thanks @Fright!
It works well with proxy_redirect and independently from WAN port number. And it is such a simple solution...
My goal is to set services in OPNsense mainly via webgui for ease of future maintenance. I used to have USG 4 Pro from Ubiquiti but that gateway's  webgui functions were lacking seriously  - most of a bit more advanced functions, had to be configured via json file (including NAT, OpenVPN and so on).  8)


One more thing, is it possible to use WAF whitelist? I mean If I set it to allow matching requests, all other requests will be rejected?
OPNsense on:
Intel(R) Xeon(R) E-2278G CPU @ 3.40GHz (4 cores)
8 GB RAM
50 GB HDD
and plenty of vlans ;-)

glad it works!
Quoteis it possible to use WAF whitelist? I mean If I set it to allow matching requests, all other requests will be rejected?
yes, if I understood you correctly. you can use whitelist policies to exclude certain rules from applied policies