HAProxy - how to point traffic to a new server?

Hi everyone!

Completely new to HAProxy here.

I inherited infrastructure with HAProxy server, web server and a database server.

Due to recent attacks on infrastructure, I would need to roll back my backup and deploy on a new server.

Within the DNS zone, I can see that A records are pointed to HAProxy server, even though application is hosted on a different server, so my assumption is that traffic to my web application is routed though HAProxy web server.

Since I need to deploy a new web instance, I’m guessing I would need to edit HAProxy configuration and point it to a new web server (I might be completely missing the point here though).

My question is how do I point incoming traffic that hits HAProxy server to my new web server?
What would be the typical HAProxy setup? At the moment I don’t have the access to HAProxy server via root, however I do have some config file and a user for HAProxy created on my web server with the instructions to call load balancer user to access HAProxy.

If it helps, I can paste HAProxy config here.

Many thanks!

It would be easier to give an answer if I could see the config. If you intend on maintaining your inherited infrastructure, I highly recommend starting with some documentation on what HAProxy does and how.

To get you started, your configuration should have 4 parts:

  • Global:

    Parameters in the “global” section are process-wide and often OS-specific. They
    are generally set once for all and do not need being changed once correct. Some
    of them have command-line equivalents.

  • Defaults: Anything set here is assumed to be set in every other section where applicable.

  • One or more Frontends: This is where HAProxy is accepting traffic. The frontend configurations will usually include a bind line showing what IP and/or Port HAProxy is listening on and may include certificates for HTTPS. The frontend sections may also include matching rules called acls. This will determine how requests are treated if there are any special circumstances that HAProxy needs to account for, like deciding that a.example.com needs to go to one place, but b.example.com needs to go to another place. At minimum, the frontend should include a default_backend defining where any traffic that does not match a rule should go.

  • One or more Backends: Backends are destinations for frontends. Many configs only have a default_backend declared in the frontend, so there will be only one backend. This is most likely where you will find one or more destination web servers. You may also find other configs here, such as header modifications and health check configurations.

This is a VERY BASIC overview of what you may find in your config file, and it misses a LOT of other basics, such as TCP verses HTTP listening and some other basic principles. I would encourage you to read the starter guide (same link as above). That said, feel free to post some or all of your config and ask whatever questions you may have.

2 Likes

Hi @stormrover Thanks a lot for replying.

Regarding the inherited infrastructure - we don’t plan to keep it. We have to keep it on life support for few months. That being said, for sure I’ll go through docs.

I’m attaching config that I found on the web server. Still don’t have access to load balancer server.

I also started to have SSL issues, since I added Sucuri firewall server in front of the load balancer server. Would you know how to go about this? From Sucuri docs I see that I can add my own cert hence I’m guessing I’d need to get rsa and private key from current HAProxy config.

global
	log /dev/log	local0
	log /dev/log	local1 notice
	chroot /var/lib/haproxy
	stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
	stats timeout 30s
	user haproxy
	group haproxy
	daemon

	# Default SSL material locations
	ca-base /etc/ssl/certs
	crt-base /etc/ssl/private

	# See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
        ssl-default-bind-ciphers ECDHE....
        ssl-default-bind-ciphersuites TLS_AES_128_GCM....
        ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets

defaults
	log	global
	mode	http
	option	httplog
	option	dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
	errorfile 400 /etc/haproxy/errors/400.http
	errorfile 403 /etc/haproxy/errors/403.http
	errorfile 408 /etc/haproxy/errors/408.http
	errorfile 500 /etc/haproxy/errors/500.http
	errorfile 502 /etc/haproxy/errors/502.http
	errorfile 503 /etc/haproxy/errors/503.http
	errorfile 504 /etc/haproxy/errors/504.http

frontend http-in
        bind *:80
        #add support for ssl
        bind *:443 ssl crt /etc/ssl/certs/sslredacted.pem
        mode http
        option httpclose
        option forwardfor
        option http-server-close
        acl url_backend         path_sub        -i admin /api/ admin_indexers /key/
        acl url_backend         path_beg        -i /.well-known /api.php /blog/
        use_backend web-backend         if url_backend
        default_backend web-servers

backend web-backend
        mode http
        reqadd X-Forwarded-Proto:\ https
        balance roundrobin
        #enable 302 redirect http -> https
        redirect scheme https if !{ ssl_fc }

        #to web-backend
        server web 127.0.0.1:8081 check
        #Varnish
        #server varnish 127.0.0.1:6081 check

