ProxyPass configuration

danb35

Hall of Famer
Joined
Aug 16, 2011
Messages
15,456
There's no way this would happen in 9.x any more, I'm sure, but it could be nice to have in 10. Plugins/jails will be seeing significant changes, but whatever form they take, there will still be apps installed, running mostly-independently, on different IP addresses and likely non-standard ports. This idea is inspired by @Joshua Parker Ruehlig's blog post on installing the SABNZBd/Transmission/SickRage/CouchPotato plugins together in a single jail. A step that I hadn't seen before was an Nginx installation to proxy http://jailIP/appname to http://jailIP:jailport, which is a nice touch.

I'm thinking it'd be better yet if there were a way to configure this through the FreeNAS web GUI, proxying http://FreeNASIP/appname to http://jailip:port. I'd see this, at least initially, as manually configured in the web GUI--user enters FreeNAS URL extension and destination URL. I don't know that there's a need for the destination URL to be local. A further refinement might be to automatically add entries for plugins.

I see a couple of benefits to this:
  • Access to plugin apps, other jail apps, etc. is simplified
  • Encrypt all the things! If there's a good certificate for the FreeNAS server, that would let you use TLS for all the web apps as well
Thoughts?
 

Jailer

Not strong, but bad
Joined
Sep 12, 2014
Messages
4,974
Not sure how I missed this. I've got a jail set up with a Nginx reverse proxy that sends traffic to 2 other jails that I have web servers running in. I did it more as an experiment to see if I could get it to work and because I was bored.

I just forward port 80 and 443 on my router to the proxy jail IP address and configure the proxy to handle the traffic from there. Pretty simple. That way it makes it easy to add something else just by adding another virtual host to the proxy config pointing it to the jail IP you want. You do have to install Nginx from ports with the rewrite module and realIP modules enabled to see the IP of the traffic on the back end server otherwise everything connecting will show the proxy IP address. Also with 9.3 you'll have to install Openssl from ports in the jails as well if you want to encrypt the traffic and run the latest encryption standards.

I know that doesn't add it to FreeNAS itself but it would do what you are looking to do by having basically one entry point for multiple services or servers on your network.
 

danb35

Hall of Famer
Joined
Aug 16, 2011
Messages
15,456
Interesting thought. Not quite as convenient as having FreeNAS do that itself, but it still gives you one place to go, rather than dealing with a bunch of IPs and port numbers. Still would be easy enough to deploy a Let's Encrypt cert to that jail, too (easier than to the FreeNAS box, actually). Thanks for the suggestion!
 

Jailer

Not strong, but bad
Joined
Sep 12, 2014
Messages
4,974
Sure not as easy as setting something up in the GUI but it gives you the flexibility of doing what ever you want with it and also not being bound by what the base FreeNAS system was compiled with.
 

Schuby

Dabbler
Joined
Apr 27, 2016
Messages
37
Not sure how I missed this. I've got a jail set up with a Nginx reverse proxy that sends traffic to 2 other jails that I have web servers running in. I did it more as an experiment to see if I could get it to work and because I was bored.

I just forward port 80 and 443 on my router to the proxy jail IP address and configure the proxy to handle the traffic from there. Pretty simple. That way it makes it easy to add something else just by adding another virtual host to the proxy config pointing it to the jail IP you want. You do have to install Nginx from ports with the rewrite module and realIP modules enabled to see the IP of the traffic on the back end server otherwise everything connecting will show the proxy IP address. Also with 9.3 you'll have to install Openssl from ports in the jails as well if you want to encrypt the traffic and run the latest encryption standards.

I know that doesn't add it to FreeNAS itself but it would do what you are looking to do by having basically one entry point for multiple services or servers on your network.

Do you have any guides on setting this up? I have nginx running in a jail and my router forwarding traffic to them. Now I want to get proxypass setup but It's all new to me.
 

Jailer

Not strong, but bad
Joined
Sep 12, 2014
Messages
4,974
Well I'm not an expert, I kinda learned by a little trial and error but I can get you pointed in the right direction. But not tonight, 4AM comes early and I'm headed off to bed.
 

Jailer

Not strong, but bad
Joined
Sep 12, 2014
Messages
4,974
Ok basics first. If you haven't already start reading. And reading. And researching and reading some more. Then go here and read about the basics of a reverse proxy.

