HOWTO insert custom headers - Nginx

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

Previous topic - Next topic

As I've almost hijacked already solved thread (https://forum.opnsense.org/index.php?topic=16595.0) I'm copying over here the last and the most fruitful :-) answer:


Quote from: Fright on September 13, 2020, 07:22:52 AM
QuoteWhere to find location.conf, somewhere within "/usr/local/etc/nginx"?
/usr/local/opnsense/service/templates/OPNsense/Nginx/..
QuoteStill I'm not able to locate separate config file where I could enter missing headers and include in main config..
in the end of location.conf right before last brace insert new hook.
so before:
{% endif %}{# honeypot #}


}

after:
{% endif %}{# honeypot #}
    include {{ location['@uuid'] }}_post/*.conf;
}



go the GUI and apply nginx config (not reload, apply. so opnsense apply new location.conf)
go to the
/usr/local/etc/nginx/nginx.conf and be sure that at the end of location blocks there is a line like:
    include 248efebe-d2e2-401b-b93f-f4d9061bb18c_post/*.conf;


if so, you can create folder like "248efebe-d2e2-401b-b93f-f4d9061bb18c_post" in /usr/local/etc/enginx/,
place a file like "mylocationname.conf" with your directives and Apply nginx conf.
imo that shoud work, (I checked and replaced User-agent header via the hook. works:
set $new_user_agent "${http_user_agent} via nginx";
proxy_set_header User-Agent $new_user_agent;
)
at any step, something can go wrong. always make a backup




And now I have a few questions. Are all of these changes persistent across upgrades?


And in web UI, in location we can enable websocket (proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $proxy_connection;)
but if I need to have them in "overall" section as per recipe (https://www.onlyoffice.com/blog/2020/01/how-to-configure-reverse-proxy-for-nextcloud-and-onlyoffice-editors/):
Quote
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
proxy_set_header X-Forwarded-Host $http_host/editors;
server {
        listen 80;
        location / {
            proxy_pass_header Server;
            proxy_pass http://nextcloud/;
        }
        location /editors/ {
            proxy_pass http://onlyoffice/;
        }
}
Does it make practical difference whether they are in location section or above?
OPNsense on:
Intel(R) Xeon(R) E-2278G CPU @ 3.40GHz (4 cores)
8 GB RAM
50 GB HDD
and plenty of vlans ;-)

September 13, 2020, 06:27:24 PM #1 Last Edit: September 13, 2020, 07:32:43 PM by Fright
QuoteAre all of these changes persistent across upgrades?
nope. upgrade of nginx plugin will overwrite location.conf. so it will need to be restored (but i hope that @fabian will include location _post conf hook in next version. and may be it will use same foldername syntax ))
QuoteDoes it make practical difference whether they are in location section or above?
no. location part will work.  "overall" section is used just in order not to write it in all locations
imho location is the right place for proxy_set_header directive.
you can set proxy_set_header directive globally. but afaik global  proxy_set_header directive will apply to location only if there is no other proxy_set_header directives in location block. so there is a chance that global proxy_set_header will not work in our case and you still have to add it to location

Quote from: Fright on September 13, 2020, 06:27:24 PM
nope. upgrade of nginx plugin will overwrite location.conf. so it will need to be restored (but i hope that @fabian will include this hook in next version. and may be it will use same foldername syntax ))
If I'm right, there are already built-in hooks in "server's" section, so it might be the same for "location"?
But :-), wouldn't it have been better to have in web GUI, let's say in Advanced view (server and location), an option to add headers manually, by typing them in? As same as it is in OpenVPN server configuration... If I may suggest it.
OPNsense on:
Intel(R) Xeon(R) E-2278G CPU @ 3.40GHz (4 cores)
8 GB RAM
50 GB HDD
and plenty of vlans ;-)

Quoteso it might be the same for "location"?
"include {{ location['@uuid'] }}_post/*.conf;" is )
Quotean option to add headers manually, by typing them in?
don't think so. ideally, there should be no "free" fields in GUI config
read "Safeguard user input"
https://docs.opnsense.org/development/guidelines/basics.html
so I highly doubt that such a request will not be declined

I have an idea about using hook and GUI, but I have a feeling that I have already tired the team with my requests and ideas)

Quote from: Fright on September 13, 2020, 08:14:37 PM

don't think so. ideally, there should be no "free" fields in GUI config
read "Safeguard user input"
https://docs.opnsense.org/development/guidelines/basics.html
so I highly doubt that such a request will not be declined

I have an idea about using hook and GUI, but I have a feeling that I have already tired the team with my requests and ideas)
Ok, understand it. Thus in perfect world we should have all in GUI named as headers are or alternatively, in their description  8)
OPNsense on:
Intel(R) Xeon(R) E-2278G CPU @ 3.40GHz (4 cores)
8 GB RAM
50 GB HDD
and plenty of vlans ;-)

September 13, 2020, 09:11:17 PM #5 Last Edit: September 13, 2020, 09:17:45 PM by Fright
why only headers?
nginx has a huge number of directives  ;D
and if each of them try to include in GUI and to validate each one before adding it to the configuration, then the head will burst.
therefore hooks are added i think  ;)



You must be right, I'm not a pro!


Anyway I have problem with URI to location matching. For example I want to open page being behind proxy https://mysubdomain.mydomain.com/onlyoffice


HTTPS server name is mysubdomain.mydomain.com
Location URL Pattern is /onlyoffice
URL Path Prefix / or empty


I can't access page, error 404.


But once I change location to root folder
HTTPS server name is onlyoffice.mydomain.com
Location URL Pattern is /
URL Path Prefix /


I'm able to access it through proxy, what am I doing wrong?

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

it looks more like a nginx question than opnsense one.
but tell more detail what the user is typing, what the request to the upstream should be (perhaps url rewrite is required).
in first and second cases you use different server names..
details of 404 errors can be viewed in the "HTTP Error Logs"

Quote from: Fright on September 14, 2020, 07:52:02 AM
it looks more like a nginx question than opnsense one.
but tell more detail what the user is typing, what the request to the upstream should be (perhaps url rewrite is required).
in first and second cases you use different server names..
details of 404 errors can be viewed in the "HTTP Error Logs"
I gave up because https://stackoverflow.com/questions/36120467/nginx-not-matching-location-i-think
Problem there was same as mine. When location's name was: /onlyoffice/ and proxy_pass ended or URL Path Prefix  with "/" it resulted with URI being added to server name (host) what caused error. Otherwise I ended up with other location /.
So I simply created another server and added location onlyoffice as "/" - root block.
BTW, is there any way/fancy redirections to achieve what I wanted initially? I mean one server with root location and other, "URI" locations being opened at their respective root folders...?
OPNsense on:
Intel(R) Xeon(R) E-2278G CPU @ 3.40GHz (4 cores)
8 GB RAM
50 GB HDD
and plenty of vlans ;-)

I still cannot understand your task exactly. which address to redirect to.
the example given is not entirely relevant. they are considering using the proxy_pass directive. the plugin uses upstreams and we will not be able to control the full address directly from the proxy_pass directive.
Need an exact task, what do you want to direct where.
If you only need to "cut" folder from uri and proxy request to root of another server you can use url rewrite (im using it for webdav client support to overcome cookie auth problems)

September 15, 2020, 05:21:45 PM #10 Last Edit: September 15, 2020, 08:50:08 PM by GreenMatter
I'll try to describe it to my best :-)
Onlyoffice server is available via https://onlyoffice.mydomain.com
Upstream server is configured 172.16.1.20:5443
Upstream to use TLS and LE cert.

Nextcloud server is available via http://next.mydomain.com
Upstream server is configured 172.16.1.2:80
Upstream to do not use TLS

As nextcloud doesn't have SSL certificate (and onlyoffice prefers it) I need to use reverse proxy to connect them.
Under one server name I cannot(?) have 2 root locations, so nextcloud was root location and onlyoffice in subfolder/URI.
And problem is/was that when proxying onlyoffice, its page was either not redirected at all (request went to root location) or redirected as 172.16.1.20:5443/onlyoffice (proxy hostname next.mydomain.com/onlyoffice) which doesn't exist. Request must goes to (location) root folder of onlyoffice server. I guessed I would need to use rewrite or redirection to achieve that but I couldn't find a solution..
OPNsense on:
Intel(R) Xeon(R) E-2278G CPU @ 3.40GHz (4 cores)
8 GB RAM
50 GB HDD
and plenty of vlans ;-)

September 15, 2020, 09:53:32 PM #11 Last Edit: September 15, 2020, 10:01:54 PM by Fright
that is, if I understand correctly, you want the user to go to one address (next.mydomain.com), and by going to /onlyoffice/.. to see the content from the site onlyoffice.mydomain.com. and whether it can be implemented using nginx.
Yes and no.
nginх will rewrite the url without a problem and send a request to another server (so request to next.mydomain.com/onlyoffice/foo goes to onlyoffice.mydomain.com/foo).
the question is what's next. if there is only a file in folder - no problem (for example, next.mydomain.com/onlyoffice/mydocfile.doc request will work). but if there is a page (like /onlyoffice/index.html) and it contains, for example, a picture (<img src = "/themes/OPNsense/assets/img/opnsense.png">) -  thats all. end of the story. browser will attach a relative path to the server address and will request a picture without "/onlyoffice/" part. and request will go to the first server.
of course you can try to work around this with $http_referer (check referer and route request to onlyoffice if referer contains "onlyoffice"),  but this requires testing and will not necessarily work smooth.
in short, if it is necessary for this to work stably, then it is necessary to make sure that the onlyoffice is actually in the /onlyoffice (ie onlyoffice.mydomain.com/onlyoffice ) then it shoud work smooth
maybe I missed something, but it seems like this

September 17, 2020, 10:18:35 PM #12 Last Edit: September 17, 2020, 10:22:01 PM by GreenMatter
Thanks, ultimately I've decided to go for 2 servers with root locations... It works :-)

BTW, today when logging in to opnsense I was welcomed with completely full drive - usage of 108%!
and the reason was:

root@OPNsense:~ # cd / && du -ma | sort -nr | head -n 20
50463   .
32519   ./var
31071   ./var/log
30435   ./var/log/nginx
30430   ./var/log/nginx/ds1.xxxxxx.xx.error.log
 

Is it normal? Shall I simply disable Access Log Format in this particular HTTP server settings? Or can we set somewhere max. size of logs?
OPNsense on:
Intel(R) Xeon(R) E-2278G CPU @ 3.40GHz (4 cores)
8 GB RAM
50 GB HDD
and plenty of vlans ;-)

QuoteIs it normal?
of course not
whats in log?
obviously something is wrong with server and errors are poured into the log at a terrifying speed

Quote from: Fright on September 17, 2020, 10:32:26 PM
whats in log?

As I connect to this OPNsense instance over VPN I was afraid of having this system completely crashed and lost access - half of services were already halted. Therefore I quickly deleted that file and restarted system.  I could try to tail the log, but I wasn't sure of outcome of command on 30GB file...
Anyway, are there any size limits for error logs?
OPNsense on:
Intel(R) Xeon(R) E-2278G CPU @ 3.40GHz (4 cores)
8 GB RAM
50 GB HDD
and plenty of vlans ;-)