HA Proxy is unable to redirect information

Hello,

I’m configuring the pfSense with HA Proxy to serve as a reverse proxy for my applications that built under a docker machine.

DNS is working fine If I open in the firewall directly the port to the specific application I through the http://app1.example.com:17919 reach it, also inside the same network I’m able to reach without the need of opening the port which is expected an means that DNS is working.

For some reason I’m not able for the communications coming from the internet to reversed to the correct application.

I’ve done this in NGinx and is working, example below.

One the things that is confusing me is that if there is any firewall and/or NAT rules that we need to implement for this to work, that is not explained in the video, but I do believe that is what is missing but not entirely sure.

For the configuration of pfSense and HAProxy I followed this tutorial and did everything as shown.
But I’m unable to find out what is wrong. Any help would be greatly appreciated.

“How To Guide For HAProxy and Let’s Encrypt on pfSense: Detailed Steps for Setting Up Reverse Proxy”

Thanks in advance.

To clarify:

  • What do the appX.example.com domains resolve to - the public address of the router, the local address of the router, the local address of the resepctive services or multiple of the above using split DNS?

  • Which port(s) do you want the services to be available at when accessing them via the reverse proxy? Normally this would be 80 and 443 instead of the non-standard ports where the application itself is listening on its machine.

Hello Paolo,

  • When you request the appX.example.com from the internet it goes to the public IP of the pfSense, in simple way to put it, all subdomains are pointing to the same public IP address that is the pfSense. The idea is to have HAProxy do the redirect to the correct ports when calling specific subdomain

  • That would be the idea. For example having an NGinx as a reverse proxy I only need to open the firewall ports and/or NAT rules to the private IP of the NGinx internally to ports 80 and 443 even though 80 is pointing to 443. From a DNS and pfSense they don’t that NGinx exists. This is my way of putting it, when a subdomain connection is requested, https://app1.example.com, it will go to the public IP address that is configured in the pfSense, as per the rules it will just redirect it to the machine that has 443 as route.

Just to clarify on the firewall and/or NAT rules:

  • You should create rules to allow incoming traffic to the ports required (80,443) on your WAN interface to hit the HAProxy Frontend service listening on same interface.
  • You should not have any NAT rules that port forward the same traffic elsewhere, such as your previously configured Nginx proxy.

Then double check your HAProxy configs:

  • Frontends match top to bottom, similar to firewall rules, so look out for a higher order entry such as Host ends with: example.com intercepting a latter entry such as Host matches: app1.example.com.
  • Ensure the names correlate perfectly when configuring frontend ACLs and matching backend Actions.

Thanks stildalf.

In the NAT rules should be:

  • Interface → WAN
  • Protocol → TCP
  • Source → Any
  • Destination → WAN Address
  • Dest. Ports → 443
  • NAT IP → Application server
  • NAT PORTS → 443
  • Filter rule association → Pass

I will create a rule later for this.

I have one front end with multiple back ends. I will be using several subdomains to the port 443 but different ports in the back end.

Question here, can I use the same back end for the same server in different ports in the server list?

in the back end in the server list:

  • Mode → Active
  • Name → app name
  • Forwardto → Address+Port:
  • Address → server IP address
  • port → 22300
  • Encrypt(SSL) → checked
  • SSL checks → no

Front end:

  • Status → Active
  • External address:
    → Listen address → WAN address (IPv4)
    → Port → 443
    → SSL offloading → checed
  • Type → http/https (offloading)
  • Access control list:
    → Name → app name
    → Expression → host matches:
    → CS → no
    → Not → no
    → Value → app1.example.com
    (DNS resolver in place and configured)
  • Actions:
    → Use backend → backend: app name
    → Parameters → see below
    → Condition acl names → app name the same as in the access control list.
  • SSL offloading:
    → Certificate → ACME Cert
    → Add ACL for certificate Subject Alternative Names → Checked

Assuming that this is correct it is still not working with NAT Rule in place.

This still looks like a NAT Port Forward with an associated filter rule, that will simply forward traffic to the Application server without going through HAProxy - not what you want.

  • Disable/Delete any entries for ports 443/80 under Firewall → NAT → Port Forwarding.
  • Create a rule each for 443 & 80 under Firewall → Rules → WAN
    • Action: Pass
    • Interface: WAN
    • Protocol: TCP
    • Source: any
    • Destination: WAN Address; From Port 443/80; To Port 443/80;
    • (Or create a port alias under Firewall → Aliases → Ports and allow 443 & 80 in one rule)

You don’t want the firewall to forward the traffic, you want HAProxy to forward based on the frontend/backend/acls you configure. You just need the firewall to allow the traffic to hit HAProxy.

Yes, you can have one frontend that hits multiple backend’s based on the acl and actions.

Good morning @stildalf,

Did what was suggested and is till not working.
Getting “503 Service Unavailable”

I went a step further and checked the box in HAproxy for health check, below is the response.

[NOTICE] (21776) : haproxy version is 2.8.3-86e043a
[NOTICE] (21776) : path to executable is /usr/local/sbin/haproxy
[WARNING] (21776) : config : Server joplin_ipvANY/joplin is DOWN, changed from server-state after a reload. 0 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
[WARNING] (21776) : config : Server kimai_ipvANY/kimai is DOWN, changed from server-state after a reload. 0 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.

The firewall rule is setup and is working I see some traffic.

Also, DNS provider seems to be correctly configured, since I can

http://kimai.example.com17919/en/login

And I get the app page.

But if I do

https://kimai.example.com

I get the 503 response.

I do have a question, HAProxy can receive communication in HTTPS and go to the app in HTTP and will go to the user in HTTPS. Or it can only communicate under SSL even in the Local Network?

You are getting closer, at least hitting the proxy which is spitting out the 503 because your backends are considered DOWN.

  • Have a look under Services → HAProxy → Stats (or Stats FS = FullScreen).
  • Then configure your backends with appropriate Health Checking settings. For a quick test, change the Health check method to none - which will force HAProxy to assume the service is always UP. The options for health checking vary significantly depending on what’s being served, from a simple socket connection or HTTP GET request on a URL such as /alive.

Yes, it’s called SSL Offloading, and common practice employed for various reasons such as load balancing, performance improvements, central certificate management, scalability, etc…

HAProxy is extremely versatile and can operate in any combination of HTTP/S ↔ HTTP/S. But, with the versatility comes the (perceived) complexity of setting it all up - at least compared to something simpler like Nginx Proxy Manager.

@stildalf stildalf,
Thanks a million for the assist.

backend still shows down, no matter what I do.

I’ve used pfSense diagnostic port and I can reach both application ports from the address that is serving as gateway for the LAN network, I’m also able to reach them from a machine that is inside the same network.

From the outside still getting the 503.

I would that there is a bad configuration in the HAProxy most likely

I would assume that this is correct, is there a log that I should look into?

Running out of things to suggest here @Zumo, some things to double check:

  • You have to get HAProxy Stats to report those backends as UP, even if by setting Health check method to none in the backend config. Otherwise HAProxy will present you the 503, because it thinks there is “No server available to handle this request”.
  • Also in the backend config with the Encrypt(SSL) → checked, is that app actually being served with an SSL cert - self signed or otherwise? If not the backend settings should be NO for both Encrypt(SSL) and SSL checks.
  • In the frontend config, under SSL Offloading → Certificate, also check the config Add ACL for certificate CommonName.

Hello @stildalf,

You’re the boss. you are absolutely right.

The apps themselves don’t have SSL certificate. Dumb of me.
I want them to have it through HAProxy.
That worked great thanks a million :smiley: