Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add acme v02 support #391

Merged
merged 14 commits into from
Dec 11, 2019
Merged
Prev Previous commit
Next Next commit
acme doc
  • Loading branch information
jcmoraisjr committed Dec 11, 2019
commit df8bfea83d98c899da3f8eed5e1cff545d33194a
32 changes: 30 additions & 2 deletions docs/content/en/docs/configuration/command-line.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,17 @@ The following command-line options are supported:

| Name | Type | Default | Since |
|---------------------------------------------------------|----------------------------|-------------------------|-------|
| [`--acme-check-period`](#acme) | time | `24h` | v0.9 |
| [`--acme-election-id`](#acme) | [namespace]/configmap-name | `acme-leader` | v0.9 |
| [`--acme-fail-initial-duration`](#acme) | time | `5m` | v0.9 |
| [`--acme-fail-max-duration`](#acme) | time | `8h` | v0.9 |
| [`--acme-secret-key-name`](#acme) | [namespace]/secret-name | `acme-private-key` | v0.9 |
| [`--acme-server`](#acme) | [true\|false] | `false` | v0.9 |
| [`--acme-token-configmap-name`](#acme) | [namespace]/configmap-name | `acme-validation-tokens` | v0.9 |
| [`--allow-cross-namespace`](#allow-cross-namespace) | [true\|false] | `false` | |
| [`--annotation-prefix`](#annotation-prefix) | prefix without `/` | `ingress.kubernetes.io` | v0.8 |
| [`--default-backend-service`](#default-backend-service) | namespace/servicename | (mandatory) | |
| [`--default-ssl-certificate`](#default-ssl-certificate) | namespace/secretname | (mandatory) | |
| [`--default-backend-service`](#default-backend-service) | namespace/servicename | haproxy's 404 page | |
| [`--default-ssl-certificate`](#default-ssl-certificate) | namespace/secretname | fake, auto generated | |
| [`--ingress-class`](#ingress-class) | name | `haproxy` | |
| [`--kubeconfig`](#kubeconfig) | /path/to/kubeconfig | in cluster config | |
| [`--max-old-config-files`](#max-old-config-files) | num of files | `0` | |
Expand All @@ -28,6 +35,27 @@ The following command-line options are supported:

---

## Acme

Configures the acme server and other static options used to authorize and sign certificates
against a server which implements the acme protocol, version 2.

Supported acme command-line options:

* `--acme-check-period`: interval between checks for expiring certificates. Defaults to `24h`.
* `--acme-election-id`: prefix of the configmap name used to store the leader election data. Only the leader of a haproxy-ingress cluster should start the authorization and sign certificate process. Defaults to `acme-leader`.
* `--acme-fail-initial-duration`: the starting time to wait and retry after a failed authorization and sign process. Defaults to `5m`.
* `--acme-fail-max-duration`: the time between retries of failed authorization will exponentially grow up to the max duration time. Defaults to `8h`.
* `--acme-secret-key-name`: secret name used to store the client private key. Defaults to `acme-private-key`. A new key, hence a new client, is created if the secret does not exist.
* `--acme-server`: mandatory, starts a local server used to answer challenges from the acme environment. This option should be provided on all haproxy-ingress instances to the certificate signing work properly.
* `--acme-token-configmap-name`: the configmap name used to store temporary tokens generated during the challenge. Defaults to `acme-validation-tokens`. Such tokens need to be stored in k8s because any haproxy-ingress instance might receive the request from the acme environment.

See also:

* [acme configuration keys]({{% relref "keys/#acme" %}}) doc, which has also an overview on how acme works on haproxy-ingress

---

## --allow-cross-namespace

`--allow-cross-namespace` argument, if added, will allow reading secrets from one namespace to an
Expand Down
90 changes: 90 additions & 0 deletions docs/content/en/docs/configuration/keys.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ The table below describes all supported configuration keys.

| Configuration key | Data type | Scope | Default value |
|------------------------------------------------------|-----------------------------------------|---------|--------------------|
| [`acme-emails`](#acme) | email1,email2,... | Global | |
| [`acme-endpoint`](#acme) | v2-staging | v2 | endpoint | Global | |
| [`acme-expiring`](#acme) | number of days | Global | `30` |
| [`acme-shared`](#acme) | [true\|false] | Global | `false` |
| [`acme-terms-agreed`](#acme) | [true\|false] | Global | `false` |
| [`affinity`](#affinity) | affinity type | Backend | |
| [`agent-check-addr`](#agent-check) | address for agent checks | Backend | |
| [`agent-check-interval`](#agent-check) | time with suffix | Backend | |
Expand Down Expand Up @@ -116,6 +121,7 @@ The table below describes all supported configuration keys.
| [`blue-green-deploy`](#blue-green) | label=value=weight,... | Backend | |
| [`blue-green-header`](#blue-green) | `HeaderName:LabelName` pair | Backend | |
| [`blue-green-mode`](#blue-green) | [pod\|deploy] | Backend | |
| [`cert-signer`](#acme) | "acme" | Host | |
| [`config-backend`](#configuration-snippet) | multiline HAProxy backend config | Backend | |
| [`config-defaults`](#configuration-snippet) | multiline HAProxy config for the defaults section | Global | |
| [`config-frontend`](#configuration-snippet) | multiline HAProxy frontend config | Global | |
Expand Down Expand Up @@ -229,6 +235,90 @@ The table below describes all supported configuration keys.
| [`waf-mode`](#waf) | [deny\|detect] | Backend | `deny` (if waf is set) |
| `whitelist-source-range` | CIDR | Backend | |

---

## Acme

| Configuration key | Scope | Default | Since |
|---------------------|----------|---------|-------|
| `acme-emails` | `Global` | | v0.9 |
| `acme-endpoint` | `Global` | | v0.9 |
| `acme-expiring` | `Global` | `30` | v0.9 |
| `acme-shared` | `Global` | `false` | v0.9 |
| `acme-terms-agreed` | `Global` | `false` | v0.9 |
| `cert-signer` | `Host` | | v0.9 |

Configures dynamic options used to authorize and sign certificates against a server
which implements the acme protocol, version 2.

The popular [Let's Encrypt](https://letsencrypt.org) certificate authority implements
acme-v2.

Supported acme configuration keys:

* `acme-emails`: mandatory, a comma-separated list of emails used to configure the client account. The account will be updated if this option is changed.
* `acme-endpoint`: mandatory, endpoint of the acme environment. `v2-staging` and `v02-staging` are alias to `https://acme-staging-v02.api.letsencrypt.org`, while `v2` and `v02` are alias to `https://acme-v02.api.letsencrypt.org`.
* `acme-expiring`: how many days before expiring a certificate should be considered old and should be updated. Defaults to `30` days.
* `acme-shared`: defines if another certificate signer is running in the cluster. If `false`, the default value, any request to `/.well-known/acme-challenge/` is sent to the local acme server despite any ingress object configuration. Otherwise, if `true`, a configured ingress object would take precedence.
* `acme-terms-agreed`: mandatory, it should be defined as `true`, otherwise certificates won't be issued.
* `cert-signer`: defines the certificate signer that should be used to authorize and sign new certificates. The only supported value is `"acme"`. Add this config as an annotation in the ingress object that should have its certificate managed by haproxy-ingress and signed by the configured acme environment.

**Minimum setup**

The command-line option `--acme-server` need to be declared to start the local
server and the work queue used to authorize and sign new certificates. See other
command-line options [here]({{% relref "command-line/#acme" %}}).

The following configuration keys are mandatory: `acme-emails`, `acme-endpoint`,
`acme-terms-agreed`.

A cluster-wide permission to `create` and `update` the `secrets` resources should
also be made.

{{% alert title="Note" %}}
haproxy-ingress need cluster-wide permissions `create` and `update` on resource
`secrets` to store the client private key (new account) and the generated certificate
and its private key. The default clusterrole configuration doesn't provide these
permissions.
{{% /alert %}}

**How it works**

All haproxy-ingress instances should declare `--acme-server`
[command-line option]({{% relref "command-line/#acme" %}}), which will start a local
server to answer acme challenges, a work queue to enqueue the domain authorization
and certificate signing, and will also start a leader election to define which
haproxy-ingress instance should perform authorizations and certificate signing.

The haproxy-ingress leader tracks ingress objects that declares the annotation
`ingress.kubernetes.io/cert-signer` with value `acme` and a configured secret name for
TLS certificates. The secret does not need to exist. A new certificate will be issued
if the certificate is old, the secret does not exist or has an invalid certificate, or
the domains of the certificate doesn't cover all the domains configured in the ingress.

Every `24h` or the duration configured in the `--acme-check-period`, and also when the
leader changes, all the certificates from all the tracked ingress will be verified. The
certificate is also verified whenever the list of the domains or the secret name changes,
so the periodic check will, in fact, only issue new certificates when there is `30` days
or less to the certificate expires. This duration can be changed with `acme-expiring`
configuration key.

If an authorization fails, the certificate request is re-enqueued to be tried again after
`5m`. This duration can be changed with `--acme-fail-initial-duration` command-line
option. If the request fails again, it will be re-enqueued after the double of the time,
in this case, after `10m`. The duration will exponentially increase up to `8h` or the
duration defined by the command-line option `--acme-fail-max-duration`. The request will
continue in the work queue until it is successfully processed and stored, or when the
ingress object is untracked, either removing the annotation, removing the secret name or
removing the ingress object itself.

See also:

* [acme command-line options]({{% relref "command-line/#acme" %}}) doc.

---


## Affinity

| Configuration key | Scope | Default | Since |
Expand Down