{"id":15813,"date":"2018-10-14T08:32:45","date_gmt":"2018-10-14T08:32:45","guid":{"rendered":"https:\/\/blog.taragana.com\/?p=15813"},"modified":"2019-09-09T11:00:25","modified_gmt":"2019-09-09T11:00:25","slug":"guide-haproxy-http-basic-authentication-for-specific-sites-ssl-termination","status":"publish","type":"post","link":"https:\/\/blog.taragana.com\/guide-haproxy-http-basic-authentication-for-specific-sites-ssl-termination-15813","title":{"rendered":"Guide: HAProxy HTTP Basic Authentication for specific sites (SSL Termination)"},"content":{"rendered":"\n

Objective<\/h2>\n\n\n\n

I use HAProxy to serve multiple SSL\/TLS enabled sites with HAProxy doing SSL termination. The sites serve regular HTTP while users see proper HTTPS sites (with free certificates from LetsEncrypt). My objective was to provide HTTP Basic Authentication as a second layer of protection for certain applications like NextCloud (DropBox clone) or Gitea (GitHub clone).<\/p>\n\n\n\n

Challenges<\/h2>\n\n\n\n

I wanted to provide HTTP Basic Auth over specific services (not all which is much easier) which didn’t natively support them like Gitea. Secondly, I wanted it to be transparent to the underlying Application. Thirdly, I didn’t want to provide plain-text passwords in haproxy.cfg.<\/p>\n\n\n\n

Solution<\/h2>\n\n\n\n

After few iterations I arrived at a simple solution to the problem. The steps are:<\/p>\n\n\n\n

  1. Create users with encrypted passwords
    <\/li>
  2. Add users to haproxy.cfg<\/li>
  3. Force authentication for specific sites on frontend<\/strong><\/li>
  4. Remove authorization on backend<\/strong><\/strong><\/li><\/ol>\n\n\n\n

    Create users with encrypted passwords<\/h2>\n\n\n\n

    To create encrypted passwords, you need a tool called mkpasswd<\/strong> which is available with whois<\/strong>, so you need to install it first (one time activity):
    <\/p>\n\n\n\n

    sudo apt install whois<\/code><\/pre>\n\n\n\n

    Create password as shown below (replace Password<\/strong> with your actual Password):<\/p>\n\n\n\n

    mkpasswd -m sha-512 Password<\/code><\/pre>\n\n\n\n

    Copy the encrypted password generated by the tool (mkpasswd).<\/p>\n\n\n\n

    Add users to haproxy.cfg<\/h2>\n\n\n\n

    You can add multiple user lists as well as user groups (beyond the scope of this guide) to haproxy. Let’s create an user list named AuthUsers (as an example):<\/p>\n\n\n\n

    userlist AuthUsers\n        user Username1 password $6$d.\/LYD0vplX$XoPWiTQfhNt4g4NRcU\/toFiV89xhW524abcdfg\n        user Username2 password $6$d.\/LYD0vplX$XoPWiTQfhNt4g4NRcU\/toFefghxhW524abcdfg<\/code><\/pre>\n\n\n\n

    Replace Username1<\/strong>, Username2<\/strong> with your actual user names and the corresponding encrypted password as the last argument in the line.<\/p>\n\n\n\n

    You can add as many users as you want.<\/p>\n\n\n\n

    Force authentication for specific sites only<\/h2>\n\n\n\n

    Let’s say we want to force authentication for these two sites (in frontend section):<\/p>\n\n\n\n

    acl host_example1 hdr(host) -i example1.com\nacl host_example1 hdr(host) -i example2.com<\/pre>\n\n\n\n

    Below this we force them to be authenticated:<\/p>\n\n\n\n

    acl authorized http_auth(AuthUsers)\nhttp-request auth realm Example1 if host_example1 !authorized\nhttp-request auth realm Example2 if host_example2 !authorized<\/pre>\n\n\n\n

    Use backend<\/strong> only when properly authenticated:<\/p>\n\n\n\n

    use_backend example1 if host_example1 authorized\nuse_backend example2 if host_cexample2 authorized<\/pre>\n\n\n\n

    Remove authentication header from backend<\/h2>\n\n\n\n

    HAProxy for some strange reason sends this Authorization header to backend which sends certain servers in a loop. it is advisable to remove it.<\/p>\n\n\n\n

    backend example1\nhttp-request set-header X-Client-IP %[src]\nserver example1 example1:3000 check\nhttp-request del-header Authorization\n\nbackend example2\nhttp-request set-header X-Client-IP %[src]\nserver example2 example2:3000 check\nhttp-request del-header Authorization<\/pre>\n\n\n\n

    Now restart the haproxy server and voila!<\/p>\n","protected":false},"excerpt":{"rendered":"

    Objective I use HAProxy to serve multiple SSL\/TLS enabled sites with HAProxy doing SSL termination. The sites serve regular HTTP while users see proper HTTPS sites (with free certificates from LetsEncrypt). My objective was to provide HTTP Basic Authentication as a second layer of protection for certain applications like NextCloud (DropBox clone) or Gitea (GitHub […]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[12],"tags":[39,141,136,55,142,140,129,138,139],"_links":{"self":[{"href":"https:\/\/blog.taragana.com\/wp-json\/wp\/v2\/posts\/15813"}],"collection":[{"href":"https:\/\/blog.taragana.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.taragana.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.taragana.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.taragana.com\/wp-json\/wp\/v2\/comments?post=15813"}],"version-history":[{"count":4,"href":"https:\/\/blog.taragana.com\/wp-json\/wp\/v2\/posts\/15813\/revisions"}],"predecessor-version":[{"id":15882,"href":"https:\/\/blog.taragana.com\/wp-json\/wp\/v2\/posts\/15813\/revisions\/15882"}],"wp:attachment":[{"href":"https:\/\/blog.taragana.com\/wp-json\/wp\/v2\/media?parent=15813"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.taragana.com\/wp-json\/wp\/v2\/categories?post=15813"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.taragana.com\/wp-json\/wp\/v2\/tags?post=15813"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}