nginx plugin

Started by fabian, June 10, 2018, 12:35:30 PM

Previous topic - Next topic
June 10, 2018, 12:35:30 PM Last Edit: June 15, 2018, 05:46:25 PM by fabian
I work on a nginx plugin and made a developer preview (may still contain bugs):
Source: https://github.com/opnsense/plugins/pull/696

Package: pkg add https://files.fabian-franz.eu/os-nginx-devel-0.2.txz
Please do not use it for production systems because it may contain unknown bugs.

I can try this on my dev system...

Erick

Do you know how to create your own build since the linked one is a bit older and the current one needs a custom patch for core:
https://github.com/opnsense/core/pull/2480

Oh, I do not know how ... yet.

I tried it on the dev build.  Once I moved the default httpdlite to 8080, the nginx worked on 80 on the NAT side. 

My goal is to set up an internal cloud, and have NGINX/OpnSense be the router/firewall/virtual hosting place.  So HTTPS traffic would be decrypted at the OpnSenseo which would be my single certificate holder.


With the new build, you don't need to move the web interface because it will disable the local web server and handle it by itself - the advantage is that the same port can be used. you can clone the plugins repository and run make package inside the www/nginx directory which will build the pkg or use make install.

for core you need the following patches in core:
if you install it as a pkg, you can also use this code: https://github.com/opnsense/core/pull/2480/commits
opnsense-patch -a fabianfrz 505a8780eae55aa552b680cf6aced44b0e5f7f55 b8d8bfeba1b65b4a3da262af32cb1f750948a51f


First let me say thanks for this plugin  and it will prove very useful if all the features planned for it get worked out.

However I am coming up to a bit of a brick wall in using the gui because it seem the logic for passing to an upstream server is broken.

Basically what I am trying to do is expose a gucamole server to OPNsense which then acts as a nginx reverse proxy which holds all the Let's Encrypt certs and renewal.

I already did this configuration by hand using a dockerized nginx container which then had traditional NAT mapped to is via the previous routers. It worked fairly well on some dumb routers but for some reason with OPNSense it interrupted the connection every 30 seconds or so breaking the guacamole sessions.

So when I found nginx could be run on the OPNsense box itself I was like "Yeah, that'll do fine " because the guacamole server is exposed to the LAN anyway just on a HTTP alt port 8080.

So the problem I have with the plugin though is the rewrite rules seem to be applied only to the OPNsense HTTP server section and not to the proxy settings as well. Because the destination URL has to be http://10.1.8.12:8080/guacamole I should be able to append the /guacamole part somewhere to the proxy URI.

