Using HAProxy to support the ACME Let's encrypt package endpoint validation



  • Hi Guys,

    I've been configuring a local setup with ACME package for Let's encrypt certificates and HAProxy and because of questions I got I decided to share this "experience".
    My goal was to let the ACME package and HAProxy work "together" in that respect that:

    • HAProxy got it's certs "renewed" automatically (That's actually what the ACME package does)

    • ACME package could validate against the random generated backend URL for ALL renewals (This is kindof the "tricky" part)

    Now please note that I am no ACL wizard and configuring this way might be considered not the way to do it.
    I'm not to blame for any bad effects caused by this setup and I'd like someone to reflect on my configs.
    Since this is running in my home setup any risk is only on my own side.

    I have created two frontends:

    • ACME-Challenge: used for redirecting all of the /.well-known/acme-challenge

    • ACME-Server: used to actually provide an endpoint to serve the /.well-known/acme-challenge requests and thus host the files ACME wants to see

    The frontends connect to two backends:

    • ACME-Redirect: used for redirecting properly executing the redirect

    • ACME-Server: used to serve the /.well-known/acme-challenge requests and thus host the files ACME wants to see

    The ACME-Challenge Frontend has this setup:
    It is running on my default frontend and has this ACL:

    acmeredir	Path starts with:	no	/.well-known/acme-challenge
    

    The action included with this is

    Use Backend	See below	acmeredir
    

    Pointing to my backend

    backend: ACME-Redirect
    

    This backend has some custom code that redirects to a different URL.
    I couldn't get this to be done from the frontend due to some order issue with the rules so kicking to backend and redirecting looked like the most proper "workaround".

    The ACME-Redirect Backend has this setup:
    Server list looks like

    	active	local	Address+Port:	127.0.0.1	8080	no	
    

    In this case the request is redirected to the internal HAProxy listening port

    In the ACL list I have

    acmerewrite	Path contains:	acme-challenge
    

    And as action

    Custom	See below	acmerewrite
    
    customaction: reqirep ^Host: Host:\ acme.myhostname.com
    

    This makes sure that all the ACME requests are pointed towards a single hostname (served by the firewall).

    –----

    The ACME-Server Frontend has this setup:
    I have two ACL rules to make sure no other requests end-up at the firewall internal sites:

    acme1	Host starts with:	no	acme
    ```   
    

    acme2 Path starts with: no /.well-known/acme-challenge

    
    The action involved and attached to this ACL is:
    

    Use Backend See below acme1 acme2

    Pointing to my backend
    backend: ACME-Server
    
    The **ACME-Server** Backend has this setup:
    The serverlist contains just this
    

    active local Address+Port: 127.0.0.1 8080 no

    
    This way the backend is served BY the firewall.
    
    In the ACME config I have this setup:
    ![](https://image.ibb.co/mA6Uva/ACME_Config.png)
    
    This makes that the "Challenge" files are written to the appropriate folder.
    
    Note1: I probably created this folder by hand; it survives a reboot
    Note2: that it's probably a good idea to clean that folder up now and than.


  • First of all, thanks!

    Could you explain me these section? ->  customaction: reqirep ^Host: Host:\ acme.myhostname.com

    What do i have to type for acme.myhostname.com ?



  • @fluxx:

    First of all, thanks!

    Could you explain me these section? ->  customaction: reqirep ^Host: Host:\ acme.myhostname.com

    What do i have to type for acme.myhostname.com ?

    You should type a domain name that ends up at the WAN IP address of your firewall on which you have your HAProxy service running.
    My DNS has a wildcard setup pointing all *.mydomain.com to the IP address my firewall is on.

    You define this specific address so HAProxy knows it is serving from it's localhost instead of another backend system.



  • When I try to request a certificate, I get an error.
    The manual call of the URL supplies a service unavailable.

    http://aaa.bbb.com/.well-known/acme-challenge/key [123.123.123.123]: 503

    I think the ACME-Backend works not as expected.
    How can I configure the firewall/HAProxy to listen on port 8080 for serving the files ACME wants to see?


Log in to reply