This commit is contained in:
github-actions[bot] 2023-01-06 22:59:18 +00:00
parent f0b523166f
commit 26a4a34359
2 changed files with 132 additions and 1 deletions

View file

@ -704,6 +704,13 @@
Certbot with Docker
</a>
</li>
<li class="md-nav__item">
<a href="#example-using-certbot-dns-cloudflare-with-docker" class="md-nav__link">
certbot-dns-cloudflare with Docker
</a>
</li>
<li class="md-nav__item">
@ -1602,6 +1609,13 @@
Certbot with Docker
</a>
</li>
<li class="md-nav__item">
<a href="#example-using-certbot-dns-cloudflare-with-docker" class="md-nav__link">
certbot-dns-cloudflare with Docker
</a>
</li>
<li class="md-nav__item">
@ -1861,6 +1875,123 @@ docker run --rm -it <span class="se">\</span>
<p class="admonition-title">Using a different ACME CA</p>
<p>Certbot does support <a href="https://certbot.eff.org/docs/using.htmlchanging-the-acme-server">alternative certificate providers via the <code>--server</code></a> option. In most cases you'll want to use the default <em>Let's Encrypt</em>.</p>
</div>
<h4 id="example-using-certbot-dns-cloudflare-with-docker"><a class="toclink" href="#example-using-certbot-dns-cloudflare-with-docker">Example using <code>certbot-dns-cloudflare</code> with Docker</a></h4>
<p>If you are unable get a certificate via the <code>HTTP-01</code> (port 80) or <code>TLS-ALPN-01</code> (port 443) <a href="https://letsencrypt.org/docs/challenge-types/">challenge types</a>, the <code>DNS-01</code> challenge can be useful (<em>this challenge can additionally issue wildcard certificates</em>). This guide shows how to use the <code>DNS-01</code> challenge with Cloudflare as your DNS provider.</p>
<p>Obtain a Cloudflare API token:</p>
<ol>
<li>Login into your Cloudflare dashboard.</li>
<li>Navigate to the <a href="https://dash.cloudflare.com/profile/api-tokens">API Tokens page</a>.</li>
<li>
<p>Click "Create Token", and choose the <code>Edit zone DNS</code> template (<em>Certbot <a href="https://certbot-dns-cloudflare.readthedocs.io/en/stable/#credentials">requires the <code>ZONE:DNS:Edit</code> permission</a></em>).</p>
<div class="admonition warning">
<p class="admonition-title">Only include the necessary Zone resource configuration</p>
<p>Be sure to configure "Zone Resources" section on this page to <code>Include -&gt; Specific zone -&gt; &lt;your zone here&gt;</code>.</p>
<p>This restricts the API token to only this zone (domain) which is an important security measure.</p>
</div>
</li>
<li>
<p>Store the <em>API token</em> you received in a file <code>cloudflare.ini</code> with content:</p>
<div class="highlight"><pre><span></span><code><span class="na">dns_cloudflare_api_token</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">YOUR_CLOUDFLARE_TOKEN_HERE</span><span class="w"></span>
</code></pre></div>
</li>
<li>
<p>As this is sensitive data, you should restrict access to it with <code>chmod 600</code> and <code>chown 0:0</code>.</p>
</li>
<li>Store the file in a folder if you like, such as <code>docker-data/certbot/secrets/</code>.</li>
<li>
<p>Your <code>docker-compose.yml</code> should include the following:</p>
<div class="highlight"><pre><span></span><code><span class="nt">services</span><span class="p">:</span><span class="w"></span>
<span class="w"> </span><span class="nt">mailserver</span><span class="p">:</span><span class="w"></span>
<span class="w"> </span><span class="nt">environments</span><span class="p">:</span><span class="w"></span>
<span class="w"> </span><span class="c1"># Set SSL certificate type.</span><span class="w"></span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">SSL_TYPE=letsencrypt</span><span class="w"></span>
<span class="w"> </span><span class="nt">volumes</span><span class="p">:</span><span class="w"></span>
<span class="w"> </span><span class="c1"># Mount the cert folder generated by Certbot into mail-server:</span><span class="w"></span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">./docker-data/certbot/certs/:/etc/letsencrypt/:ro</span><span class="w"></span>
<span class="w"> </span><span class="nt">certbot-cloudflare</span><span class="p">:</span><span class="w"></span>
<span class="w"> </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">certbot/dns-cloudflare:latest</span><span class="w"></span>
<span class="w"> </span><span class="nt">command</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">certonly --dns-cloudflare --dns-cloudflare-credentials /run/secrets/cloudflare-api-token -d mail.example.com</span><span class="w"></span>
<span class="w"> </span><span class="nt">volumes</span><span class="p">:</span><span class="w"></span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">./docker-data/certbot/certs/:/etc/letsencrypt/</span><span class="w"></span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">./docker-data/certbot/logs/:/var/log/letsencrypt/</span><span class="w"></span>
<span class="w"> </span><span class="nt">secrets</span><span class="p">:</span><span class="w"></span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">cloudflare-api-token</span><span class="w"></span>
<span class="c1"># Docs: https://docs.docker.com/engine/swarm/secrets/#use-secrets-in-compose</span><span class="w"></span>
<span class="c1"># WARNING: In compose configs without swarm, the long syntax options have no effect,</span><span class="w"></span>
<span class="c1"># Ensure that you properly `chmod 600` and `chown 0:0` the file on disk. Effectively treated as a bind mount.</span><span class="w"></span>
<span class="nt">secrets</span><span class="p">:</span><span class="w"></span>
<span class="w"> </span><span class="nt">cloudflare-api-token</span><span class="p">:</span><span class="w"></span>
<span class="w"> </span><span class="nt">file</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">./docker-data/certbot/secrets/cloudflare.ini</span><span class="w"></span>
</code></pre></div>
<p>Alternative using the <code>docker run</code> command (<code>secrets</code> feature is not available):</p>
<div class="highlight"><pre><span></span><code>docker run <span class="se">\</span>
--volume <span class="s2">&quot;</span><span class="si">${</span><span class="nv">PWD</span><span class="si">}</span><span class="s2">/docker-data/certbot/certs/:/etc/letsencrypt/&quot;</span> <span class="se">\</span>
--volume <span class="s2">&quot;</span><span class="si">${</span><span class="nv">PWD</span><span class="si">}</span><span class="s2">/docker-data/certbot/logs/:/var/log/letsencrypt/&quot;</span> <span class="se">\</span>
--volume <span class="s2">&quot;</span><span class="si">${</span><span class="nv">PWD</span><span class="si">}</span><span class="s2">/docker-data/certbot/secrets/:/tmp/secrets/certbot/&quot;</span>
certbot/dns-cloudflare <span class="se">\</span>
certonly --dns-cloudflare --dns-cloudflare-credentials /tmp/secrets/certbot/cloudflare.ini -d mail.example.com
</code></pre></div>
</li>
<li>
<p>Run the service to provision a certificate:</p>
<div class="highlight"><pre><span></span><code>docker-compose run certbot-cloudflare
</code></pre></div>
</li>
<li>
<p>You should see the following log output:</p>
<div class="highlight"><pre><span></span><code><span class="go">Saving debug log to /var/log/letsencrypt/letsencrypt. log | Requesting a certificate for mail.example.com</span>
<span class="go">Waiting 10 seconds for DNS changes to propagate</span>
<span class="go">Successfully received certificate.</span>
<span class="go">Certificate is saved at: /etc/letsencrypt/live/mail.example.com/fullchain.pem</span>
<span class="go">Key is saved at: /etc/letsencrypt/live/mail.example.com/privkey.pem</span>
<span class="go">This certificate expires on YYYY-MM-DD.</span>
<span class="go">These files will be updated when the certificate renews.</span>
<span class="go">NEXT STEPS:</span>
<span class="go">- The certificate will need to be renewed before it expires. Certbot can automatically renew the certificate in background, but you may need to take steps to enable that functionality. See https://certbot.org/renewal structions.</span>
</code></pre></div>
</li>
</ol>
<p>After completing the steps above, your certificate should be ready to use.</p>
<details class="tip">
<summary>Renewing a certificate (Optional)</summary>
<p>We've only demonstrated how to provision a certificate, but it will expire in 90 days and need to be renewed before then.</p>
<p>In the following example, add a new service (<code>certbot-cloudflare-renew</code>) into <code>docker-compose.yml</code> that will handle certificate renewals:</p>
<div class="highlight"><pre><span></span><code><span class="nt">services</span><span class="p">:</span><span class="w"></span>
<span class="w"> </span><span class="nt">certbot-cloudflare-renew</span><span class="p">:</span><span class="w"></span>
<span class="w"> </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">certbot/dns-cloudflare:latest</span><span class="w"></span>
<span class="w"> </span><span class="nt">command</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">renew --dns-cloudflare --dns-cloudflare-credentials /run/secrets/cloudflare-api-token</span><span class="w"></span>
<span class="w"> </span><span class="nt">volumes</span><span class="p">:</span><span class="w"></span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">./docker-data/certbot/certs/:/etc/letsencrtypt/</span><span class="w"></span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">./docker-data/certbot/logs/:/var/log/letsencrypt/</span><span class="w"></span>
<span class="w"> </span><span class="nt">secrets</span><span class="p">:</span><span class="w"></span>
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">cloudflare-api-token</span><span class="w"></span>
</code></pre></div>
<p>You can manually run this service to renew the cert within 90 days:</p>
<div class="highlight"><pre><span></span><code>docker-compose run certbot-cloudflare-renew
</code></pre></div>
<p>You should see the following output
(The following log was generated with <code>--dry-run</code> options)</p>
<div class="highlight"><pre><span></span><code><span class="go">Saving debug log to /var/log/letsencrypt/letsencrypt.log</span>
<span class="go">- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -</span>
<span class="go">Processing /etc/letsencrypt/renewal/mail.example.com.conf</span>
<span class="go">- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -</span>
<span class="go">Account registered.</span>
<span class="go">Simulating renewal of an existing certificate for mail.example.com</span>
<span class="go">Waiting 10 seconds for DNS changes to propagate</span>
<span class="go">- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -</span>
<span class="go">Congratulations, all simulated renewals succeeded:</span>
<span class="go"> /etc/letsencrypt/live/mail.example.com/fullchain.pem (success)</span>
<span class="go">- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -</span>
</code></pre></div>
<p>It is recommended to automate this renewal via a task scheduler like a <em>systemd timer</em> or in <code>crontab</code>
(<code>crontab</code> example: Checks every day if the certificate should be renewed)</p>
<div class="highlight"><pre><span></span><code><span class="m">0</span> <span class="m">0</span> * * * docker-compose -f PATH_TO_YOUR_DOCKER_COMPOSE_YML up certbot-cloudflare-renew
</code></pre></div>
</details>
<h4 id="example-using-nginx-proxy-and-acme-companion-with-docker"><a class="toclink" href="#example-using-nginx-proxy-and-acme-companion-with-docker">Example using <code>nginx-proxy</code> and <code>acme-companion</code> with Docker</a></h4>
<p>If you are running a web server already, port 80 will be in use which Certbot requires. You could use the <a href="https://certbot.eff.org/docs/using.html#webroot">Certbot <code>--webroot</code></a> feature, but it is more common to leverage a <em>reverse proxy</em> that manages the provisioning and renewal of certificates for your services automatically.</p>
<p>In the following example, we show how <code>docker-mailserver</code> can be run alongside the docker containers <a href="https://github.com/nginx-proxy/nginx-proxy"><code>nginx-proxy</code></a> and <a href="https://github.com/nginx-proxy/acme-companion"><code>acme-companion</code></a> (<em>Referencing: <a href="https://github.com/nginx-proxy/acme-companion/blob/main/docs"><code>acme-companion</code> documentation</a></em>):</p>

File diff suppressed because one or more lines are too long