This is how it worked when I did it  by hand.


    location / {
        root   /usr/share/nginx/html;
        return 301 https://$host/rs;
}

   
location /rs/ {

      proxy_pass  http://172.17.0.7:8080/guacamole/;
      proxy_buffering off;
      proxy_http_version 1.1;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection $http_connection;
      access_log off;






But this is how the GUI sort of mangles it:

# UPSTREAM SERVERS
upstream upstream70b4351bbf6548ba827f620ee5b55029 {
server 10.1.8.12:8080 weight=1 max_conns=100 max_fails=10 fail_timeout=5;

}


....



    # apache htpasswd and htaccess
    location ~ /\.ht {
        return 403;
    }
    # those files may expose file system stuff
    location ~ \.DS_Store$ {
        return 403;
    }
    rewrite / /guacamole redirect;


location ~* $host/guacamole {
    DeniedUrl "/waf_denied.html";
    if ($scheme != "https") {
        return 302 https://$host$request_uri;
    }
    autoindex off;
    proxy_set_header Host $host;
    proxy_pass http://upstream70b4351bbf6548ba827f620ee5b55029;




So I realise that this is a beta plugin at best and you do say not to use it for production but obviously this way of parsing the conf file is a deal breaker for redirects like mine. I suspect I will have to just go back to making a manual config file and leaving the gui blank in case it overwrites my changes.

Unless there is another way I am missing of course ?

Websocket support will be in 1.1 (https://github.com/opnsense/plugins/pull/828)

For the location block: it looks very strange to me to include the hostname. Why?

QuoteWebsocket support will be in 1.1 (https://github.com/opnsense/plugins/pull/828)

Oh that is cool. Great!

QuoteFor the location block: it looks very strange to me to include the hostname. Why?

I think it was more convention than anything else. I took the same sort of rules I used for nginx is the standalone  instance and one of the cool things is nginx (like apache) can have multiple 'identites' in different config files which can be very handy. So if you are coming in as say mail.host.domain you get the webmaill forwarding, if you come in as dashboard.host.domain you get another service. All the $host does is make sure that the urls stay consistent I think.

I assume you knew this because you can allow multiple entries to be created though I am still unclear how they are all supposed to work together with the same nginx.conf file. Or maybe I am just misunderstanding how it is all parsed, it was very late last night when I started  looking into it going off into the weeds.

Either way looks like it is shaping up nicely and I don't mind playing around with it on a non-production install and ironing out other edge cases.

Thanks.

Quote from: opnonce on September 20, 2018, 11:18:20 AM
I think it was more convention than anything else. I took the same sort of rules I used for nginx is the standalone  instance and one of the cool things is nginx (like apache) can have multiple 'identites' in different config files which can be very handy. So if you are coming in as say mail.host.domain you get the webmaill forwarding, if you come in as dashboard.host.domain you get another service. All the $host does is make sure that the urls stay consistent I think.
[/qoute]
No your URL for

location ~* $host/guacamole

would be: https://mail.host.domain/mail.host.domain/guacamole which is very uncommon and stupid.

Quote from: opnonce on September 20, 2018, 11:18:20 AMI assume you knew this because you can allow multiple entries to be created though I am still unclear how they are all supposed to work together with the same nginx.conf file. Or maybe I am just misunderstanding how it is all parsed, it was very late last night when I started  looking into it going off into the weeds.
you probably want a "/guacamole" or "/" location to forward to the upstream which it will reach with the same URL (without pre- or postfix).

Quote from: opnonce on September 20, 2018, 11:18:20 AMEither way looks like it is shaping up nicely and I don't mind playing around with it on a non-production install and ironing out other edge cases.
If you find a normal case, it would be probably good for everyone to know about it.

Hi folks,

We are testing nginx with WAF enabled, according https://wiki.opnsense.org/manual/how-tos/nginx.html but when we enable the WAF we get denied page to localtion /, even in learning mode we got denied page.

This is the part of config ...

location  / {
    SecRulesEnabled;
    LibInjectionXss;
    CheckRule "$LIBINJECTION_XSS >= 8" BLOCK;
    LibInjectionSql;
    CheckRule "$LIBINJECTION_SQL >= 8" BLOCK;
    DeniedUrl "/waf_denied.html";
    autoindex off;
    proxy_set_header Host $host;
    proxy_pass http://upstream16d9678a48cf438b8f71617150c53c4c;

}



Could someone have ideia about it?

Regards

Carlos

It may be because of a naxsi bug which I have reported and is already fixed upstream but needs to get included in FreeBSD.

It blocks everything if there is no main rule present. Because if this, I've talked to the developers to get a patch and now it is documented that you can use this to prevent it from blocking everything: https://github.com/opnsense/plugins/blob/master/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/ruleset.conf#L1

For some reason the naxsi patch has not reached us yet. A work around is just create some main rules. The project has some good ones:
https://github.com/nbs-system/naxsi/blob/master/naxsi_config/naxsi_core.rules

Hello @Fabian,

Thank you by your clarify.
Well, if I understood, as workaround need I a Main rules. https://github.com/nbs-system/naxsi/blob/master/naxsi_config/naxsi_core.rules
But how can I add this using GUI. Or need I put it into specific directory!?

Regards
Carlos

Configure a naxsi rule, add it to a policy and add the policy to a location and it should be there.