HAProxy isn’t just for securing HTTP; it can also be used to protect TCP-based services as well. One service that, when exposed to the Internet, is always under constant attack is SSH. In this lab, we’re going to get hands-on with HAProxy, using it to protect our SSH service. We’ll proxy our SSH service. Then we’ll set some connection boundaries in HAProxy, which should cut down on malicious traffic to our SSH service. Upon completion of the lab, you will be able to configure an HAProxy installation to protect a TCP-based service.
Learning Objectives
Successfully complete this lab by achieving the following learning objectives:
- Protect an SSH Service with HAProxy
Before we get started, let’s confirm that our SSH service is working.
- Check our containers using
podman
- Try pulling a file from our SSH container, directly, on the HAProxy server, using
scp
:- StrictHostKeyChecking=no
- UserKnownHostsFile=/dev/null
- port=2223
- cloud_user@ssh.site3.com
- file: /sshfiles/ssh-test.txt
Securing Our SSH Service Using HAProxy
In order to secure our SSH service, we need to add a
frontend
and abackend
to/etc/haproxy/haproxy.cfg
.Let’s make some changes to our
/etc/haproxy/haproxy.cfg
fileAdd a
frontend
for SSH namedssh-in
:- bind port 2222 to all addresses
- tcp mode
- use the sshd1 backend
Add a
backend
for SSH namedsshd1
:- tcp mode
- one server, sshd1-server1
- localhost, port 2223
- add a check for it
Restart the
haproxy
serviceTry pulling a file from our SSH container, via HAProxy, on the HAProxy server, using
scp
- StrictHostKeyChecking=no
- UserKnownHostsFile=/dev/null
- port=2222
- cloud_user@ssh.site3.com
- file: /sshfiles/ssh-test.txt
Running Some Basic Tests
Before we get started with protecting our sites with HAProxy, let’s take a look at what a stock HAProxy configuration looks like when presented with a large number of requests.
We’ll open our web browser, connect to port
8050
on our public IP/DNS, and go get thestats
information for our HAProxy installation.Let’s generate some SSH traffic on our local HAProxy host.
- Use a
for
loop to launch 1000scp
operations- Put each in the background
- Try pulling a file from our SSH container, via HAProxy, on the HAProxy server, using
scp
: - StrictHostKeyChecking=no
- UserKnownHostsFile=/dev/null
- port=2222
- cloud_user@ssh.site3.com
- file: /sshfiles/ssh-test.txt
We can see traffic moving through our
ssh-in
frontend
andsshd1
backend
. We’re ready to start setting some boundaries on SSH connections.Setting Some SSH Restrictions
We just dropped 1,000 SSH connections on our SSH service in short order. Even though our service has no problem handling that from a single client, it’s not a normal use case. We’d like to set some connection restrictions on our SSH service, so it can’t be overwhelmed by a single client.
We’re going to create a new
backend
to hold astick-table
to track SSH connections by client, namedssh_per_ip_connections
:- type ip
- size 1m
- expire 1m
- store
- conn_cur
- conn_rate(1m)
We’ll add the following to our SSH
frontend
: Use the TCP log format, set a 1 minute client timeout, and track our SSH connections in thessh_per_ip_connections
stick-table
we created. We’ll reject connections over 2 per client or if there are more than 10 connections in the span of 1 minute.- Check our containers using
- Test Your SSH Attack Protection
Testing Our SSH Restrictions
Now that we’ve set some boundaries on SSH connections, let’s test our work!
Before we proceed, let’s restart the
haproxy
service to pick up our configuration changes and reset our statistics.Let’s generate some SSH traffic on our local HAProxy host
- Use a
for
loop to launch 1000scp
operations- Put each in the background
- Try pulling a file from our SSH container, via HAProxy, on the HAProxy server, using
scp
- StrictHostKeyChecking=no
- UserKnownHostsFile=/dev/null
- port=2222
- cloud_user@ssh.site3.com
- file: /sshfiles/ssh-test.txt
Looking at the HAProxy
stats
web interface using a web browser, we can see that 2 connections succeeded, and 998 failed. Things are working!Let’s give our HAProxy server a minute to recover, then try some serial SSH connections.
- Try pulling a single file from our SSH container, via HAProxy, on the HAProxy server, using
scp
- StrictHostKeyChecking=no
- UserKnownHostsFile=/dev/null
- port=2222
- cloud_user@ssh.site3.com
- file: /sshfiles/ssh-test.txt
Repeating this, one
scp
at a time, until we are blocked, we can go until we hit our rate limit of 10 sessions per minute. Our SSH service is protected!- Use a