It all depends on what you want to use it for on how you set it up. I have mine set up to pass traffic to a small private forum that I host and a wordpress blog that I set up on a free subdomain just to see if I could get the proxy server working. It's worked quite well so far but of course your setup may be different so you may need a slightly different configuration.

There are all kinds of basic proxy pass configurations out there and you can use any of them as a basis to get your started. You'll have to do the research yourself on how to harden it against attack and plan your setup according to your needs. I'm comfortable with my setup but again I'm no expert and would never recommend any setup of mine as a secure setup for someone else. That's something you'll have to figure out on your own.

One thing you will have to do is install Nginx from ports for a couple of features that aren't compiled in the package version. Those are the realip_module and the rewrite_module. If you plan on running SSL on your site you'll also need to also install openssl from ports and enable the ssl_module and add the following to your /etc/make.conf before you install:
Code:
WITH_OPENSSL_PORT=yes


After you have everything installed and configured you'll have to set up your server blocks. Below is how I have mine set up and again this is what works for me.

Code:
    server    {       
        listen       80;
        server_name  my_public_IP;
        root /usr/local/www/nginx;
        index index.html;
       
        location / {
            try_files $uri $uri/ /index.php?q=$uri&$args;
        }

        error_page      500 502 503 504  /50x.html;
        location = /50x.html {
            root /usr/local/www/nginx-dist;
        }
    }
   
    server {
            listen    80;
            server_name  boredguy.chickenkiller.com www.boredguy.chickenkiller.com;
                location / {
                    proxy_pass  http://IP_OF_BACKEND_SERVER_1;
                    proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
                    proxy_set_header        Host $host;
                    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;
                    }
    }
   
    server {
        listen       80;
        server_name  mlcnfriends.mooo.com www.mlcnfriends.mooo.com;
        return         301 https://mlcnfriends.com$request_uri; 
    }
       
    server    {       
        listen       443 ssl;
        server_name  mlcnfriends.mooo.com www.mlcnfriends.mooo.com;
        ssl_session_cache    shared:SSL:10m;
        ssl_session_timeout  10m;
        ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
        ssl_prefer_server_ciphers   on;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_certificate /usr/local/etc/nginx/server.pem;
        ssl_certificate_key /usr/local/etc/nginx/server.key;
        ssl_dhparam /usr/local/etc/nginx/dhparams.pem;
        add_header Strict-Transport-Security "max-age=16070400; includeSubdomains";
       
        location / {
            proxy_pass              https://IP_OF_BACKEND_SERVER_2;
            proxy_redirect             http:// https://;
            proxy_set_header        Host $host;
            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;   
        }
    }
} 


First server block is a static page with 2 links to the 2 sites. Kinda serves as a landing page in case someone connects via my public IP and gives 2 links to choose from to continue on. Second server block is for the wordpress blog. Just a basic pass to the first backend server. The third server block is for the forum I host. You'll notice in the http block there is a permanent redirect (return 301) that redirects all traffic to https. This configuration and cypher suite is well supported by most browsers and OS and will will get you an A+ score on SSL Labs server test with a valid SSL certificate.

Hope that helps get you going.
 

danb35

Hall of Famer
Joined
Aug 16, 2011
Messages
15,456
I'm starting to play around with Caddy Server for this. Installation's pretty easy, and a basic config file is only a handful of lines (see below). The problem so far is that this basic config file works for Transmission, but not for SABNZBd, Sonarr, CouchPotato, or UrBackup. One out of five isn't great.

Code:
hostname:80 {
  root /usr/local/www/html
  tls off
  proxy /transmission http://192.168.1.15:9091
  proxy /sonarr http://192.168.1.15:8989
  proxy /cp http://192.168.1.15:5050
  proxy /nzb http://192.168.1.15:8080
  proxy /urbackup http://192.168.1.19:55414
}


OTOH, it automatically obtains its own certs from Let's Encrypt (though I don't yet know how, or if, it can complete the DNS challenge), automatically configures HTTPS, etc.
 

Jailer

Not strong, but bad
Joined
Sep 12, 2014
Messages
4,974
Wouldn't you have to put each of those in curly brackets? Not at all familiar with Caddy but each instance it seems would be a virtual host. If I'm reading that correctly it's listening on 80 for your defined hostname and serving up the first proxy it comes to in your config. It seems you would have to define each hostname with a virtual host location seperately and where you want to proxy it to.

