This commit is contained in:
github-actions[bot] 2021-04-18 13:21:36 +00:00
parent ad3b21342f
commit be408c683a
3 changed files with 50 additions and 92 deletions

View file

@ -657,31 +657,11 @@
</li> </li>
<li class="md-nav__item">
<a href="#traefik" class="md-nav__link">
Traefik
</a>
<nav class="md-nav" aria-label="Traefik">
<ul class="md-nav__list">
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#traefik-v2" class="md-nav__link"> <a href="#traefik-v2" class="md-nav__link">
Traefik v2 Traefik v2
</a> </a>
</li>
<li class="md-nav__item">
<a href="#traefik-v1" class="md-nav__link">
Traefik v1
</a>
</li>
</ul>
</nav>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
@ -1392,31 +1372,11 @@
</li> </li>
<li class="md-nav__item">
<a href="#traefik" class="md-nav__link">
Traefik
</a>
<nav class="md-nav" aria-label="Traefik">
<ul class="md-nav__list">
<li class="md-nav__item"> <li class="md-nav__item">
<a href="#traefik-v2" class="md-nav__link"> <a href="#traefik-v2" class="md-nav__link">
Traefik v2 Traefik v2
</a> </a>
</li>
<li class="md-nav__item">
<a href="#traefik-v1" class="md-nav__link">
Traefik v1
</a>
</li>
</ul>
</nav>
</li> </li>
<li class="md-nav__item"> <li class="md-nav__item">
@ -1495,7 +1455,7 @@
<li> <li>
<p>The certs folder name located in <code>letsencrypt/live/</code> must be the <code>fqdn</code> of your container responding to the <code>hostname</code> command. The <code>fqdn</code> (full qualified domain name) inside the docker container is built combining the <code>hostname</code> and <code>domainname</code> values of the <code>docker-compose</code> file, eg:</p> <p>The certs folder name located in <code>letsencrypt/live/</code> must be the <code>fqdn</code> of your container responding to the <code>hostname</code> command. The <code>fqdn</code> (full qualified domain name) inside the docker container is built combining the <code>hostname</code> and <code>domainname</code> values of the <code>docker-compose</code> file, eg:</p>
<div class="highlight"><pre><span></span><code><span class="nt">services</span><span class="p">:</span> <div class="highlight"><pre><span></span><code><span class="nt">services</span><span class="p">:</span>
<span class="nt">mail</span><span class="p">:</span> <span class="nt">mailserver</span><span class="p">:</span>
<span class="nt">hostname</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">mail</span> <span class="nt">hostname</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">mail</span>
<span class="nt">domainname</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">myserver.tld</span> <span class="nt">domainname</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">myserver.tld</span>
<span class="nt">fqdn</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">mail.myserver.tld</span> <span class="nt">fqdn</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">mail.myserver.tld</span>
@ -1632,7 +1592,7 @@
<p>The second part of the setup is the actual mail container. So, in another folder, create another <code>docker-compose.yml</code> with the following content (Removed all ENV variables for this example):</p> <p>The second part of the setup is the actual mail container. So, in another folder, create another <code>docker-compose.yml</code> with the following content (Removed all ENV variables for this example):</p>
<details class="example" open="open"><summary>Example Code</summary><div class="highlight"><pre><span></span><code><span class="nt">version</span><span class="p">:</span> <span class="s">&#39;2&#39;</span> <details class="example" open="open"><summary>Example Code</summary><div class="highlight"><pre><span></span><code><span class="nt">version</span><span class="p">:</span> <span class="s">&#39;2&#39;</span>
<span class="nt">services</span><span class="p">:</span> <span class="nt">services</span><span class="p">:</span>
<span class="nt">mail</span><span class="p">:</span> <span class="nt">mailserver</span><span class="p">:</span>
<span class="nt">image</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">mailserver/docker-mailserver:latest</span> <span class="nt">image</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">mailserver/docker-mailserver:latest</span>
<span class="nt">hostname</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">${HOSTNAME}</span> <span class="nt">hostname</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">${HOSTNAME}</span>
<span class="nt">domainname</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">${DOMAINNAME}</span> <span class="nt">domainname</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">${DOMAINNAME}</span>
@ -1777,60 +1737,58 @@
<span class="go">no peer certificate available</span> <span class="go">no peer certificate available</span>
<span class="go">No client certificate CA names sent</span> <span class="go">No client certificate CA names sent</span>
</code></pre></div> </code></pre></div>
<h2 id="traefik"><a class="toclink" href="#traefik">Traefik</a></h2> <h2 id="traefik-v2"><a class="toclink" href="#traefik-v2">Traefik v2</a></h2>
<p><a href="https://github.com/containous/traefik">Traefik</a> is an open-source Edge Router which handles ACME protocol using <a href="https://github.com/go-acme/lego">lego</a>.</p> <p><a href="https://github.com/containous/traefik">Traefik</a> is an open-source application proxy using the <a href="https://tools.ietf.org/html/rfc8555">ACME protocol</a>. <a href="https://github.com/containous/traefik">Traefik</a> can request certificates for domains and subdomains, and it will take care of renewals, challenge negotiations, etc. We strongly recommend to use <a href="https://github.com/containous/traefik">Traefik</a>'s major version 2.</p>
<p>Traefik can request certificates for domains through the ACME protocol (see <a href="https://docs.traefik.io/https/acme/">Traefik's documentation about its ACME negotiation &amp; storage mechanism</a>). Traefik's router will take care of renewals, challenge negotiations, etc.</p> <p><a href="https://github.com/containous/traefik">Traefik</a>'s storage format is natively supported if the <code>acme.json</code> store is mounted into the container at <code>/etc/letsencrypt/acme.json</code>. The file is also monitored for changes and will trigger a reload of the mail services. Wild card certificates issued for <code>*.domain.tld</code> are supported. You will then want to use <code class="highlight"><span class="nv">SSL_DOMAIN</span><span class="o">=</span>domain.tld</code>. Lookup of the certificate domain happens in the following order:</p>
<h3 id="traefik-v2"><a class="toclink" href="#traefik-v2">Traefik v2</a></h3>
<p>(For Traefik v1 see <a href="#traefik-v1">next section</a>)</p>
<p>Traefik's V2 storage format is natively supported if the <code>acme.json</code> store is mounted into the container at <code>/etc/letsencrypt/acme.json</code>. The file is also monitored for changes and will trigger a reload of the mail services. Lookup of the certificate domain happens in the following order:</p>
<ol> <ol>
<li><code>$SSL_DOMAIN</code></li> <li><code class="highlight"><span class="si">${</span><span class="nv">SSL_DOMAIN</span><span class="si">}</span></code></li>
<li><code>$HOSTNAME</code></li> <li><code class="highlight"><span class="si">${</span><span class="nv">HOSTNAME</span><span class="si">}</span></code></li>
<li><code>$DOMAINNAME</code></li> <li><code class="highlight"><span class="si">${</span><span class="nv">DOMAINNAME</span><span class="si">}</span></code></li>
</ol> </ol>
<p>This allows for support of wild card certificates: <code>SSL_DOMAIN=*.example.com</code>. Here is an example setup for <a href="https://docs.docker.com/compose/"><code>docker-compose</code></a>:</p> <p>This setup only comes with one caveat: The domain has to be configured on another service for <a href="https://github.com/containous/traefik">Traefik</a> to actually request it from Let'sEncrypt, i.e. <a href="https://github.com/containous/traefik">Traefik</a> will not issue a certificate without a service / router demanding it.</p>
<details class="example" open="open"><summary>Example Code</summary><div class="highlight"><pre><span></span><code><span class="nt">version</span><span class="p">:</span> <span class="s">&#39;3.8&#39;</span> <details class="example" open="open"><summary>Example Code</summary><p>Here is an example setup for <a href="https://docs.docker.com/compose/"><code>docker-compose</code></a>:</p>
<div class="highlight"><pre><span></span><code><span class="nt">version</span><span class="p">:</span> <span class="s">&#39;3.8&#39;</span>
<span class="nt">services</span><span class="p">:</span> <span class="nt">services</span><span class="p">:</span>
<span class="nt">mail</span><span class="p">:</span>
<span class="nt">image</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">mailserver/docker-mailserver:stable</span> <span class="nt">mailserver</span><span class="p">:</span>
<span class="nt">image</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">docker.io/mailserver/docker-mailserver:latest</span>
<span class="nt">container_name</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">mailserver</span>
<span class="nt">hostname</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">mail</span> <span class="nt">hostname</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">mail</span>
<span class="nt">domainname</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">example.com</span> <span class="nt">domainname</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">domain.tld</span>
<span class="nt">volumes</span><span class="p">:</span> <span class="nt">volumes</span><span class="p">:</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">/etc/ssl/acme-v2.json:/etc/letsencrypt/acme.json:ro</span> <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">/traefik/acme.json:/etc/letsencrypt/acme.json:ro</span>
<span class="nt">environment</span><span class="p">:</span> <span class="nt">environment</span><span class="p">:</span>
<span class="nt">SSL_TYPE</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">letsencrypt</span> <span class="nt">SSL_TYPE</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">letsencrypt</span>
<span class="c1"># SSL_DOMAIN: &quot;*.example.com&quot; </span> <span class="nt">SSL_DOMAIN</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">mail.example.com&quot;</span>
<span class="c1"># for a wildcard certificate, use</span>
<span class="c1"># SSL_DOMAIN: example.com</span>
<span class="nt">traefik</span><span class="p">:</span> <span class="nt">traefik</span><span class="p">:</span>
<span class="nt">image</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">traefik:v2.2</span> <span class="nt">image</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">docker.io/traefik:v2.4.8</span>
<span class="nt">restart</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">always</span>
<span class="nt">ports</span><span class="p">:</span> <span class="nt">ports</span><span class="p">:</span>
<span class="p p-Indicator">-</span> <span class="s">&quot;80:80&quot;</span> <span class="p p-Indicator">-</span> <span class="s">&quot;80:80&quot;</span>
<span class="p p-Indicator">-</span> <span class="s">&quot;443:443&quot;</span> <span class="p p-Indicator">-</span> <span class="s">&quot;443:443&quot;</span>
<span class="nt">command</span><span class="p">:</span> <span class="nt">command</span><span class="p">:</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">--providers.docker</span> <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">--providers.docker</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">--entrypoints.web.address=:80</span> <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">--entrypoints.http.address=:80</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">--entrypoints.web.http.redirections.entryPoint.to=websecure</span> <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">--entrypoints.http.http.redirections.entryPoint.to=https</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">--entrypoints.web.http.redirections.entryPoint.scheme=https</span> <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">--entrypoints.http.http.redirections.entryPoint.scheme=https</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">--entrypoints.websecure.address=:443</span> <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">--entrypoints.https.address=:443</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">--entrypoints.websecure.http.middlewares=hsts@docker</span> <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">--entrypoints.https.http.tls.certResolver=letsencrypt</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">--entrypoints.websecure.http.tls.certResolver=le</span> <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">--certificatesresolvers.letsencrypt.acme.email=admin@domain.tld</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">--certificatesresolvers.le.acme.email=admin@example.net</span> <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">--certificatesresolvers.letsencrypt.acme.storage=/acme.json</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">--certificatesresolvers.le.acme.storage=/acme.json</span> <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">--certificatesresolvers.le.acme.httpchallenge.entrypoint=web</span>
<span class="nt">volumes</span><span class="p">:</span> <span class="nt">volumes</span><span class="p">:</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">/traefik/acme.json:/acme.json</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">/var/run/docker.sock:/var/run/docker.sock:ro</span> <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">/var/run/docker.sock:/var/run/docker.sock:ro</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">/etc/ssl/acme-v2.json:/acme.json</span>
<span class="nt">whoami</span><span class="p">:</span> <span class="nt">whoami</span><span class="p">:</span>
<span class="nt">image</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">containous/whoami</span> <span class="nt">image</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">docker.io/traefik/whoami:latest</span>
<span class="nt">labels</span><span class="p">:</span> <span class="nt">labels</span><span class="p">:</span>
<span class="p p-Indicator">-</span> <span class="s">&quot;traefik.http.routers.whoami.rule=Host(`mail.example.com`)&quot;</span> <span class="p p-Indicator">-</span> <span class="s">&quot;traefik.http.routers.whoami.rule=Host(`mail.domain.tld`)&quot;</span>
</code></pre></div> </code></pre></div>
</details> </details>
<p>This setup only comes with one caveat: The domain has to be configured on another service for traefik to actually request it from lets-encrypt (<code>whoami</code> in this case).</p>
<h3 id="traefik-v1"><a class="toclink" href="#traefik-v1">Traefik v1</a></h3>
<p>If you are using Traefik v1, you might want to <em>push</em> your Traefik-managed certificates to the mailserver container, in order to reuse them. Not an easy task, but fortunately, <a href="https://github.com/youtous/docker-mailserver-traefik"><code>youtous/mailserver-traefik</code></a> is a certificate renewal service for <code>docker-mailserver</code>.</p>
<p>Depending of your Traefik configuration, certificates may be stored using a file or a KV Store (consul, etcd...) Either way, certificates will be renewed by Traefik, then automatically pushed to the mailserver thanks to the <code>cert-renewer</code> service. Finally, dovecot and postfix will be restarted.</p>
<h2 id="self-signed-certificates"><a class="toclink" href="#self-signed-certificates">Self-Signed Certificates</a></h2> <h2 id="self-signed-certificates"><a class="toclink" href="#self-signed-certificates">Self-Signed Certificates</a></h2>
<div class="admonition warning"> <div class="admonition warning">
<p class="admonition-title">Warning</p> <p class="admonition-title">Warning</p>

File diff suppressed because one or more lines are too long

Binary file not shown.