diff --git a/cmd/traefik/storeconfig.go b/cmd/traefik/storeconfig.go index 534a0682d..296e30608 100644 --- a/cmd/traefik/storeconfig.go +++ b/cmd/traefik/storeconfig.go @@ -67,12 +67,21 @@ func runStoreConfig(kv *staert.KvSource, traefikConfiguration *TraefikConfigurat return err } } - if traefikConfiguration.GlobalConfiguration.ACME != nil && len(traefikConfiguration.GlobalConfiguration.ACME.StorageFile) > 0 { - // convert ACME json file to KV store - localStore := acme.NewLocalStore(traefikConfiguration.GlobalConfiguration.ACME.StorageFile) - object, err := localStore.Load() - if err != nil { - return err + if traefikConfiguration.GlobalConfiguration.ACME != nil { + var object cluster.Object + if len(traefikConfiguration.GlobalConfiguration.ACME.StorageFile) > 0 { + // convert ACME json file to KV store + localStore := acme.NewLocalStore(traefikConfiguration.GlobalConfiguration.ACME.StorageFile) + object, err = localStore.Load() + if err != nil { + return err + } + + } else { + // Create an empty account to create all the keys into the KV store + account := &acme.Account{} + account.Init() + object = account } meta := cluster.NewMetadata(object) @@ -89,6 +98,11 @@ func runStoreConfig(kv *staert.KvSource, traefikConfiguration *TraefikConfigurat if err != nil { return err } + // Force to delete storagefile + err = kv.Delete(kv.Prefix + "/acme/storagefile") + if err != nil { + return err + } } return nil } diff --git a/docs/configuration/acme.md b/docs/configuration/acme.md index 8308e7d41..05a105c1c 100644 --- a/docs/configuration/acme.md +++ b/docs/configuration/acme.md @@ -20,6 +20,12 @@ See also [Let's Encrypt examples](/user-guide/examples/#lets-encrypt-support) an # email = "test@traefik.io" +# File used for certificates storage. +# +# Optional (Deprecated) +# +#storageFile = "acme.json" + # File or key used for certificates storage. # # Required @@ -55,7 +61,7 @@ entryPoint = "https" # # acmeLogging = true -# Enable on demand certificate. +# Enable on demand certificate. (Deprecated) # # Optional # @@ -89,6 +95,10 @@ entryPoint = "https" # main = "local4.com" ``` +!!! note + ACME entryPoint has to be relied to the port 443, otherwise ACME Challenges can not be done. + It's a Let's Encrypt limitation as described on the [community forum](https://community.letsencrypt.org/t/support-for-ports-other-than-80-and-443/3419/72). + ### `storage` ```toml @@ -100,7 +110,7 @@ storage = "acme.json" File or key used for certificates storage. -**WARNING** If you use Traefik in Docker, you have 2 options: +**WARNING** If you use Træfik in Docker, you have 2 options: - create a file on your host and mount it as a volume: ```toml @@ -118,6 +128,14 @@ storage = "/etc/traefik/acme/acme.json" docker run -v "/my/host/acme:/etc/traefik/acme" traefik ``` +!!! note + `storage` replaces `storageFile` which is deprecated. + +!!! note + During Træfik configuration migration from a configuration file to a KV store (thanks to `storeconfig` subcommand as described [here](/user-guide/kv-config/#store-configuration-in-key-value-store)), if ACME certificates have to be migrated too, use both `storageFile` and `storage`. + `storageFile` will contain the path to the `acme.json` file to migrate. + `storage` will contain the key where the certificates will be stored. + ### `dnsProvider` ```toml @@ -146,7 +164,7 @@ Select the provider that matches the DNS domain that will host the challenge TXT | [GoDaddy](https://godaddy.com/domains) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` | | [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, `GCE_SERVICE_ACCOUNT_FILE` | | [Linode](https://www.linode.com) | `linode` | `LINODE_API_KEY` | -| manual | - | none, but run Traefik interactively & turn on `acmeLogging` to see instructions & press Enter. | +| manual | - | none, but run Træfik interactively & turn on `acmeLogging` to see instructions & press Enter. | | [Namecheap](https://www.namecheap.com) | `namecheap` | `NAMECHEAP_API_USER`, `NAMECHEAP_API_KEY` | | [Ns1](https://ns1.com/) | `ns1` | `NS1_API_KEY` | | [Open Telekom Cloud](https://cloud.telekom.de/en/) | `otc` | `OTC_DOMAIN_NAME`, `OTC_USER_NAME`, `OTC_PASSWORD`, `OTC_PROJECT_NAME`, `OTC_IDENTITY_ENDPOINT` | @@ -171,7 +189,7 @@ If `delayDontCheckDNS` is greater than zero, avoid this & instead just wait so m Useful if internal networks block external DNS queries. -### `onDemand` +### `onDemand` (Deprecated) ```toml [acme] @@ -188,7 +206,10 @@ This will request a certificate from Let's Encrypt during the first TLS handshak TLS handshakes will be slow when requesting a hostname certificate for the first time, this can lead to DoS attacks. !!! warning - Take note that Let's Encrypt have [rate limiting](https://letsencrypt.org/docs/rate-limits) + Take note that Let's Encrypt have [rate limiting](https://letsencrypt.org/docs/rate-limits). + +!!! warning + This option is deprecated. ### `onHostRule` @@ -238,7 +259,7 @@ main = "local4.com" ``` You can provide SANs (alternative domains) to each main domain. -All domains must have A/AAAA records pointing to Traefik. +All domains must have A/AAAA records pointing to Træfik. !!! warning Take note that Let's Encrypt have [rate limiting](https://letsencrypt.org/docs/rate-limits). diff --git a/examples/cluster/docker-compose.yml b/examples/cluster/docker-compose.yml index 2dd1b0b46..c45102874 100644 --- a/examples/cluster/docker-compose.yml +++ b/examples/cluster/docker-compose.yml @@ -38,16 +38,7 @@ services: etcdctl-ping: image: tenstartups/etcdctl - command: --endpoints=[10.0.1.12:2379] get "traefik/acme/storagefile" - environment: - ETCDCTL_DIAL_: "TIMEOUT 10s" - ETCDCTL_API : "3" - networks: - - net - - etcdctl-rm: - image: tenstartups/etcdctl - command: --endpoints=[10.0.1.12:2379] del "/traefik/acme/storagefile" + command: --endpoints=[10.0.1.12:2379] get "traefik/acme/storage" environment: ETCDCTL_DIAL_: "TIMEOUT 10s" ETCDCTL_API : "3" @@ -129,7 +120,6 @@ services: image: containous/traefik volumes: - "./traefik.toml:/traefik.toml:ro" - - "./acme.json:/acme.json:ro" command: storeconfig --debug networks: - net diff --git a/examples/cluster/manage_cluster_docker_environment.sh b/examples/cluster/manage_cluster_docker_environment.sh index 9252d2a5e..7f1196157 100755 --- a/examples/cluster/manage_cluster_docker_environment.sh +++ b/examples/cluster/manage_cluster_docker_environment.sh @@ -32,15 +32,6 @@ delete_services() { return 0 } -# Init the environment : get IP address and create needed files -init_acme_json() { - echo "CREATE empty acme.json file" - rm -f $basedir/acme.json && \ - touch $basedir/acme.json && \ - echo "{}" > $basedir/acme.json && \ - chmod 600 $basedir/acme.json # Needed for ACME -} - start_consul() { up_environment consul waiting_counter=12 @@ -76,7 +67,6 @@ start_etcd3() { } start_storeconfig_consul() { - init_acme_json # Create traefik.toml with consul provider cp $basedir/traefik.toml.tmpl $basedir/traefik.toml echo ' @@ -85,29 +75,13 @@ start_storeconfig_consul() { watch = true prefix = "traefik"' >> $basedir/traefik.toml up_environment traefik-storeconfig - rm -f $basedir/traefik.toml && rm -f $basedir/acme.json - # Delete acme-storage-file key + rm -f $basedir/traefik.toml waiting_counter=5 - # Not start Traefik store config if consul is not started - echo "Delete storage file key..." - while [[ -z $(curl -s http://10.0.1.2:8500/v1/kv/traefik/acme/storagefile) && $waiting_counter -gt 0 ]]; do - sleep 5 - let waiting_counter-=1 - done - if [[ $waiting_counter -eq 0 ]]; then - echo "[WARN] Unable to get storagefile key in consul" - else - curl -s --request DELETE http://10.0.1.2:8500/v1/kv/traefik/acme/storagefile - ret=$1 - if [[ $ret -ne 0 ]]; then - echo "[ERROR] Unable to delete storagefile key from consul kv." - fi - fi + delete_services traefik-storeconfig } start_storeconfig_etcd3() { - init_acme_json # Create traefik.toml with consul provider cp $basedir/traefik.toml.tmpl $basedir/traefik.toml echo ' @@ -117,20 +91,15 @@ start_storeconfig_etcd3() { prefix = "/traefik" useAPIV3 = true' >> $basedir/traefik.toml up_environment traefik-storeconfig - rm -f $basedir/traefik.toml && rm -f $basedir/acme.json - # Delete acme-storage-file key + rm -f $basedir/traefik.toml waiting_counter=5 - # Not start Traefik store config if consul is not started + # Don't start Traefik store config if ETCD3 is not started echo "Delete storage file key..." while [[ $(docker-compose -f $doc_file up --exit-code-from etcdctl-ping etcdctl-ping &>/dev/null) -ne 0 && $waiting_counter -gt 0 ]]; do sleep 5 let waiting_counter-=1 done - # Not start Traefik store config if consul is not started - echo "Delete storage file key from ETCD3..." - - up_environment etcdctl-rm && \ - delete_services etcdctl-rm traefik-storeconfig etcdctl-ping + delete_services traefik-storeconfig etcdctl-ping } start_traefik() { diff --git a/examples/cluster/traefik.toml.tmpl b/examples/cluster/traefik.toml.tmpl index bfa09538c..2569e66d8 100644 --- a/examples/cluster/traefik.toml.tmpl +++ b/examples/cluster/traefik.toml.tmpl @@ -12,7 +12,6 @@ defaultEntryPoints = ["http", "https"] [acme] email = "test@traefik.io" storage = "traefik/acme/account" -storageFile = "/acme.json" entryPoint = "https" OnHostRule = true caServer = "http://traefik.boulder.com:4000/directory"