Attempt To Add Support Let's Encrypt Validation Via DNS

Discussion in 'Developers' Forum' started by ahrasis, Jul 18, 2018.

  1. ahrasis

    ahrasis Well-Known Member HowtoForge Supporter

    I am putting my mind into this writing here wihich the extension from the earlier thread in here, so bear with me. :D

    # First Part
    Basically as stated, I am trying to add support for Let's Encrypt validation via DNS but I couldn't think of a better solution other than adding an extra tab (LE) in web settings (Sites > Websites > Create / Edit Website) for Let's Encrypt (right after SSL tab).

    My idea is, within this tab, there should be several info that must be selected and / or added in order to use DNS feature.

    The first option will be to choose to leave it as it is (i.e. the default webwoot method), so the current way of creating LE SSL certs (via valid website) will be implemented; however, if DNS method is selected instead, then certbot (as default LE client) will attempt to request the certs via DNS validation. At this stage I am attempting with certbot only so other other LE client / script like Neilpang acme.sh will have to wait.

    Then there should be a list of DNS server type to be selected from the official certbot plugins currently available; where from here, a detail for the website DNS config file (the credentials file) should be provided to correspond the respective selected DNS server. Of course, ideallly for own ISPConfig DNS server (a multi-server case), no information is needed as it should be done automatically via its DNS server internal function (to be created as well); but this will also have to wait since I don't have a proper ISPConfig DNS server to test.

    The information provided will be added to /etc/letsencrypt/.secrets/domain.tld and this /etc/letsencrypt/.secrets folder will be chmod to 600 (refer to this post) for security that will be called upon the certs creation or renewal.

    So for this part, I think web_vhost_domain_edit.php will be the most relevant (as well as its template and language files, of course).

    # Second Part
    For this part I believe that only letsencrypt.inc.php that needed to be modified so that it will by default choose webroot - current way of creating LE SSL certs (via valid website), but when DNS is selected, the credentials file as created earlier will be used in order to request and validate the website via DNS.

    Please advise me if there is some other files that need to be looked into to make this work, so I can try to work it out properly. Thank you. ;)
     
  2. till

    till Super Moderator Staff Member ISPConfig Developer

    I think that LE dns auth should support two ways, either by using the dns servers in ispconfig or by using a non-automated generic approach where it just displays which token/cert needs to be added by the user in his external DNS server without connecting to the external DNS automatically. There are just too many providers with different approaches so this would just clutter the UI to implement them all and in the end, the provider of the customer is not supported anyway.

    In regard to an LE tab, I would prefer to add this to the SSL tab and show different input fields on the dns tab depending on the LE checkbox of the first tab.
     
    Last edited: Jul 19, 2018
    ahrasis likes this.
  3. ahrasis

    ahrasis Well-Known Member HowtoForge Supporter

    Oh yes. My plan is that both will be available but currently, I don't have a proper ISPConfig DNS server to test. The credentials file will only be created upon save and no execution will take place until Let's Encrypt SSL is selected.

    And about LE tab, if it is in the DNS tab, it would not show if one do not use ISPConfig DNS server for one website(s), would it? That is why I suggested it to be added next to SSL tab in Sites tab instead.
     
  4. Jesse Norell

    Jesse Norell ISPConfig Developer Staff Member ISPConfig Developer

    Would it make sense to put the letsencrypt config right on the SSL tab? Ie. in the selection list for whether to use letsencrypt with webroot or dns methods, simply have another option to use a custom ssl certificate, and show/hide the fields in the current SSL tab accordingly when that option is changed. That will additionally solve the issue of people accidentally adding info under the SSL tab and also trying to use letsencrypt.

    And make sure there are the correct hooks (events or whatever they're called) firing so that a simple(?) server plugin could be written to take the DNS tokens and add them to whatever remote api is needed. An example of such a plugin could be provided which uses certbot or acme.sh, and anyone can adapt it for their needs.
     
    ahrasis likes this.
  5. ahrasis

    ahrasis Well-Known Member HowtoForge Supporter

    Smart. So the option would be LE SSL via webroot or DNS or self-signed SSL? I'll think about it.

    I am not so sure about the hook but the credential file will use domain name tld for most dns server, so it can be called from the /etc/letsencrypt/.secrets folder for those who are using certbot.

    Last time I checked, Neilpang acme.sh does not use a separate file for keeping credentials, so that would not be easy.
     
    Last edited: Sep 1, 2018
  6. Jesse Norell

    Jesse Norell ISPConfig Developer Staff Member ISPConfig Developer

    both self-signed and purchased certificates, just what the ssl tab does now (or maybe it would be even more clear to list self-signed and custom/purchased as separate options?)
     
    ahrasis likes this.
  7. till

    till Super Moderator Staff Member ISPConfig Developer

    Sorry for causing the confusion, I meant the SSL tab of the website. was a bit in a hurry when writing it.
     
  8. ahrasis

    ahrasis Well-Known Member HowtoForge Supporter

  9. ahrasis

    ahrasis Well-Known Member HowtoForge Supporter

    Sorry for revisiting this but @till what do you mean to do this we need to implement forms for dozen DNS providers in another thread? Do we really need forms for all dns providers to implement this?

    In my mind, at least for certbot, as I am not very well-versed with acme.sh yet, I am thinking of drop down menu approach, showing the list of the supported providers (if not all dns providers are supported), taken from ISPConfig database (as to me we only need to add this), when selected, the credentials, when entered, will be saved under its specific DNS providers name folder (the exact name as per command to be executed is preferred).

    Suggested folder (chmod 600) is /var/www/clients/clientX/webY/ssl/ssl/.secrets/{DNSProvidersName}/domain.tld.ini.

    So, in this theory, if wildcard (*) subdomain is chosen with LE SSL, locate domain.tld.ini will be run and if the credentials exist, specific command to issue DNS-challenge, based on its containing folder will be run, or else, log with current default error message or we could improvise this further, if needed.

    Rough idea for execution code to be modded in /server/lib/classes/letsencrypt.inc.php:
    Code:
    $dns_file = shell_exec("locate $primary_domain.ini");
    if (file_exists($dns_file) && substr($domain, 0, 2) === '*.' && version_compare($letsencrypt_version, '0.22', '>=')) {
       $dns_provider = basename(dirname($dns_path));
       $dns_provider_credentials = " --$dns_provider-credentials $dns_file ";
           $cmd = $letsencrypt . " certonly -n --text --agree-tos $cert_selection_command $dns_provider $dns_provider-credentials --server $acme_version --rsa-key-size 4096 --email [email protected]$primary_domain -d $primary_domain -d *.$primary_domain";
    } else {
           $cmd = $letsencrypt . " certonly -n --text --agree-tos $cert_selection_command --authenticator webroot --server $acme_version --rsa-key-size 4096 --email [email protected]$primary_domain $webroot_args";
    }
            return $cmd;
    
     
  10. till

    till Super Moderator Staff Member ISPConfig Developer

    This might work when all DNS providers use just a username and password and no other info is needed besides these two fields.
     
    ahrasis likes this.
  11. Jesse Norell

    Jesse Norell ISPConfig Developer Staff Member ISPConfig Developer

    Or store all needed info in a single field, json encoded?
     
  12. till

    till Super Moderator Staff Member ISPConfig Developer

    I thought @ahrasis was talking to the input fields where the customer must enter the data?
     
  13. Jesse Norell

    Jesse Norell ISPConfig Developer Staff Member ISPConfig Developer

    Yeah, I think so; ignore my last post.

    I'd expect some variations in what fields are needed for different dns providers, but if creating a domain.tld.ini it could probably be done in a generic manner, eg. some things like api endpoint url can be set according to the selected dns provider, and then each provider has a list of required ini names to be used, and the front end just use text fields to read each of those, and write to the ini file values.
     
    ahrasis likes this.

Share This Page