But again, I'm not familiar with Caddy so I culd just be talking out my.........
 

Schuby

Dabbler
Joined
Apr 27, 2016
Messages
37
I'm starting to play around with Caddy Server for this. Installation's pretty easy, and a basic config file is only a handful of lines (see below). The problem so far is that this basic config file works for Transmission, but not for SABNZBd, Sonarr, CouchPotato, or UrBackup. One out of five isn't great.

Code:
hostname:80 {
  root /usr/local/www/html
  tls off
  proxy /transmission http://192.168.1.15:9091
  proxy /sonarr http://192.168.1.15:8989
  proxy /cp http://192.168.1.15:5050
  proxy /nzb http://192.168.1.15:8080
  proxy /urbackup http://192.168.1.19:55414
}


OTOH, it automatically obtains its own certs from Let's Encrypt (though I don't yet know how, or if, it can complete the DNS challenge), automatically configures HTTPS, etc.

Wish I knew about this before purchasing a cheap SSL certificate!
 

danb35

Hall of Famer
Joined
Aug 16, 2011
Messages
15,456
Wouldn't you have to put each of those in curly brackets?
I don't think so, based on what the Caddy docs say. As I read them, the proxy directive goes proxy from to, where from is the base path to match, and to is the desired endpoint. But I'm only very minimally familiar with Caddy myself, so it's highly probable I'm missing something. Just for giggles, though, I'll try putting one of the other proxy statements first and see if that changes anything.
 

Jailer

Not strong, but bad
Joined
Sep 12, 2014
Messages
4,974
Yeah but you've only specified one hostname (from) in your example. You have to define a hostname for each destination otherwise how is it going to know which destination to send it to. I found an example that explains it better than I can.

https://gist.github.com/turtlemonvh/1e6dc4621202b2c1a8c4
 

danb35

Hall of Famer
Joined
Aug 16, 2011
Messages
15,456
You have to define a hostname for each destination otherwise how is it going to know which destination to send it to.
The destination is (or should be) determined by the requested path. http://hostname/transmission should give me the Transmission page; http://hostname/cp should give me CouchPotato, etc. I don't see why I'd need to define more than one hostname in this case. The example you gave showed directing different hostnames to different destinations; I want to direct different URLs on the same hostname to different destinations.

Further testing shows that changing the order of the proxy statements doesn't change the behavior--Transmission still works, even when CouchPotato is listed first. Commenting out all but one of the proxy statements also doesn't make a difference--Transmission works; the others don't as described infra. CouchPotato does something, but not the right something--it bounces me from /cp to /#cp and then serves up the test page from the Caddy server (text saying "this is a test page"). NZB does something--it redirects me to the URL of my SABNZBd installation (i.e., that URL shows in the address bar) and says only "SABnzbd |||0" on the page. Sonarr loads a page that says "Sonarr Ver." in plain, unformatted text. Urbackup loads a page saying "Sorry. File not found." (but that isn't a 404 page).
 

Jailer

Not strong, but bad
Joined
Sep 12, 2014
Messages
4,974
Copy that. Admittedly my response was a guess. Other than that I got nothing. :oops:
 
Last edited:

Jailer

Not strong, but bad
Joined
Sep 12, 2014
Messages
4,974
Found something on reddit that may be useful. It's for configuring Nginx as a reverse proxy but the relevant part from one of the responses is listed below. Might be what you are experiencing with a couple of the apps?

https://www.reddit.com/r/usenet/comments/436kdp/configuring_reverse_proxy_nginx_to_connect_to/

Also, don't forget to enable webroot, reverse proxy, or URL Base on each app.

Sonarr: Settings -> General -> URL Base -- i have /sonarr

CP: Settings -> Show Advanced -> General -> URL Base -- i have /couchpotato
 

danb35

Hall of Famer
Joined
Aug 16, 2011
Messages
15,456
Those settings made couchpotato and sonarr work--thanks for the pointer! Now to find corresponding settings for the other apps...
 

Jailer

Not strong, but bad
Joined
Sep 12, 2014
Messages
4,974
Does SABNZBd have to use ssl?

ETA: have you tried adding the subfolder that SABNZBd is installed to to your "to" directive? Like:

Code:
proxy /nzb http://192.168.1.15:8080/nzb
 
Top