How to define basic authentication on HAProxy

Define basic authentication on HAProxy load balancer limit access to specific backends.

HAProxy version.

$  haproxy -v
HA-Proxy version 1.7.5-2 2017/05/17
Copyright 2000-2017 Willy Tarreau <[email protected]>

Default HAProxy configuration.

global
	log /dev/log	local0
	log /dev/log	local1 notice
	chroot /var/lib/haproxy
	stats socket /run/haproxy/admin.sock mode 660 level admin
	stats timeout 30s
	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/
	# An alternative list with additional directives can be obtained from
	#  https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy
	ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
	ssl-default-bind-options no-sslv3

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

Install whois package to use mkpassword utility - an overfeatured frontend to the crypt function.

$ sudo apt-get install whois

Generate hashed passwords. You can use DES, MD5, SHA-256 or SHA-512.

$ printf "password" | mkpasswd --stdin --method=des
ASYRtiLFCipT6
$ printf "secondarypassword" | mkpasswd --stdin --method=md5
$1$R29iAdV/$1QUKx8eo6e5pcMIEgaZwt0
$ printf "thirdpassword" | mkpasswd --stdin --method=sha-256
$5$gZZsvtRWI$9JIU8pfHLG8BtYW5tceAKD1oNAjjfL5e4LwUfAW1sqA

Note, you need whois package to use mkpassword an overfeatured front end to crypt.

Create user list that describes users and groups.

userlist basic-auth-list
  group is-regular-user
  group is-admin

  user admin  password ASYRtiLFCipT6                                            groups is-admin
  user michal password $5$gZZsvtRWI$9JIU8pfHLG8BtYW5tceAKD1oNAjjfL5e4LwUfAW1sqA groups is-regular-user
  user milosz password $1$R29iAdV/$1QUKx8eo6e5pcMIEgaZwt0                       groups is-regular-user
  user guest  insecure-password guestpassword

Create ACL rule inside backend section that will allow every user defined in specified userlist.

acl draw-auth http_auth(basic-auth-list)
http-request auth realm draw unless draw-auth

Create ACL rule inside backend section that will allow users who belong to group is-admin defined in specified userlist.

acl devops-auth http_auth_group(basic-auth-list) is-admin
http-request auth realm devops unless devops-auth

Create ACL rules inside frontend section that will allow users who do not belong to is-admin or is-regular-user groups defined in specified userlist.

acl is-guest hdr_dom(host) -i guest.example.org
acl is-basic-auth-user http_auth(basic-auth-list)
acl is-basic-auth-user-with-group  http_auth_group(basic-auth-list) is-admin is-regular-user
http-request auth realm guest if is-guest !is-basic-auth-user OR is-guest is-basic-auth-user-with-group
use_backend web-guest-production if is-guest

Sample frontend and backend using the specified ACL rules.

userlist basic-auth-list
  group is-regular-user
  group is-admin

  user admin  password ASYRtiLFCipT6                                            groups is-admin
  user michal password $5$gZZsvtRWI$9JIU8pfHLG8BtYW5tceAKD1oNAjjfL5e4LwUfAW1sqA groups is-regular-user
  user milosz password $1$R29iAdV/$1QUKx8eo6e5pcMIEgaZwt0                       groups is-regular-user
  user guest  insecure-password guestpassword


frontend web
  bind :80
  #bind :443 ssl crt /etc/ssl/cert/

  option httplog
  log /dev/log local0 debug

  option forwardfor except 127.0.0.1
  option forwardfor header X-Real-IP

  #redirect scheme https code 301 if !{ ssl_fc }

  # allow every defined user using acl defined in backend
  acl is-draw hdr_dom(host) -i draw.example.org
  use_backend web-draw-production if is-draw

  # allow every defined user in admin group using acl defined in backend
  acl is-devops hdr_dom(host) -i devops.example.org
  use_backend web-devops-production if is-devops

  # allow every defined user not in admin, regular groups
  acl is-guest hdr_dom(host) -i guest.example.org
  acl is-basic-auth-user http_auth(basic-auth-list)
  acl is-basic-auth-user-with-group  http_auth_group(basic-auth-list) is-admin is-regular-user
  http-request auth realm guest if is-guest !is-basic-auth-user OR is-guest is-basic-auth-user-with-group
  use_backend web-guest-production if is-guest


backend web-draw-production
  acl draw-auth http_auth(basic-auth-list)
  http-request auth realm draw unless draw-auth

  mode http
  server draw 10.0.10.15:80

backend web-devops-production
  acl devops-auth http_auth_group(basic-auth-list) is-admin
  http-request auth realm devops unless devops-auth

  mode http
  server devops 10.0.10.16:80

backend web-guest-production
  mode http
  server guest 10.0.10.17:80

Notice, you can define basic auth using frontend or backend.

About Milosz Galazka

Milosz is a Linux Foundation Certified Engineer working for a successful Polish company as a system administrator and a long time supporter of Free Software Foundation and Debian operating system. He is also open for new opportunities and challenges.