No doubt by now you’ve heard about the buzz around the cloud. Probably you’ve already used it too, either played with it or used it for a personal project.
You might have ideas on how to use the many tools provided around virtualization in cloud to improve your own working environment, but are unable to. Perhaps because you can’t move all of your stack to the cloud, or can’t get permission to do so, or simply because the existing stack is a monolithic/archaic beast that nobody dares to move or touch in fear it might burn down.
Fortunately “moving to the cloud” doesn’t have to mean moving everything you already have but instead developing the new services for the cloud – a more gradual approach.
Problem
Accessing the ‘monolith’ back home. In many cases the new services you’ll be developing might depend on the existing infrastructure. Perhaps there is a database without a public IP, or there is a service you can’t access, or your sysadmin would prefer not setting up hundreds of new firewall rules, specifically for you.
Solution
Proxy. Routing the required, or all, traffic through a proxy running on your local environment. This provides an easily manageable, monitorable node from where your cloud services may arise.
Setup
For the proxy we’ll be using one linux machine with ubuntu 16/18 and a HAProxy installation. Although the differences between distributions are usually minimal for these cases, so you can probably use what you’re used to. Except for the firewall, where ubuntu provides ufw
for a simple firewall configuration tool.
Installation
Once your local proxy machine is up and running let’s intall haproxy on it. sudo apt install haproxy
Configuration
- Enable HAProxy in the init script by editing
/etc/default/haproxy
Add this line:ENABLED=1
. Save and quit. This will ensure that HAProxy runs during startup, should the server be forced to restart.
2. Let’s start configuring the proxy itself.sudo vim /etc/haproxy/haproxy.cfg
The configuration file should include the basic global and default values.
The easiest way to create a routing is to add a listen block.
listen con_name
bind :1444 interface ens160
mode tcp
timeout client 3600s
timeout server 3600s
option clitcpka
balance roundrobin
server internal_database 10.2.2.2:1433
Let’s dissect this line by line
listen con_name
Creating a new socket with the name con_name
bind :1444 interface ens160
bind the socket to the machines ip, on port 1444, you can exchange the port to whatever fits your network. The interface ens160 part is optional, and allows you to bind to only selected network interfaces, ens160 being the interface name.
mode tcp
HAProxy has 2 main modes, http and tcp. Choose this based on your needs.
timeout client 3600s
and timeout server 3600s
Timeouts are quite a complicated topic and in most cases there is no “golden standard”. Look into what services you are connecting to this proxy and choose based on that. Here however is a starting point for http connections too.
timeout connect 5000
timeout check 5000
timeout client 30000
timeout server 30000
option clitcpka
Send TCP keepalive request. Incase your server has lower timeout values.
for http mode the equivalent is option http-keep-alive
balance roundrobin
HAProxy is much more then a proxy, it’s also a load-balancer, a great bonus to have, which adds enormous amouts of flexibility.
This option dictates how the next server should be chosen. Roundrobin being the simplest, just direct the request to the next server in the list.
You can read more about all the options on their docs at HAProxy version 1.9.0 – Configuration Manual
server internal_database 10.2.2.2:1433
And this is our internal target where we proxy our connections to. internal_database is just a name for the server. You can add multiple of those lines to use the loadbalancing feature of HAProxy.
Save and quit the file, restart haproxy with sudo service haproxy restart
3. Staying safe behind a firewall. The following steps only apply on ubuntu.
Enable ufw and create the rules for your instance
The following steps only apply on ubuntu.
Enable ufw and create the rules for your instance
sudo ufw default deny #Drop all unneccasary connections
sudo ufw allow 22/tcp #Allow SSH
sudo ufw allow 1444/tcp # Your proxy connections
sudo ufw allow 1433/tcp
sudo ufw enable #Enable Firewall
You should be able to connect to your target through the proxy.
4. Monitoring the proxy. Go back and add the following block to the haproxy configuration file, substitute the user:password with your own values and change the port or uri if you wish.
listen stats
bind :9001
mode http
stats enable
stats hide-version
stats realm Haproxy\ Statistics
stats uri /haproxy_stats
stats auth user:password
After adding this, restart the proxy again and navigate to proxy_ip:9001/haproxy_stats and login with your account. You should see the basic stats for your proxy.
5. Configuring the Access-Control-List (ACL) for further safety. Wouldnt want others accessing our entrypoint, so let’s limit access to us only. Open up the haproxy configuration file and add the following to the con_name socket configuration
acl allowed_ips src 1.2.3.4 5.6.7.8
tcp-request connection reject if !allowed_ips # For TCP mode
block if !network_allowed # For Http mode
Lets dissect this yet again:acl allowed_ips src 1.2.3.4 5.6.7.8
Defines a list named allowed_ips where the connection source matches those ips. Use the IP addresses of your virtual machines in the cloud or any other service that you want to use with this proxy.
If you wish for even more extensibility then you can load the list of addresses from a file with the -f flag.
Ex: acl allowed_ips src -f /path/to/file.txt
tcp-request connection reject if !allowed_ips
For TCP mode sockets, limit connections only to those in the allowed_ips ACL
block if !network_allowed
Same as above but for HTTP sockets
Save and quit the configuration file, restart the proxy yet again with sudo service haproxy restart
and check your connection.
Conclusion
Alright, this should cover the basics and get you started with haproxy. Hopefully now you can start building your future-proof cloud services without having to worry about the old-man back home.