I have configuration that works well when HTTPS is in the URL but of course, when it is HTTP, it fails. The problem is, I must specify the port number in the URL. I am using this as a way to test individual servers. So the website name must remain unchanged to work with the SSL cert but I can assign one port (and an associated frontend and backend) in the haproxy.cfg file to route to the correct server.
The problem happens when for what ever reason, HTTPS is not specified but the magic port number is. Some apps do a redirect (code beyond my control) and because the server is only running on port 80 without SSL and haproxy is doing all the SSL work, the app doesn’t realize it needs to redirect to https://… so it just redirects to the http:// version and that is where things break.
Now, the question is, how do I make this work so if I specify http://mysite.com:801 that haproxy will still respond but auto redirect to https://mysite.com:801 without throwing a fit?
The frontend port801_combined detects whether the incoming request is SSL/HTTPS or plaintext HTTP.
It forwards the traffic to backend recir_http if the it is plaintext HTTP.
Otherwise it forwards the traffic to backend recir_https.
The backend recir_http sends all the traffic to the frontend fe-http via the socket abns@haproxy-http.
The backend recir_https sends all the traffic to the frontend fe-https via the socket abns@haproxy-https.
Ultimately, I did some tweaking to include the port number into all of the reference points and because I have several servers that I want to be able to address individually, I needed to replicate this process once for each port 801, 802, 803, etc.
Feels clunky, but since these only exist for testing purposes and cannot be accessed from the world because of our firewall, this works pretty well. If there is a simpler way, would love to know it but this will do the trick for me.
frontend port801_combined
mode tcp
bind :801
tcp-request inspect-delay 2s
tcp-request content accept if HTTP
tcp-request content accept if { req.ssl_hello_type 1 }
use_backend recir_801_http if HTTP
default_backend recir_801_https
backend recir_801_http
mode tcp
server loopback-for-http abns@801-haproxy-http send-proxy-v2
backend recir_801_https
mode tcp
server loopback-for-https abns@801-haproxy-https send-proxy-v2
frontend fe_801_https
mode http
bind abns@801-haproxy-https accept-proxy ssl crt /etc/ssl/private/unified-cert-file.pem
capture request header Host len 32
capture request header User-Agent len 90
default_backend port_801
frontend fe_801_http
mode http
bind abns@801-haproxy-http accept-proxy
capture request header Host len 32
capture request header User-Agent len 90
default_backend port_801
backend port_801
option forwardfor
http-request add-header X-CLIENT-IP %[src]
redirect scheme https code 301 if !{ ssl_fc }
server server1 192.168.10.107:80 check
I missed one label when switching 801 to 802 and caused a duplicate backend entry.
This morning I was looking it over and spotted it. So putting the port number into the labels and socket name works, baring human error when retyping the port numbers.
Based on the solution provided, is it fair to say that haproxy can handle situations where I want to achieve the following:
I have one server hosting an https site and as ssh site, and also using certbot to get/refresh ssl certs from letsencrypt (why I need to do this is a whole different story, will not go into that here).
The catch is that only ports 80 and 443 are accessible.
Would haproxy be able to handle it in a way that any http/s traffic to any of those two ports is routed to the correct backend in http/s mode, and all other traffic is forwarded to the ssh port at a tcp level?
Hi, I’m trying to do something similar using the HAProxy plugin on pfSense. I would like to listen to for example port 8000 (sub1.domain.tld:8000) and if the traffic is plaintext http, redirect it to https. The problem is that for the GUI the steps aren’t really the same.
The following has already been done:
We are listening on different ports and proxying the traffic internally. For example when we type https://sub1.domain.tld:8000 it will redirect to the application and do an ssl offloading. The issue is that when I type http://sub1.domain.tld:8000 it doesn’t redirect to https://sub1.domain.tld:8000. The redirection only works when port 80 is being redirected to 443.
Grateful if you could please assist on this issue.
We can help you with haproxy. Cannot help you with your pfsense GUI though.
Share the current haproxy configuration as well as the output of haproxy -vv and we may be able to suggest what should be done on a configuration level.
reposting here expecting some expert help as nobody even viewed my query.
I have two incoming requests, one of it needs to go to a “http:// server” and other to “https:// server”.
Below is my acl and backend definitions
------in haproxy_peers.cfg---------
acl downstream_service1 path_beg /downstream_serv1/internal/api
acl downstream_service2 path_beg /downstream_serv2/internal/api
use_backend downstream_serv1_http if downstream_service1
use_backend downstream_serv2_https if downstream_service2
------------------------------------------
backend configs:
--------in backend config file-----------
backend downstream_serv1_http
http-request set-path "%[path,regsub(^/downstream_serv1/,/)]"
server downstream_server1 host-name.domain:port_number check //*note there is no http/https protocol mentioned.*
backend downstream_serv2_https
http-request set-path "%[path,regsub(^/downstream_serv2/,/)]"
server downstream_server2 host-name2.domain:port_number check //*note there is no http/https protocol mentioned.*
---------------------------------------------
Expectation is http://haproxyHost/downstream_serv1/internal/api should be routed to http://host-name.domain:port_number/internal/api
http://haproxyHost/downstream_serv2/internal/api should be routed to https://host-name2.domain:port_number/internal/api
With the above config im getting a 503/502 for the https route. HTTP route is working as expected…Kindly help.