backend web-servers
        mode http
        reqadd X-Forwarded-Proto:\ https
        balance roundrobin
        #enable 302 redirect http -> https
        redirect scheme https if !{ ssl_fc }

        #to web-backend
        server web 127.0.0.1:8081 check
        #Varnish
#        server varnish 127.0.0.1:6081 check

Quick #notsponsored remark: If you are planning on replacing your infrastructure with something else and have not previously considered HAProxy, I recommend it to anyone needing a super-efficient and highly configurable load balancer. Just feels wrong not to say that here. :slightly_smiling_face:

/etc/ssl/certs/sslredacted.pem contains your certificate, private key, and potentially intermediate certificates in PEM format. I don’t know anything about a Sucuri firewall, but if it intercepts HTTP traffic, it almost certainly needs some certificate information.

There’s a non-zero chance that your load balancer is presenting a different certificate. If so, the certificate in this file may only be used to validate the connection between this web server and the load balancer in front of it. You may want to make sure it’s the one you want before you import it.

I read this as your load balancer is also running HAProxy? If so, the configurations may look very similar. On this server, you have two backends, but as far as I can tell, they are exactly the same. I won’t cover every line, but here’s the parts that are probably important to you:

# Frontend covers incoming requests. This one is called "http-in"
frontend http-in
        # This frontend should listen on port 80
        bind *:80

        # This frontend should also listen on 443 and use SSL for this port.
        # For SSL, use the certificate info in this file.
        bind *:443 ssl crt /etc/ssl/certs/sslredacted.pem

        # If the path contains admin, /api/, admin_indexers, or /key/
        # then set "url_backend" to TRUE
        acl url_backend path_sub -i admin /api/ admin_indexers /key/

        # If the path begins with /.well-known, /api.php, or /blog/
        # then set "url_backend" to TRUE
        acl url_backend path_beg -i /.well-known /api.php /blog/

        # If "url_backend" is TRUE, send it to the backend called "web-backend"
        use_backend web-backend if url_backend

        # Any traffic without a destination backend should be sent here
        default_backend web-servers

# This backend is called "web-backend" and defines a destination for requests.
backend web-backend
        # Redirect to "https" if ssl is not present
        redirect scheme https if !{ ssl_fc }

        # This is the destination!
        # Syntax is 'server <name> <address:port> <options>'
        # "check" means that HAProxy is performing health checks
        server web 127.0.0.1:8081 check

I hope this helps! Feel free to keep asking questions!

1 Like

Hi @stormrover

Thanks a lot for detailed help.
I managed to extract SSL from the load balancer server and upload that to Sucuri.
That was the one. Sucuri immediately recognized the certificate so now we have secure connection.

What I do see is that cert will expire in February. Is there a specific way to renew this in HAProxy?

We managed to clean up the files from all the malware. For the sake of my time I decided not to deploy additional web server which gives me time to go through HAProxy docs. Thanks a lot for the explanations within my config file!

Much appreciated!

It’s nothing special. Once a new certificate and key is obtained, it can be put in the same file as it is in the current file or in a new file with the same structure. If I recall correctly, the order, top to bottom, is

  • Private Key
  • Certificate
  • Intermediate (Optional)
  • Root (Optional)

If putting in a new file, it will need to be configured in HAProxy by modifying bind *:443 ssl crt </path/to/new/cert/file>.

You can test the syntax of any configuration changes by running haproxy -c -f </path/to/config/file>. Example: haproxy -c -f /etc/haproxy/haproxy.cfg

HAProxy needs to be reloaded for changes to take effect. On Debian-based systems, this can be done with service haproxy reload or systemctl reload haproxy.service.

Edit: If you have the option to reload or restart the service, choose to reload. I’m not sure what version of HAProxy you are running, but newer versions are very smart about reloading and will let current requests finish out before killing the workers, while new workers will start up and start receiving requests before the old workers are gone. This helps avoid interruptions in active connections, making the reload invisible to end users. Restarting will tell workers to stop quickly and is not seamless. Though it would be seen as a small blip, restarts are more noticeable to end users.

1 Like

Thanks a lot @stormrover .

You helped me a lot. I’ll experiment with SSL beginning of Feb. I checked, it expires on 18th so we’re good in January.

Thanks a lot again!

1 Like