Double Reverse Proxy with pfSense and CloudFlare + Full SSL - Part 1
Okay, so the title of this post probably left some of you scratching your heads on why this is even a valid scenario.
Let me explain. For most homelabers such as myself, hosting a public facing website is a definite possibility. For example, you may want to host your blog on your own equipment. Unfortunately, without doing some specific things using one IP for multiple websites can get ugly. You see, when you expose your website to port 80 on your WAN that's all people can see so in most cases if you want to throw up another site you either need to some trickery with your routes, expose it on a different port, or do some magic with DNS records using URL redirects or SRV records.
Alas there's a better way, Reverse proxies!
How does it work? Perhaps an image will clear this up.
In our scenario the reverse proxy intercepts HTTP requests from clients and redirects them to the appropriate web-server behind the firewall. The reverse proxy stores a FQDN to local-IP mapping so that it knows which server to redirect the request to. For example if the client makes a GET request to foobar.com, the reverse proxy will inspect the HTTP request, compare it to the FQDN->IP table and route the request to that server.
Configuring Squid in pfSense
For our setup we'll be using pfSense and the excellent squid package for it.
First login to pfSense and navigate to
System -> Package Manager -> Available Packages and install the package called
After squid finishes installing you should see two new options in your
Services menu, click on the one that says
Squid Reverse Proxy
General tab we'll need to make a few changes. First off, make sure the
Reverse Proxy Interface(s) selection is set to WAN. Also, you will need to set the
External FQDN this should be a domain with an A record that points to your WAN IP, if you don't have a static IP this will be your DDNS domain. Next we'll need to check
Enable HTTP Reverse Proxy and set the
Reverse HTTP Port to 80. The rest of the defaults on this page are fine, we'll be covering SSL and HTTPS in another post so don't bother enabling it. Click
Moving on to the
Web Servers tab, click
Add to create a new mapping. Check
Enable This Peer and set the
Peer Alias to anything you want (I usually set it to the hostname of the web server). Set the
Peer IP to the LAN IP of the Web Server, the
Peer Port to 80, and
Peer Protocol to HTTP. Click
Save. If you have multiple servers create additional entries for those too.
Navigate to the
Mappings tab and click
Add to create a new Mapping. Check
Enable This URI and set the
Group Name to anything you want (again I typically use the server's hostname). Select the peer you want to map to, and type in a regex for the Mapping to match against. For example you could set the
Save. If you have multiple servers create additional mappings for those too.
Enable PASS rule for HTTP
Okay, almost there! Next thing we need to do is create a PASS rule for HTTP otherwise all requests going to port 80 will get tossed.
Firewall -> Rules then click
Add. In the new firewall rule, set the
Action to pass,
Interface to WAN, if your network supports IPv6, you can set the
Address Family to IPv4+IPv6. Set the
Protocol to TCP. Under the
Source select any for the drop-down. Under the
Destination section select
WAN address for the first drop-down. For the
Destination port range set
From to HTTP(80), and
To to HTTP(80). Click
Finally, the last thing we need to do is start the squid service. Navigate to
Status -> Services and click the
Start Service action arrow next to squid service.
That's it. If all goes well, when you type in
foobar.com or whatever your domain is you should see your website load.
- Be sure to update your domain records to point to your WAN IP.
- If you simply type in you WAN IP manually the reverse proxy server will likely toss the request and you'll either get a blank page or no response as it will not match against any of the mappings you setup earlier, this is expected.
In my next tutorial I'll cover hiding your WAN IP in this configuration by using CloudFlare