Recently I stuck with a dearth of Amazon Web Services Elastic Load-Balancer.(ELB)
My setup required SSL Mutual /Client authentication. Checked with AWS support
and they clarified that, as of now AWS ELB won’t support SSL client certificate
authentication. I looked for alternate solution. pfSense with HAProxy came to
my rescue. Thought this would be useful to me later for reference also to my team.
Hope this would be useful to some one evaluating alternate option for ELB.
My AWS VPC information used for this article.
Public Subnet: 10.20.0.0/24
Private Subnet: 10.20.1.0/24
First, we need to install pfSense Gateway from the market place.
IP and assign Elastic IP so that we can map this with DNS names later. Like any
other EC2 instance, you should be able to launch the pfSense on your designated
public subnet. Make sure you enable ports 22,80 and 443 are enabled in the
security groups. SSH to the box using your private key and set password
for the admin interface with cli option. After that you should be able
to have administrative access through the WAN interface. Also since
we are going to use HTTPS termination at pfSense, better we change
From EC2 console, you can add second interface as LAN and attach
that to the pfSense Gateway. LAN interface is part of your private subnet,
where you can have your application server. Let us assign the LAN Interface IP as 10.20.1.254 . You need to make sure security group attached to LAN interface allows required traffic from the private subnet.You also need to add the firewall rules on the LAN interface to allow traffic from the private subnet. In our case it is 10.20.1.0/24.
We also need to create separate route table for the private subnet and add
the routes through the pfSense gateway. Also need to associate this route table
with the private subnet. Below are reference screen shots.
After that associate this with private subnet as below:
This is not enough for you to access Internet from the application server.
You also need to disable source/destination check on both the interface of the
pfSense Gateway from EC2 console. This can be done with right click on the interface and Actions > Networking > Change Src Dest Check menu option. Below the output.
Please make sure this is done on both the interface of the firewall. With proper
security groups, Firewall rules on the interface and disabling the Src destination
check, you should be able to reach Internet from the application server.
Now we can install HAProxy on the pfSense firewall from the package manager.
After installation, we can see that is part of the installed packages as below.
HAProxy stats option is available from Status Menu as well.
We need to first create the back-end server pool. For this documentation purpose
we need to have only one back-end server, still for production you may create
more than one servers from the server list as part of Backend server pool. There are various load-balancing options available for production setup. In our
case we have 10.20.1.101 as the back-end server. Screenshot from my setup is
Please note that server is running on plain HTTP protocol and listening on
port 80. HAProxy comes with so many control options to manage client requests.
Leaving this for later exploration. I kept all other options with default value and
saved the back-end server pool. Before staring the front-end, we need to create required SSL CA certificates, Server Certificates and user certificates. This can be done from pfSense Certificate Manager menu. By default you can see that there is one NetGate VPN CA is available there. It is upto us to use the same CA or create a new CA. For avoiding the complexity let us use the available CA itself.
Let us create two certificates using the default CA.
- Server Certificate for the pfSense.
- User certificate sandeepas for client authentication.
Once the certificates and the back-end server pool is ready, we can
create the front-end as below. In this case we are using WAN address,
which is the main Elastic IP for front-end. We need to select port 443 and
select ‘SSL Offloading’ as below. Please remember that we have already
changed the management port to other than 443 to avoid conflicts.
There are various ACL option to get granular control over the client access.
Here I have selected accept any. On the actions side, we selected the back-end
server pool created before.
On SSL Offloading section, we need to select server certificate, which we need
to use. Here we have option to select various ACLs based on SSL certificate
characteristics say common-name, CA Name, Subject alternate names etc.
SSL Offloading, client certificates section is for controlling SSL client
authentication. Here you need to select the CA certificate, against which
all the user certificates are getting authenticated. Also we can use SSL client
verification revocation list (CRL). The list need to be non empty for Haproxy to
accept this section. Below is my setting.
Save this and apply the settings to make sure all the changes are taking effect.
After configuring this if you try to access the WAN Elastic IP through HTTPS, your accesswill be denied as you have not started using the client certificate in browser. You can export the user certificate from the Certificate Manager in PKCS#12 format. Ie with .p12 extn. This file can be directly imported to your browser as below.
After Importing the certificate to your browser, you would be able to access
HTTPS url. Since we are using self-signed certificate, you need to add exemption
for this SSL certificate to access the site. The the browser will give you the pop up as below to select the correct client certificate file as below.
that access is accepted only with valid client SSL certificate. The access to website will be denied without a valid client certificate from the selected Certificate Authority.