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

    Can HAproxy Backends work with self-signed certs

    Cache/Proxy
    3
    22
    3.9k
    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.
    • snide_remarksS
      snide_remarks @Derelict
      last edited by

      @derelict
      Last of the hoops to jump through [I think]. I think I have to use CNAME to verify I own the domain, but for the life of me could not see how that gets set up in ACME even after finding info on it.
      😸

      DerelictD 1 Reply Last reply Reply Quote 0
      • DerelictD
        Derelict LAYER 8 Netgate @snide_remarks
        last edited by Derelict

        @snide_remarks If you are not using a DNS method for verification of domain ownership with Let's Encrypt you have to be able to place a blob in the "well-known" location.

        For HAproxy I chose to run a script like this:

        -- ACME http-01 domain validation plugin for Haproxy 1.6+
        -- copyright (C) 2015 Jan Broer
        -- 
        -- usage:
        -- 
        -- 1) copy acme-webroot.lua in your haproxy config dir
        -- 
        -- 2) Invoke the plugin by adding in the 'global' section of haproxy.cfg:
        -- 
        --    lua-load /etc/haproxy/acme-webroot.lua
        -- 
        -- 3) insert these two lines in every http frontend that is
        --    serving domains for which you want to create certificates:
        -- 
        --    acl url_acme_http01 path_beg /.well-known/acme-challenge/
        --    http-request use-service lua.acme-http01 if METH_GET url_acme_http01
        -- 
        -- 4) reload haproxy
        -- 
        -- 5) create a certificate:
        -- 
        -- ./letsencrypt-auto certonly --text --webroot --webroot-path /var/tmp -d blah.example.com --renew-by-default --agree-tos --email my@email.com
        -- 
        
        acme = {}
        acme.version = "0.1.1"
        
        -- 
        -- Configuration
        -- 
        -- When HAProxy is *not* configured with the 'chroot' option you must set an absolute path here and pass 
        -- that as 'webroot-path' to the letsencrypt client
        
        acme.conf = {
        ["non_chroot_webroot"] = ""
        }
        
        -- 
        -- Startup
        --  
        acme.startup = function()
        core.Info("[acme] http-01 plugin v" .. acme.version);
        end
        
        -- 
        -- ACME http-01 validation endpoint
        -- 
        acme.http01 = function(applet)
        local response = ""
        local reqPath = applet.path
        local src = applet.sf:src()
        local token = reqPath:match( ".+/(.*)$" )
        
        if token then
        token = sanitizeToken(token)
        end
        
        if (token == nil or token == '') then
        response = "bad request\n"
        applet:set_status(400)
        core.Warning("[acme] malformed request (client-ip: " .. tostring(src) .. ")")
        else
        auth = getKeyAuth(token)
        if (auth:len() >= 1) then
        response = auth .. "\n"
        applet:set_status(200)
        core.Info("[acme] served http-01 token: " .. token .. " (client-ip: " .. tostring(src) .. ")")
        else
        response = "resource not found\n"
        applet:set_status(404)
        core.Warning("[acme] http-01 token not found: " .. token .. " (client-ip: " .. tostring(src) .. ")")
        end
        end
        
        applet:add_header("Server", "haproxy/acme-http01-authenticator")
        applet:add_header("Content-Length", string.len(response))
        applet:add_header("Content-Type", "text/plain")
        applet:start_response()
        applet:send(response)
        end
        
        -- 
        -- strip chars that are not in the URL-safe Base64 alphabet
        -- see https://github.com/letsencrypt/acme-spec/blob/master/draft-barnes-acme.md
        -- 
        function sanitizeToken(token)
        _strip="[^%a%d%+%-%_=]"
        token = token:gsub(_strip,'')
        return token
        end
        
        -- 
        -- get key auth from token file
        -- 
        function getKeyAuth(token)
                local keyAuth = ""
                local path = acme.conf.non_chroot_webroot .. "/.well-known/acme-challenge/" .. token
                local f = io.open(path, "rb")
                if f ~= nil then
                        keyAuth = f:read("*all")
                        f:close()
                end
                return keyAuth
        end
        
        core.register_init(acme.startup)
        core.register_service("acme-http01", "http", acme.http01)
        	
        

        That is added as a lua script acme-http01 in the Files section.

        It is called like this:

        Screen Shot 2022-01-04 at 9.50.37 AM.png

        Screen Shot 2022-01-04 at 9.51.25 AM.png

        Acme is set up like this:

        10103f0d-74d1-46cf-b7bf-51325c0c3298-image.png

        Chattanooga, Tennessee, USA
        A comprehensive network diagram is worth 10,000 words and 15 conference calls.
        DO NOT set a source address/port in a port forward or firewall rule unless you KNOW you need it!
        Do Not Chat For Help! NO_WAN_EGRESS(TM)

        snide_remarksS 1 Reply Last reply Reply Quote 0
        • snide_remarksS
          snide_remarks
          last edited by

          Yikes - no wonder the CNAME info was over my head. My API creditials don't seem to work any longer when I choose www.dynu.com from the drop down.
          In the past I have always used [DNS Records] to make a secure site. It usually is trial and error before I get it correct.
          I had [Sun Jan 2 21:04:00 CST 2022] Cert success. but it only seemed to be self-signed so I deleted it all to try again and now API credentials are my road block among other things.
          [Mon Jan 3 22:21:07 CST 2022] Dynu client id and secret is not specified.
          [Mon Jan 3 22:21:07 CST 2022] Please create you API client id and secret and try again.
          [Mon Jan 3 22:21:07 CST 2022] Error add txt for domain:_acme-challenge.www.tripwire.mywire.org
          [Mon Jan 3 22:21:07 CST 2022] Please check log file for more details: /tmp/acme/tripwire.mywire.org/acme_issuecert.log

          My DNS Record maybe needed to start over again. THANKS

          1 Reply Last reply Reply Quote 0
          • snide_remarksS
            snide_remarks @Derelict
            last edited by

            @derelict
            WOW - back to sucess with a cert, but still acts as if it's self-signed and get asked if I want to proceed and such.

            DerelictD 1 Reply Last reply Reply Quote 0
            • DerelictD
              Derelict LAYER 8 Netgate @snide_remarks
              last edited by

              @snide_remarks Sounds like for some reason you don't have everything installed correctly (Intermediate certs, etc). Look at the certificate error in your browser. Browsers are pretty good about giving you the information you need to figure out what's wrong.

              Chattanooga, Tennessee, USA
              A comprehensive network diagram is worth 10,000 words and 15 conference calls.
              DO NOT set a source address/port in a port forward or firewall rule unless you KNOW you need it!
              Do Not Chat For Help! NO_WAN_EGRESS(TM)

              snide_remarksS 1 Reply Last reply Reply Quote 0
              • snide_remarksS
                snide_remarks @Derelict
                last edited by

                @derelict
                Someone said the cert is still a staging cert. I don't see any other option in the drop down on my front end. I changed my keys to production. Any thoughts?

                DerelictD 1 Reply Last reply Reply Quote 0
                • DerelictD
                  Derelict LAYER 8 Netgate @snide_remarks
                  last edited by

                  @snide_remarks Reissue it using the production network so it is signed by a CA that browsers will trust.

                  Chattanooga, Tennessee, USA
                  A comprehensive network diagram is worth 10,000 words and 15 conference calls.
                  DO NOT set a source address/port in a port forward or firewall rule unless you KNOW you need it!
                  Do Not Chat For Help! NO_WAN_EGRESS(TM)

                  snide_remarksS 1 Reply Last reply Reply Quote 0
                  • snide_remarksS
                    snide_remarks @Derelict
                    last edited by snide_remarks

                    @derelict ,
                    After I changed to a production key I reissued or renewed and nothing changes. Can you explain each step. Why does this have to be so convoluded? I think with an active staging cert the next step to make it a production cert would be like taking candy from a baby. 😭

                    snide_remarksS 1 Reply Last reply Reply Quote 0
                    • snide_remarksS
                      snide_remarks @snide_remarks
                      last edited by

                      @snide_remarks

                      tripwire.mywire
                      Renewing certificate
                      account: tripwire.mywire.org
                      server: letsencrypt-production-2

                      Finally got it!!!

                      1 Reply Last reply Reply Quote 0
                      • W
                        wickeren
                        last edited by

                        Put ssl verify none in per server passtrough under advanced in the backend. That way a self-signed cert will be accepted.
                        The frontend can still be encrypted with a valid (Letsencrypt) cert.

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