Friday, August 12, 2022

LetsEncrypt certificate renewal issue with Cloudflare proxied Bitnami server

Found one of the Bitnami servers on AWS had an expired LetsEncrypt certificate. Checking, found that its bncert-tool was not able to renew the certificate because it was checking DNS as part of validation, and the server was being proxied by Cloudflare

  1. Temporary solution - turning proxying off (DNS only) in cloudflare, ran bncert to renew, OK for now.
  2. Looking for ways in which the renewal can happen without us having to manually change the cloudflare settings, I found the following:
    https://nodehost.ca/docs/containers/make-lets-encrypt-work-when-using-cloudflare-acme-challenge

    But this is when the host uses certbot and not bitnami's bncert-tool, which uses a different authentication method. This does not work out of the box for Bitnami servers since the config files' paths are different. On the server itself, there is the rule
    RewriteCond %{REQUEST_URI} !^/\.well-known
    in the file /opt/bitnami/apache2/conf/bitnami/bitnami.conf
  3. Possibly the final solution:
    bncert-tool uses the lego client, documentation at
    https://go-acme.github.io/lego/usage/cli/options/

    From the documentation, it looks like we can choose Cloudflare as the DNS provider and get the actual dns address. For this, we will need an api key for lms.sssihl.edu.in -
     via
    Creating API tokens · Cloudflare API docs

    (Using api key instead of api token for initial testing,
    Cloudflare and restricted API tokens · Issue #984 · go-acme/lego (github.com) )

    Then we can try and configure the server to auto update the ssl certificates by authenticating the IP address from cloudflare.

    So, I have added two files on the server,
    /home/bitnami/cloudflare-user
    and
    /home/bitnami/cloudflare-api-key

    and I have modified the cron command which runs daily to check for renewal,
    from
    51 23 * * * sudo /opt/bitnami/letsencrypt/lego --path /opt/bitnami/letsencrypt --email="theemail@thedomain.in" --http --http-timeout 30 --http.webroot /opt/bitnami/apps/letsencrypt --domains=thedomain.in --user-agent bitnami-bncert/1.0.0 renew && sudo /opt/bitnami/apache/bin/httpd -f /opt/bitnami/apache/conf/httpd.conf -k graceful # bncert-autorenew

    to
    51 23 * * * sudo CLOUDFLARE_EMAIL_FILE=/home/bitnami/cloudflare-user CLOUDFLARE_API_KEY_FILE=/home/bitnami/cloudflare-api-key /opt/bitnami/letsencrypt/lego --path /opt/bitnami/letsencrypt --dns cloudflare --email="theemail@thedomain.in" --http --http-timeout 30 --http.webroot /opt/bitnami/apps/letsencrypt --domains=thedomain.in --user-agent bitnami-bncert/1.0.0 renew && sudo /opt/bitnami/apache/bin/httpd -f /opt/bitnami/apache/conf/httpd.conf -k graceful # bncert-autorenew

    Let's see after 30 days if it successfully renews. Seemed to work OK during testing.
    Edit: 14 Sep - Yes, it has auto-renewed on 10 Sep.

Some other alternative solutions, which I did not explore:

  1. There is an alternative method using self-signed certificates, but that would need cloudflare HTTPS setting to be changed to Full instead of Full (Strict), https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/ )
     
  2. Another option is, you could create an Origin Certificate using Cloudflare, and use that instead of the LetsEncrypt certificate.
    https://developers.cloudflare.com/ssl/origin-configuration/origin-ca/
    This would need a one-time set up on the server, after that would not need renewal (for 15 years.)
    Setup on the server would be similar to this, https://visser.io/2018/03/setting-up-a-cloudflare-ssl-certificate-for-bitnami-wordpress-on-google-cloud-compute-engine/
    Edit - I have implemented this, and posted about it here.
  3. There is probably another option using manual configuration of certbot, but more difficult than the above, so I'm skipping that.

No comments:

Post a Comment