Hi,
I’m using haproxy through PfSense and as I’m not able to have my conf working, I was wondering if what I need is possible or not, hence my question here.
here is a recap of my need :
I have 1 single public IP address,
I need the following at the same time :
I have a domain , smalldragoon.com , where
A1 - A.smalldragoon.com, B.smalldragoon.com, C.smalldragoon.com need to be forwarded to an internal which is managing the SSL connection ( equivalent to port forwarding of the 443 as ex )
A2 - D.smalldragoon.com need to have its SSL communication terminated on PFSense and redirected to an internal host which is running on port 80 ( so not in https , it is a basic website).
Ex : https://D.smalldragoon.com redirect to http://192.168.1.1:80
So maybe first question : is this possible ?
I get some warnings with telling me I need to use shared frontends but everything I have done so far did not work.
Of course, each config alone works perflectly
Thanks for your insights !
well…up ? just at least to know if iti is posisble or not ?
It’s possible, you need a TCP frontend that SNI routes the traffic as necessary.
The SSL session that you want to terminate you router to SSL terminating frontend on another port of the same haproxy instance, so you are able to have both.
This all works only if the certificates do not overlap.
Hi @lukastribus , thanks for your answer.
let me rephrase to be sure I understand correctly :
I have 2 domain A and B
I want to terminate B and fw A as is to internal
So based on SNI, single frontend, I
for A domain, FW to my internal host
for B : redirect to port 12345
then create another frontend on port 12345 , which will do SSL termination
am I correct stating that ?
Thanks
Thanks a lot !
I will play in the next couple of days !
Thanks
Hi,
As I still can’t get it working , I decided to proceed step by step.
1 - re-started from a blank complete config.
2 - created a front end with SNI on port 443, with each Server Name Indication TLS extension matches X1.smalldragoon.com to an action ( X1 to x1, X2 to x2 …).
Action beiing : x1 - > use backend “general”; General is a backend with forward to ip + port and has his own certificate public working .
3 - apply config , it works ( if I try to reach X1.smalldragoon.com" )
4 - Now, I Change this frontend to use port 445
5 - I create a backend " Forwarder-to-smalldragoon.com", where action is " redirected to frontend “my main frontend which now listeing on port 445 )
6 - create a new front end, using port 443, with a rule " Server Name Indication TLS extension contains: smalldragoon.com”, forward to backend “Forwarder-to-smalldragoon.com port 445”
it just do not do anything …
Am doing right ?missing a step or even maybe it is where I’m wrong since the begining … is it the proper method ?
Thanks
[ EDIT] I forgot to say that of course, if I try to reach site on port 445 ( https://X1.smalldragoon.com:445 , it works )
Post the full configuration, otherwise it’s difficult to get a complete picture of the situation.
sure, here we go then
global
maxconn 1500
log /var/run/log local0 debug
stats socket /tmp/haproxy.socket level admin expose-fd listeners
uid 80
gid 80
nbproc 1
nbthread 1
hard-stop-after 15m
chroot /tmp/haproxy_chroot
daemon
tune.ssl.default-dh-param 2048
log-send-hostname BASTION
server-state-file /tmp/haproxy_server_state
listen HAProxyLocalStats
bind 127.0.0.1:2200 name localstats
mode http
stats enable
stats refresh 10
stats admin if TRUE
stats show-legends
stats uri /haproxy/haproxy_stats.php?haproxystats=1
timeout client 5000
timeout connect 5000
timeout server 5000
frontend Main-Frontend-SNI-redirect-443
bind [MY PUBLIC IP]:443 name [MY PUBLIC IP]:443
mode tcp
log global
timeout client 30000
tcp-request inspect-delay 5s
acl dragoon req.ssl_sni -m sub -i smalldragoon.com
tcp-request content accept if { req.ssl_hello_type 1 }
use_backend Forwarder-to-smalldragoon.com-port-445_ipvANY if dragoon
frontend Frontend-smalldragoon.com-SNI
bind [MY PUBLIC IP]:445 name [MY PUBLIC IP]:445
bind /tmp/haproxy_chroot/Frontend-smalldragoon.com-SNI.socket name unixsocket uid 80 accept-proxy
mode tcp
log global
timeout client 30000
tcp-request inspect-delay 5s
acl admin req.ssl_sni -i admin-poc.smalldragoon.com
acl ssp req.ssl_sni -i ssp-poc.smalldragoon.com
acl dmz req.ssl_sni -i dmz-poc.smalldragoon.com
tcp-request content accept if { req.ssl_hello_type 1 }
use_backend smalldragoon.com-Server_ipvANY if admin
use_backend smalldragoon.com-Server_ipvANY if ssp
use_backend smalldragoon.com-Server_ipvANY if dmz
backend Forwarder-to-smalldragoon.com-port-445_ipvANY
mode tcp
id 106
log global
timeout connect 30000
timeout server 30000
retries 3
option httpchk OPTIONS /
server forwarder /Frontend-smalldragoon.com-SNI.socket send-proxy-v2-ssl-cn id 107 check inter 1000
backend smalldragoon.com-Server_ipvANY
mode tcp
id 104
log global
timeout connect 30000
timeout server 30000
retries 3
server smalldragoon.com 192.168.1.1:443 id 105 check inter 1000
A few suggestions:
- you only need to match SNI in one frontend (the one listening on port 443)
- start using normal IP sockets for the backend → frontend re-circulation, thats less complex
- don’t start adding features when your basic configuration doesn’t work. Don’t use proxy-protocol on the first try
- I don’t see any SSL terminating configuration in there, so it’s unclear how that would work
Here’s a (untested) configuration that would work, based on your initial description (a, b, c.smalldragoon.com should be SSL passthrough, d.smalldragoon.com should be SSL terminated):
frontend Main-Frontend-SNI-redirect-443
bind [MY PUBLIC IP]:443 name [MY PUBLIC IP]:443
mode tcp
log global
timeout client 30000
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
acl passthroughdom req.ssl_sni -i a.smalldragoon.com
acl passthroughdom req.ssl_sni -i b.smalldragoon.com
acl passthroughdom req.ssl_sni -i c.smalldragoon.com
use_backend passthrough if passthroughdom
acl ssltermdom req.ssl_sni -i d.smalldragoon.com
use_backend sslterm if ssltermdom
# or use a default_backend directive
frontend frontsslterm
mode http
bind 127.0.0.1:445 ssl crt /var/ssl/private/
default_backend httpbackend
backend httpbackend
mode http
server server1 192.168.1.2:80
backend passthrough
mode tcp
server server1 192.168.1.1:443
backend sslterm
mode tcp
server local 127.0.0.1:445
hi @lukastribus , thanks a lot for all your help . So I understand indeed your suggestions on SNI matching and normal IP sockets.
regarding now the “other features”, I’m using PfSense and the GUI is adding these extra’s.
I checked all the options, checkboxes trying to be as close as possible updating the conf to get it matched with your sugested one :
listen HAProxyLocalStats
bind 127.0.0.1:2200 name localstats
mode http
stats enable
stats refresh 10
stats admin if TRUE
stats show-legends
stats uri /haproxy/haproxy_stats.php?haproxystats=1
timeout client 5000
timeout connect 5000
timeout server 5000
frontend Main-Frontend-SNI-and-redirect
bind [MY PUBLIC IP]:443 name [MY PUBLIC IP]:443
mode tcp
log global
timeout client 30000
tcp-request inspect-delay 5s
acl passthrough req.ssl_sni -i admin-poc.smalldragoon.com
acl passthrough req.ssl_sni -i ssp-poc.smalldragoon.com
acl joomla req.ssl_sni -i joomla.smalldragoon.com
tcp-request content accept if { req.ssl_hello_type 1 }
use_backend passtrough-smalldragoon.com-Server_ipvANY if passthrough
use_backend SSLterm_ipvANY if joomla
frontend frontend-ssl-term
bind 127.0.0.1:445 name 127.0.0.1:445
mode tcp
log global
timeout client 30000
default_backend httpbackend-portal-joomla_ipvANY
backend passtrough-smalldragoon.com-Server_ipvANY
mode tcp
id 104
log global
timeout connect 30000
timeout server 30000
retries 3
server smalldragoon-com 192.168.1.69:443 id 105 check inter 1000
backend SSLterm_ipvANY
mode tcp
id 106
log global
timeout connect 30000
timeout server 30000
retries 3
option httpchk OPTIONS /
server sslterm 127.0.0.1:445 id 107 check inter 1000
backend httpbackend-portal-joomla_ipvANY
mode tcp
id 108
log global
timeout connect 30000
timeout server 30000
retries 3
server portal 192.168.1.26:80 id 109 check inter 1000
The differences I see are the mode for http backend ( do not manage to switch it to http instead of tcp)
When I try to access to https://joomla.smalldragoon.com, it is still redirected to the passtrhough site ( like he is not making a difference on the SNI )
frontend frontend-ssl-term
is missing all the SSL configuration. It needs ssl and crt keywords with certificate.
And importantly:
I tried to anonymize as less as possible for the certificate not overlaping.
I have the SSL config in place now I think
frontend Main-Frontend-SNI-and-redirect
bind [My Public IP]:443 name [My Public IP]:443
mode tcp
log global
timeout client 30000
tcp-request inspect-delay 5s
acl passthrough req.ssl_sni -i admin-poc.smalldragoon.com
acl passthrough req.ssl_sni -i ssp-poc.smalldragoon.com
acl joomla req.ssl_sni -i joomla.smalldragoon.xyz
tcp-request content accept if { req.ssl_hello_type 1 }
use_backend passtrough-smalldragoon.com-Server_ipvANY if passthrough
use_backend SSLterm_ipvANY if joomla
frontend frontend-ssl-term
bind 127.0.0.1:445 name 127.0.0.1:445 ssl crt-list /var/etc/haproxy/frontend-ssl-term.crt_list
mode http
log global
option http-keep-alive
timeout client 30000
acl aclcrt_frontend-ssl-term var(txn.txnhost) -m reg -i ^([^\.]*)\.smalldragoon\.xyz(:([0-9]){1,5})?$
http-request set-var(txn.txnhost) hdr(host)
http-request deny if { req.hdr_cnt(content-length) gt 1 }
http-response deny if { res.hdr_cnt(content-length) gt 1 }
use_backend httpbackend-portal-joomla_ipvANY if aclcrt_frontend-ssl-term
backend passtrough-smalldragoon.com-Server_ipvANY
mode tcp
id 104
log global
timeout connect 30000
timeout server 30000
retries 3
server smalldragoon.com 192.168.1.69:443 id 105 check inter 1000
backend SSLterm_ipvANY
mode tcp
id 106
log global
timeout connect 30000
timeout server 30000
retries 3
option httpchk OPTIONS /
server sslterm 127.0.0.1:445 id 107 check inter 1000
backend httpbackend-portal-joomla_ipvANY
mode http
id 108
log global
timeout connect 30000
timeout server 30000
retries 3
server portal 192.168.1.26:80 id 109 check inter 1000
but the SSL still says it is presenting the smalldragoon.com instead of offloading for domain smalldragoon.xyz ( and therefore saying the cert domain is not matching )
I can’t really help you further at this point. Check haproxy logs and confirm that the correct routing decision are made. Check that the correct SSL certificate used for SSL termination.
Go step by step.
OK, thanks you. will keep you posted.
HI, just an update. I’m having trouble to get logs from haproxy with PFSense. I only get the stop /restart but no info on the routing.
Will keep you posted once this solved and hopefully the main problem thanks to the logs
Check this for syslog configuration: