Skip to main content

HAproxy

HAproxy is fantastic reverse proxy with a massive amount of features. Knocknoc has supported HAproxy for years, and integrates with it natively. TheHAproxy vastcan amountbe a little confusing at first due to its wide array of options and implementations, for HAproxynow can make it confusing at first, however we canwe'll walk through thesome barebasic essentials to be able to use Knocknoc, and you can extend it from there.

If you wanted to protect an arbitrary web application,configuration for example a legacy PHP app, or Atlassian Confluence, we would recommend deploying HAproxy to situse in front of theConfluence. application,

Note: If you are reading this page, you should already have your Knocknoc Server and useAgent Knocknocsetup toas controlthis access. Thisguide will oftenassume beyou anare easierat deploymentleast path,aware andof isthe afeatures costbeing effective security measure for many reasons.

addressed.

HAproxy Configuration via the Admin socketSocket

Knocknoc supports HAproxy's admin socket directly, so you can just configure the socket path, adjust the permissions and away you go.

image.png

You can see fromsocket, this screenshot,interaction whenis youhow createthe aaccess newcontrol backend,list you(ACL) can selectwithin HAproxy asis the socket type, and then add the path. This implies your knocknoc-agent 'test' can read and write directly to the socket. One wayupdated to allow your users to access the protected application behind. For this guide we are going to make a few assumptions, the first is that you have a Linux based system and the second is the Knocknoc Agent and HAproxy is installed already.

  1. First, we need to add the knocknoc-agent useruser, to the haproxy group:

    group. This allows the knocknoc-agent to access and modify the HAproxy socket.

    adduser knocknoc-agent haproxy
  2. Then we need to map out a HAproxy configuration file with a few things to ensure we are looking at the right socket, are using an ACL and that ACL is in use for accessing confluence.

    vi /etc/haproxy/haproxy.cfg
  3. The first thing to check and not here is the socket configuration under the global section, this item should list the location of the socket, the permissions set and the user and group that has access, for example.

    stats socket /run/haproxy/admin.sock mode 0666 level admin user haproxy group haproxy

    Works 

  4. Next, we need to configure our frontend definition, in our example we are protecting a Confluence instance. In this example we are listening for HTTP traffic on debian,all orinterfaces equivalent.on port 443 and HAproxy is providing the SSL verification from the certificates within the provided directory.
    frontend https_frontend 
     mode http
     bind *:443 ssl crt /etc/ssl/private/ alpn h2,http/1.1

     

  5. There are 3 ACL's defined here;
    1. acl is_confluence hdr(host) confluence.mycompany.com any traffic hitting the url defined here is marked with the ACL "is_confluence"

    2. acl is_http hdr(X-Forwarded-Proto) http any traffic that is HTTP and not HTTPS is marked with ACL "is_http"

    3. acl knoc_confluence src -u 500 lastly, is the interaction with Knocknoc, this ACL checks the admin socket from step 3 above. If a user has logged into knocknoc and is a part of the security group that is approved for that ACL their IP will be reserved in ACL-ID 500 and traffic from those IP's is marked with the ACL "knoc_confluence"

      acl is_confluence hdr(host) confluence.mycompany.com
      acl is_http hdr(X-Forwarded-Proto) http
      acl knoc_confluence src -u 500

       

  6. The second to last entry in the frontend definition tells HAproxy if traffic is marked with the ACL "is_http" redirect it to HTTPS. Forcing all traffic to be encrypted.
     redirect scheme https if is_http 
  7. The last line, indicates traffic that is marked with the ACL's "is_confluence" and "knoc_confluence" is the use the backend definition "confluence_backend"

    use_backend confluence_backend if is_confluence knoc_confluence

     

  8. The last thing to do is define the backend definition we are going to target in the above frontend. A few things to note;
    1. The backend name has to match the name used in the frontend.
    2. The mode in almost all cases should match the frontend.
    3. The server definition must contain a name, IP:Port at the very least.
  9. In the following example, our server line contains the name confluence_server, with an IP and Port. The additional config of "check ssl verify none" tells HAproxy to check the backend server on the port to see if the server is alive and to ignore verifying the SSL certificate. This means SSL only need to be maintained on HAProxy, reducing management overhead.
     
    backend confluence_backend 
     mode http
     server confluence_server 192.168.0.200:443 check ssl verify none

     

There is a lot, lot more that can be done with HAProxy the more familiar you become with it the more confident you will be to use it. Tied with Knocknoc's security integration it can become a fundamental cog in your security machine. Should you need further assistance feel free to reach out to one of our support partners.

HaproxyKnocknoc Configuration

  1. Within the Knocknoc Servers admin interface, a backend will need to be created. The agent will be the one installed on this server, and the address needs to be the path specified in the Global config of HAproxy for the socket.
    image.png
  2. Then we need to create an ACL using the above backend. The ACL name needs to match the ACL ID used in the HAproxy config.
    image.png
  3. Now we need to add a Security Group and add this ACL to the security group to allow the IP of the users within the group to be added to ACL 500. Now user

Additional Configuration Notes

HAproxy TCP Socket

The HAproxy backend also supports a TCP socket, in which case it still expects to talk to the unix socket, but it can do so via a TCP redirect. This is most easily accomplished with the spiped utility.

knocknoc-agent ships with a script make-spiped-tunnel.sh which can walk you through making an spiped encrypted tunnel between your knocknoc-agent machine and a remote haproxy. It is often easier to deploy knocknoc-agent directly to a machine, but in case this isn't possible, you can use an spiped tunnel for this purpose.

Haproxy Configuration

Haproxy configuration is vast topic, however here is a minimal config for the seasoned admin to get started quickly:

frontend https_frontend 
 mode http
 bind *:443 ssl crt /etc/ssl/private/ alpn h2,http/1.1

 acl is_confluence hdr(host) confluence.mycompany.com
 acl is_http hdr(X-Forwarded-Proto) http
 acl knoc_confluence src -u 500

 redirect scheme https if is_http 
 use_backend confluence_backend if is_confluence knoc_confluence

backend confluence_backend 
 mode http
 server confluence_server internal_confluence_ip:443 check ssl verify none

This config snippet sets up an HAproxy fronted on port 443, with certs served from the directory /etc/ssl/private and enabled HTTP2.

Then it sets up some ACLs for the hostname and Knocknoc to update (ACL ID 500).

Then the use_backend directive only allows connections to the backends if the hostname matches confluence.mycompany.com AND the list of source IPs in ACL 500.

Knocknoc will then be configured using the ACL setting pane to have ACL 500 map to this backend on this agent:

image.png

Then this ACL needs to be added to a Group, and any user in that group will have their Source IP added to ACL 500 when they authenticate OK to Knocknoc!

Error Responses

HAproxy can easily send custom 403 or 503 responses to users who aren't allowed to access the backend resource. For example:

image.png

 

This is configured as the default_backend error response in the haproxy config, so if the http request doesn't match the right source IP or hostname, the above is show to the browser. An admin can customise this to display whatever you like, but keep in mind its an HTTP response, not an HTML page, so there are limitations. You could of course link people to your Knocknoc instance in the error message, depending on your users and risk profile.

Full haproxy.cfg example

Below is a full example of a basic default HAProxy configuration file completed with the setting from above.

global
  log /dev/log local0
  log /dev/log local1 notice
  stats socket /run/haproxy/admin.sock mode 0666 level admin user haproxy group haproxy
  user haproxy
  group haproxy
  daemon
  # Default SSL material locations
  ca-base /etc/ssl/certs
  crt-base /etc/ssl/private
  # Default ciphers to use on SSL-enabled listening sockets.
  # For more information, see ciphers(1SSL). This list is from:
  #  https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
  ssl-default-bind-ciphers kEECDH+aRSA+AES:kRSA+AES:+AES256:RC4-SHA:!kEDH:!LOW:!EXP:!MD5:!aNULL:!eNULL
  ssl-default-bind-options no-sslv3
  # Default ciphers to use on SSL-enabled listening sockets.
  # For more information, see ciphers(1SSL). This list is from:
  #  https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
  ssl-default-server-ciphers kEECDH+aRSA+AES:kRSA+AES:+AES256:RC4-SHA:!kEDH:!LOW:!EXP:!MD5:!aNULL:!eNULL
  ssl-default-server-options no-sslv3
  nbproc 1

# Defaults
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

# Userlist

# Resolvers

# Listen

frontend https_frontend 
 mode http
 bind *:443 ssl crt /etc/ssl/private/ alpn h2,http/1.1

 acl is_confluence hdr(host) confluence.mycompany.com
 acl is_http hdr(X-Forwarded-Proto) http
 acl knoc_confluence src -u 500

 redirect scheme https if is_http 
 use_backend confluence_backend if is_confluence knoc_confluence

backend confluence_backend 
 mode http
 server confluence_server 192.168.0.1:443 check ssl verify none