Netgate Discussion Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Search
    • Register
    • Login

    Redirect HTTP to HTTPS whilst allowing ACME challenges through the 'Standalone HTTP server' method (with ACME and HAProxy)?

    Scheduled Pinned Locked Moved General pfSense Questions
    4 Posts 2 Posters 1.4k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • _
      _mbx_
      last edited by

      I use my pfSense with ACME and HAProxy extensions to manage and auto-renew certificates as well as having a reverse proxy with load balancing capabilities. In my ACME module I define my domains to challenge for like so:

      In my domain SAN list I have my enabled domain with the method type 'Standalone HTTP server'.

      This means once my certificate will be re-newed, a standalone HTTP server will be launched that will listen on port 80. The 'well known acme challenge' files will be reached on such server and my certificate will be validated.

      Now I'd like to redirect all HTTP traffic to HTTPS in the reverse proxy (HAProxy frontend) of pfSense. For this, I could setup a new frontend that listens on the WAN address on port 80 in the HAProxy module that will redirect if the path does not start with /.well-known/acme-challenge/ like so:

      In the Access Control List (ACL) I define a rule called "acme" with the expression "Path starts with" and the value . In the Actions table I would add the action  with the child Action  for the condition acl names .

      So if the path starts with /.well-known/acme-challenge/, no redirect will occur, but if not, the HTTP request will respond with a Location header to the HTTPS version of the requested URL. The ACL conditioning works so far, but my problem is that HAProxy will now return "503 Service Unavailable - No server is available to handle this request." when I request anything within /.well-known/acme-challenge/.

      This is obvious: HAProxy started to listen on the port 80 of the WAN address, so my Standalone HTTP server gets shadowed by it. HAProxy can only return error 503 as it doesn't know what pfSense itself would do with such request.

      What I think I need to do is to setup a backend that I send the request to, if the request's path starts with /.well-known/acme-challenge/, but how do I have to setup such backend in HAProxy, so it works with the Standalone HTTP server of the ACME module?

      I've tried to add a backend for 127.0.0.1:80 as well as the IP of my host on port 80. I then added another Action on my frontend in HAProxy with the Condition acl names acme to such backend, but I still get error 503 and this is not due to the fact that my standalone server is not running yet. I get the same error when I try to run the ACME challenge with the Let's Encrypt Staging Environment.

      [The log says: Verifving; Standalone mode server; Pending, The CA is processing your order, please just wait. (1/30); socat989891 E write(6, 0x800add000, 39): Broken pipe
scat!209211 E write(6. 0x800add000. 126): Broken pipe
.com:Verify error:...: Invalid response from http://.../.well-known/acme-challenge/...

      In one example my default HAProxy Backend has 192.168.0.1:80 in its server list (IP of PfSense in the LAN).

      The redirection of ACME requests to the backend are put in the first row in the action table of the frontend.

      How can I make the ACME Standalone HTTP server as well as my HTTP to HTTPS redirection co-exist without any problems?

      1 Reply Last reply Reply Quote 0
      • stephenw10S
        stephenw10 Netgate Administrator
        last edited by

        Hmm, interesting problem.

        Is there no way you can use on of the other methods?

        _ 1 Reply Last reply Reply Quote 1
        • _
          _mbx_ @stephenw10
          last edited by

          This post is deleted!
          1 Reply Last reply Reply Quote 1
          • _
            _mbx_
            last edited by

            I don't know what I did wrong previously, but I re-attempted it and managed to get it to work with the same thought processing in mind. I created a backend that will be my local web server:

            - Open HAProxy/Backend and add a new backend entry, named , which forwards to  port

            My http/https offloader (front-end) defines a path rule and redirects to such backend if we have an ACME challenge:

            - Edit your frontend, which shall be named  and is triggered by any external address with port

            - Under "Access Control List" add an entry called  with the expression "Path starts with:", CS: no (not case-sensitive), Not: no (no inversion) and the value

            - You now need two actions, one for the condition name  and one for .  should offload using the action "http-request redirect" with the rule  while  should use the action "Use Backend" with the previously created local backend

            Maybe it was the ordering of the actions, maybe it was the naming. I was pretty confident that I tested my previous setup with 127.0.0.1 as well, but this seems to work and I don't know why it did not work previously.

            Now it was very easy to confirm the configuration is right when using postman. Say you have the domain example.org, you should do a GET request to two different URLs to validate their response:

            • http://example.org/foobar: Should return a Location header with the https version of the URL, so confirming the offloader works
            • http://example.org/.well-known/acme-challenge/foobar: Should timeout! It must not return an error immediately, or the configuration is wrong. If the configuration is right, it will try to talk to the standalone HTTP server that only runs during the ACME challenge, so it will timeout with 503 Service Unavailable after 60 seconds or so, which means it will succeed if the standalone HTTP server is running.

            With this setup the "Standalone HTTP server" method will work.

            1 Reply Last reply Reply Quote 1
            • First post
              Last post
            Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.