You will find your certificates in the .lego folder of the current working directory:
$ ls -1 ./.lego/certificates
example.com.crt
example.com.issuer.crt
example.com.json
example.com.key
[maybe more files for different domains...]
where
example.com.crt is the server certificate (including the CA certificate),
example.com.key is the private key needed for the server certificate,
example.com.issuer.crt is the CA certificate, and
example.com.json contains some JSON encoded meta information.
For each domain, you will have a set of these four files.
For wildcard certificates (*.example.com), the filenames will look like _.example.com.crt.
The .crt and .key files are PEM-encoded x509 certificates and private keys.
If you’re looking for a cert.pem and privkey.pem, you can just use example.com.crt and example.com.key.
Using a custom certificate signing request (CSR)
The first step in the process of obtaining certificates involves creating a signing request.
This CSR bundles various information, including the domain name(s) and a public key.
By default, lego will hide this step from you, but if you already have a CSR, you can easily reuse it:
Execute the following command:
lego run --http --csr="/path/to/csr.pem"
Create a .lego.yml file with the following content:
lego will infer the domains to be validated based on the contents of the CSR, so make sure the CSR’s Common Name and SubjectAltNames are set correctly.
This guide explains how to get and renew a certificate with the DNS-PERSIST-01 challenge.
Subsections of Obtain or renew certificates
DNS-01 Challenge
This guide explains how to get and renew a certificate with the DNS-01 challenge.
lego comes with support for many providers,
and you need to pick the one where your domain’s DNS settings are set up.
Typically, this is the registrar where you bought the domain, but in some cases this can be another third-party provider.
Using a DNS provider
For this example, let’s assume you have set up Cloudflare for your domain.
Execute the following command:
CLOUDFLARE_EMAIL='you@example.com'\
CLOUDFLARE_API_KEY='yourprivatecloudflareapikey'\
lego run --dns cloudflare --domains 'example.org' --domains '*.example.org'
Create a .lego.yml file with the following content:
This can often be found where your DNS provider has a zone entry for an internal network (i.e., a corporate network, or home LAN) as well as the public internet.
In this case, point lego at an external authoritative server for the zone using the additional parameter --dns.resolvers.
This guide explains how to get and renew a certificate with the HTTP-01 challenge.
Note
The examples require that the lego binary has permission to bind to ports 80.
If your environment does not allow you to bind to these ports, please read Running without root privileges and Port Usage.
Using the built-in web server
Execute the following command:
lego run -d 'example.com' --http
Create a .lego.yml file with the following content:
If you have an existing server running on port 80, the --http option also requires the --http.webroot option.
This just writes the http-01 challenge token to the given directory in the folder .well-known/acme-challenge and does not start a server.
The given directory should be publicly served as / on the domain(s) for the validation to complete.
If the given directory is not publicly served, you will have to support rewriting the request to the directory;
You could also implement a rewrite to rewrite .well-known/acme-challenge to the given directory .well-known/acme-challenge.
You should be able to run an existing webserver on port 80 and have lego write the token file with the HTTP-01 challenge key authorization to <webroot dir>/.well-known/acme-challenge/ by running something like:
Execute the following command:
lego run --http --http.webroot /path/to/webroot --domains example.com
Create a .lego.yml file with the following content:
This guide explains how to get and renew a certificate with the TLS-ALPN-01 challenge.
Note
The examples require that the lego binary has permission to bind to ports 443.
If your environment does not allow you to bind to these ports, please read Running without root privileges and Port Usage.
Execute the following command:
lego run -d 'example.com' --tls
Create a .lego.yml file with the following content:
This is currently not available in most CA production.
Important
This challenge could be less secure than DNS-01 due to its requirements.
This is especially true if your DNS provider does not offer any way to limit the access controls to the specific persistent record required by the DNS-PERSIST-01 challenge.
Replace the Resource value with your Lightsail DNS zone ARN.
You can retrieve the ARN using aws cli by running aws lightsail get-domains --region us-east-1 (Lightsail web console does not show the ARN, unfortunately).
It should be in the format of arn:aws:lightsail:global:<ACCOUNT ID>:Domain/<DOMAIN ID>.
You also need to replace the region in the ARN to us-east-1 (instead of global).
Alternatively, you can also set the Resource to * (wildcard), which allow to access all domain, but this is not recommended.
The following IAM policy document grants access to the required APIs needed by lego to complete the DNS challenge.
A word of caution:
These permissions grant write access to any DNS record in any hosted zone,
so it is recommended to narrow them down as much as possible if you are using this policy in production.
The following AWS IAM policy document describes the least privilege permissions required for lego to complete the DNS challenge.
Write access is limited to a specified hosted zone’s DNS TXT records with a key of _acme-challenge.example.com.
Replace Z11111112222222333333 with your hosted zone ID and example.com with your domain name to use this policy.
Here is an example bash command using the Azure DNS provider:
### Using client secretAZURE_CLIENT_ID=<your service principal client ID> \
AZURE_TENANT_ID=<your service principal tenant ID> \
AZURE_CLIENT_SECRET=<your service principal client secret> \
lego run --dns azuredns -d '*.example.com' -d example.com
### Using client certificateAZURE_CLIENT_ID=<your service principal client ID> \
AZURE_TENANT_ID=<your service principal tenant ID> \
AZURE_CLIENT_CERTIFICATE_PATH=<your service principal certificate path> \
lego run --dns azuredns -d '*.example.com' -d example.com
### Using Azure CLIaz login \
lego run --dns azuredns -d '*.example.com' -d example.com
### Using Managed Identity (Azure VM)AZURE_TENANT_ID=<your service principal tenant ID> \
AZURE_RESOURCE_GROUP=<your target zone resource group name> \
lego run --dns azuredns -d '*.example.com' -d example.com
### Using Managed Identity (Azure Arc)AZURE_TENANT_ID=<your service principal tenant ID> \
IMDS_ENDPOINT=http://localhost:40342 \
IDENTITY_ENDPOINT=http://localhost:40342/metadata/identity/oauth2/token \
lego run --dns azuredns -d '*.example.com' -d example.com
Credentials
Environment Variable Name
Description
AZURE_CLIENT_CERTIFICATE_PATH
Client certificate path
AZURE_CLIENT_ID
Client ID
AZURE_CLIENT_SECRET
Client secret
AZURE_TENANT_ID
Tenant ID
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Additional Configuration
Environment Variable Name
Description
AZURE_AUTH_METHOD
Specify which authentication method to use
AZURE_AUTH_MSI_TIMEOUT
Managed Identity timeout duration
AZURE_ENVIRONMENT
Azure environment, one of: public, usgovernment, and china
AZURE_POLLING_INTERVAL
Time between DNS propagation check in seconds (Default: 2)
AZURE_PRIVATE_ZONE
Set to true to use Azure Private DNS Zones and not public
AZURE_PROPAGATION_TIMEOUT
Maximum waiting time for DNS propagation in seconds (Default: 120)
AZURE_RESOURCE_GROUP
DNS zone resource group
AZURE_SERVICEDISCOVERY_FILTER
Advanced ServiceDiscovery filter using Kusto query condition
AZURE_SUBSCRIPTION_ID
DNS zone subscription ID
AZURE_TTL
The TTL of the TXT record used for the DNS challenge in seconds (Default: 60)
AZURE_ZONE_NAME
Zone name to use inside Azure DNS service to add the TXT record in
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Description
Several authentication methods can be used to authenticate against Azure DNS API.
Default Azure Credentials (default option)
Default Azure Credentials automatically detects in the following locations and prioritized in the following order:
Environment variables for client secret: AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET
Environment variables for client certificate: AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_CERTIFICATE_PATH
Workload identity for resources hosted in Azure environment (see below)
Shared credentials (defaults to ~/.azure folder), used by Azure CLI
Lego automatically finds all visible Azure (private) DNS zones using Azure ResourceGraph query.
This can be limited by specifying environment variable AZURE_SUBSCRIPTION_ID and/or AZURE_RESOURCE_GROUP which limits the
DNS zones to only a subscription or to one resourceGroup.
Additionally environment variable AZURE_SERVICEDISCOVERY_FILTER can be used to filter DNS zones with an addition Kusto filter eg:
resources
| where type =~ "microsoft.network/dnszones"
| ${AZURE_SERVICEDISCOVERY_FILTER}
| project subscriptionId, resourceGroup, name
Client secret
The Azure Credentials can be configured using the following environment variables:
AZURE_CLIENT_ID = “Client ID”
AZURE_CLIENT_SECRET = “Client secret”
AZURE_TENANT_ID = “Tenant ID”
This authentication method can be specifically used by setting the AZURE_AUTH_METHOD environment variable to env.
Client certificate
The Azure Credentials can be configured using the following environment variables:
This authentication method can be specifically used by setting the AZURE_AUTH_METHOD environment variable to env.
Workload identity
Workload identity allows workloads running Azure Kubernetes Services (AKS) clusters to authenticate as an Azure AD application identity using federated credentials.
This must be configured in kubernetes workload deployment in one hand and on the Azure AD application registration in the other hand.
Here is a summary of the steps to follow to use it :
create a ServiceAccount resource, add following annotations to reference the targeted Azure AD application registration : azure.workload.identity/client-id and azure.workload.identity/tenant-id.
on the Deployment resource you must reference the previous ServiceAccount and add the following label : azure.workload.identity/use: "true".
create a federated credentials of type Kubernetes accessing Azure resources, add the cluster issuer URL and add the namespace and name of your kubernetes service account.
This authentication method can be specifically used by setting the AZURE_AUTH_METHOD environment variable to wli.
Azure Managed Identity
Azure Managed Identity (with Azure workload)
The Azure Managed Identity service allows linking Azure AD identities to Azure resources, without needing to manually manage client IDs and secrets.
Workloads with a Managed Identity can manage their own certificates, with permissions on specific domain names set using IAM assignments.
For this to work, the Managed Identity requires the Reader role on the target DNS Zone,
and the DNS Zone Contributor on the relevant _acme-challenge TXT records.
For example, to allow a Managed Identity to create a certificate for “fw01.lab.example.com”, using Azure CLI:
export AZURE_SUBSCRIPTION_ID="00000000-0000-0000-0000-000000000000"export AZURE_RESOURCE_GROUP="rg1"export SERVICE_PRINCIPAL_ID="00000000-0000-0000-0000-000000000000"export AZURE_DNS_ZONE="lab.example.com"export AZ_HOSTNAME="fw01"export AZ_RECORD_SET="_acme-challenge.${AZ_HOSTNAME}"az role assignment create \
--assignee "${SERVICE_PRINCIPAL_ID}"\
--role "Reader"\
--scope "/subscriptions/${AZURE_SUBSCRIPTION_ID}/resourceGroups/${AZURE_RESOURCE_GROUP}/providers/Microsoft.Network/dnszones/${AZURE_DNS_ZONE}"az role assignment create \
--assignee "${SERVICE_PRINCIPAL_ID}"\
--role "DNS Zone Contributor"\
--scope "/subscriptions/${AZURE_SUBSCRIPTION_ID}/resourceGroups/${AZURE_RESOURCE_GROUP}/providers/Microsoft.Network/dnszones/${AZURE_DNS_ZONE}/TXT/${AZ_RECORD_SET}"
A timeout wrapper is configured for this authentication method.
The duration can be configured by setting the AZURE_AUTH_MSI_TIMEOUT.
The default timeout is 2 seconds.
This authentication method can be specifically used by setting the AZURE_AUTH_METHOD environment variable to msi.
Azure Managed Identity (with Azure Arc)
The Azure Arc agent provides the ability to use a Managed Identity on resources hosted outside of Azure
(such as on-prem virtual machines, or VMs in another cloud provider).
While the upstream azidentity SDK will try to automatically identify and use the Azure Arc metadata service,
if you get azuredns: DefaultAzureCredential: failed to acquire a token. error messages,
you may need to set the environment variables:
A timeout wrapper is configured for this authentication method.
The duration can be configured by setting the AZURE_AUTH_MSI_TIMEOUT.
The default timeout is 2 seconds.
This authentication method can be specifically used by setting the AZURE_AUTH_METHOD environment variable to msi.
Azure CLI
The Azure CLI is a command-line tool provided by Microsoft to interact with Azure resources.
It provides an easy way to authenticate by simply running az login command.
The generated token will be cached by default in the ~/.azure folder.
This authentication method can be specifically used by setting the AZURE_AUTH_METHOD environment variable to cli.
Open ID Connect
Open ID Connect is a mechanism that establish a trust relationship between a running environment and the Azure AD identity provider.
It can be enabled by setting the AZURE_AUTH_METHOD environment variable to oidc.
Azure DevOps Pipelines
It can be enabled by setting the AZURE_AUTH_METHOD environment variable to pipeline.
Time between DNS propagation check in seconds (Default: 2)
CLOUDFLARE_PROPAGATION_TIMEOUT
Maximum waiting time for DNS propagation in seconds (Default: 120)
CLOUDFLARE_TTL
The TTL of the TXT record used for the DNS challenge in seconds (Default: 120)
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Description
You may use CF_API_EMAIL and CF_API_KEY to authenticate, or CF_DNS_API_TOKEN, or CF_DNS_API_TOKEN and CF_ZONE_API_TOKEN.
API keys
If using API keys (CF_API_EMAIL and CF_API_KEY), the Global API Key needs to be used, not the Origin CA Key.
Please be aware, that this in principle allows Lego to read and change everything related to this account.
API tokens
With API tokens (CF_DNS_API_TOKEN, and optionally CF_ZONE_API_TOKEN),
very specific access can be granted to your resources at Cloudflare.
See this Cloudflare announcement for details.
The main resources Lego cares for are the DNS entries for your Zones.
It also needs to resolve a domain name to an internal Zone ID in order to manipulate DNS entries.
Hence, you should create an API token with the following permissions:
Zone / Zone / Read
Zone / DNS / Edit
You also need to scope the access to all your domains for this to work.
Then pass the API token as CF_DNS_API_TOKEN to Lego.
Alternatively, if you prefer a more strict set of privileges,
you can split the access tokens:
Create one with Zone / Zone / Read permissions and scope it to all your zones or just the individual zone you need to edit.
This is needed to resolve domain names to Zone IDs and can be shared among multiple Lego installations.
Pass this API token as CF_ZONE_API_TOKEN to Lego.
Create another API token with Zone / DNS / Edit permissions and set the scope to the domains you want to manage with a single Lego installation.
Pass this token as CF_DNS_API_TOKEN to Lego.
Repeat the previous step for each host you want to run Lego on.
It is possible to use the same api token for both variables if it is given Zone:Read and DNS:Edit permission for the zone.
This “paranoid” setup is mainly interesting for users who manage many zones/domains with a single Cloudflare account.
It follows the principle of least privilege and limits the possible damage, should one of the hosts become compromised.
Here is an example bash command using the Designate DNSaaS for Openstack provider:
# With a `clouds.yaml`OS_CLOUD=my_openstack \
lego run --dns designate -d '*.example.com' -d example.com
# orOS_AUTH_URL=https://openstack.example.org \
OS_REGION_NAME=RegionOne \
OS_PROJECT_ID=23d4522a987d4ab529f722a007c27846
OS_USERNAME=myuser \
OS_PASSWORD=passw0rd \
lego run --dns designate -d '*.example.com' -d example.com
# orOS_AUTH_URL=https://openstack.example.org \
OS_REGION_NAME=RegionOne \
OS_AUTH_TYPE=v3applicationcredential \
OS_APPLICATION_CREDENTIAL_ID=imn74uq0or7dyzz20dwo1ytls4me8dry \
OS_APPLICATION_CREDENTIAL_SECRET=68FuSPSdQqkFQYH5X1OoriEIJOwyLtQ8QSqXZOc9XxFK1A9tzZT6He2PfPw0OMja \
lego run --dns designate -d '*.example.com' -d example.com
Credentials
Environment Variable Name
Description
OS_APPLICATION_CREDENTIAL_ID
Application credential ID
OS_APPLICATION_CREDENTIAL_NAME
Application credential name
OS_APPLICATION_CREDENTIAL_SECRET
Application credential secret
OS_AUTH_URL
Identity endpoint URL
OS_PASSWORD
Password
OS_PROJECT_NAME
Project name
OS_REGION_NAME
Region name
OS_USERNAME
Username
OS_USER_ID
User ID
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Additional Configuration
Environment Variable Name
Description
DESIGNATE_POLLING_INTERVAL
Time between DNS propagation check in seconds (Default: 10)
DESIGNATE_PROPAGATION_TIMEOUT
Maximum waiting time for DNS propagation in seconds (Default: 600)
DESIGNATE_TTL
The TTL of the TXT record used for the DNS challenge in seconds (Default: 10)
DESIGNATE_ZONE_NAME
The zone name to use in the OpenStack Project to manage TXT records.
OS_PROJECT_ID
Project ID
OS_TENANT_NAME
Tenant name (deprecated see OS_PROJECT_NAME and OS_PROJECT_ID)
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Description
There are three main ways of authenticating with Designate:
The first one is by using the OS_CLOUD environment variable and a clouds.yaml file.
The second one is using your username and password, via the OS_USERNAME, OS_PASSWORD and OS_PROJECT_NAME environment variables.
The third one is by using an application credential, via the OS_APPLICATION_CREDENTIAL_* and OS_USER_ID environment variables.
For the username/password and application methods, the OS_AUTH_URL and OS_REGION_NAME environment variables are required.
For more information, you can read about the different methods of authentication with OpenStack in the Keystone’s documentation and the gophercloud documentation:
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Additional Configuration
Environment Variable Name
Description
DNSUPDATE_DNS_TIMEOUT
API request timeout in seconds (Default: 10)
DNSUPDATE_POLLING_INTERVAL
Time between DNS propagation check in seconds (Default: 2)
DNSUPDATE_PROPAGATION_TIMEOUT
Maximum waiting time for DNS propagation in seconds (Default: 60)
DNSUPDATE_SEQUENCE_INTERVAL
Time between sequential requests in seconds (Default: 60)
DNSUPDATE_TSIG_ALGORITHM
TSIG algorithm. See miekg/dns#tsig.go for supported values. To disable TSIG authentication, leave the DNSUPDATE_TSIG_KEY or DNSUPDATE_TSIG_SECRET variables unset.
DNSUPDATE_TSIG_FILE
Path to a key file generated by tsig-keygen
DNSUPDATE_TSIG_GSS_KEYTAB_FILE
Path to Kerberos keytab file. The TSIG algorithm must be gss-tsig..
DNSUPDATE_TSIG_GSS_PASSWORD
Kerberos password. The TSIG algorithm must be gss-tsig..
DNSUPDATE_TSIG_GSS_REALM
Kerberos realm. The TSIG algorithm must be gss-tsig..
DNSUPDATE_TSIG_GSS_USERNAME
Kerberos username. The TSIG algorithm must be gss-tsig..
DNSUPDATE_TSIG_KEY
Name of the secret key as defined in DNS server configuration. To disable TSIG authentication, leave the DNSUPDATE_TSIG_KEY variable unset.
DNSUPDATE_TSIG_SECRET
Secret key payload. To disable TSIG authentication, leave the DNSUPDATE_TSIG_SECRET variable unset.
DNSUPDATE_TTL
The TTL of the TXT record used for the DNS challenge in seconds (Default: 120)
DNSUPDATE_ZONES
List of potential zones (separated by commas)
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
TSIG-GSS / RFC3645 / Kerberos
To ease the usage of DNS Update in some environments, lego provides some aliases for RFC3645.
DNSUPDATE_RFC3645_REALM is an alias on DNSUPDATE_TSIG_GSS_REALM
DNSUPDATE_RFC3645_USERNAME is an alias on DNSUPDATE_TSIG_GSS_USERNAME
DNSUPDATE_RFC3645_PASSWORD is an alias on DNSUPDATE_TSIG_GSS_PASSWORD
DNSUPDATE_RFC3645_KEYTAB_FILE is an alias on DNSUPDATE_TSIG_GSS_KEYTAB_FILE
Examples
# Using passwordDNSUPDATE_NAMESERVER=127.0.0.1 \
DNSUPDATE_TSIG_ALGORITHM=gss-tsig. \
DNSUPDATE_RFC3645_REALM=realm.example
DNSUPDATE_RFC3645_USERNAME='xxx'DNSUPDATE_RFC3645_PASSWORD='yyy'lego run --dns dnsupdate -d '*.example.com' -d example.com
# Using a keytab file.DNSUPDATE_NAMESERVER="127.0.0.1"\
DNSUPDATE_TSIG_ALGORITHM=gss-tsig. \
DNSUPDATE_RFC3645_REALM=realm.example \
DNSUPDATE_RFC3645_USERNAME='xxx'\
DNSUPDATE_RFC3645_KEYTAB_FILE="/path/to/my.keytab"\
lego run --dns dnsupdate -d '*.example.com' -d example.com
Here is an example bash command using the DNSimple provider:
DNSIMPLE_OAUTH_TOKEN=1234567890abcdefghijklmnopqrstuvwxyz \
lego run --dns dnsimple -d '*.example.com' -d example.com
Credentials
Environment Variable Name
Description
DNSIMPLE_OAUTH_TOKEN
OAuth token
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Additional Configuration
Environment Variable Name
Description
DNSIMPLE_BASE_URL
API endpoint URL
DNSIMPLE_POLLING_INTERVAL
Time between DNS propagation check in seconds (Default: 2)
DNSIMPLE_PROPAGATION_TIMEOUT
Maximum waiting time for DNS propagation in seconds (Default: 60)
DNSIMPLE_TTL
The TTL of the TXT record used for the DNS challenge in seconds (Default: 120)
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Description
DNSIMPLE_BASE_URL is optional and must be set to production (https://api.dnsimple.com).
if DNSIMPLE_BASE_URL is not defined or empty, the production URL is used by default.
While you can manage DNS records in the DNSimple Sandbox environment,
DNS records will not resolve, and you will not be able to satisfy the ACME DNS challenge.
To authenticate you need to provide a valid API token.
HTTP Basic Authentication is intentionally not supported.
API tokens
You can generate a new API token from your account page.
Only Account API tokens are supported, if you try to use a User API token you will receive an error message.
Solving the DNS-01 challenge using an external program.
Code: exec
Since: v0.5.0
Here is an example bash command using the External program provider:
EXEC_PATH=/the/path/to/myscript.sh \
lego run --dns exec -d '*.example.com' -d example.com
Base Configuration
Environment Variable Name
Description
EXEC_MODE
RAW, none
EXEC_PATH
The path of the the external program.
Additional Configuration
Environment Variable Name
Description
EXEC_POLLING_INTERVAL
Time between DNS propagation check in seconds (Default: 3).
EXEC_PROPAGATION_TIMEOUT
Maximum waiting time for DNS propagation in seconds (Default: 60).
EXEC_SEQUENCE_INTERVAL
Time between sequential requests in seconds (Default: 60).
Description
The file name of the external program is specified in the environment variable EXEC_PATH.
When it is run by lego, three command-line parameters are passed to it:
The action (“present” or “cleanup”), the fully-qualified domain name and the value for the record.
For example, requesting a certificate for the domain ‘my.example.org’ can be achieved by calling lego as follows:
EXEC_PATH=./update-dns.sh \
lego --dns exec --d my.example.org run
It will then call the program ‘./update-dns.sh’ with like this:
The -- is because the token MAY start with a -, and the called program may try and interpret a - as indicating a flag.
In the case of urfave, which is commonly used,
you can use the -- delimiter to specify the start of positional arguments, and handle such a string safely.
Here is an example bash command using the Google Cloud provider:
# Using a service account fileGCE_PROJECT="gc-project-id"\
GCE_SERVICE_ACCOUNT_FILE="/path/to/svc/account/file.json"\
lego run --dns gcloud -d '*.example.com' -d example.com
# Using default credentials with impersonationGCE_PROJECT="gc-project-id"\
GCE_IMPERSONATE_SERVICE_ACCOUNT="target-sa@gc-project-id.iam.gserviceaccount.com"\
lego run --dns gcloud -d '*.example.com' -d example.com
# Using service account key with impersonationGCE_PROJECT="gc-project-id"\
GCE_SERVICE_ACCOUNT_FILE="/path/to/svc/account/file.json"\
GCE_IMPERSONATE_SERVICE_ACCOUNT="target-sa@gc-project-id.iam.gserviceaccount.com"\
lego run --dns gcloud -d '*.example.com' -d example.com
Here is an example bash command using the Hurricane Electric DNS provider:
HURRICANE_TOKENS=example.org:token \
lego run --dns hurricane -d '*.example.com' -d example.com
HURRICANE_TOKENS=my.example.org:token1,demo.example.org:token2 \
lego run --dns hurricane -d my.example.org -d demo.example.org
Credentials
Environment Variable Name
Description
HURRICANE_TOKENS
TXT record names and tokens
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Additional Configuration
Environment Variable Name
Description
HURRICANE_HTTP_TIMEOUT
API request timeout in seconds (Default: 30)
HURRICANE_POLLING_INTERVAL
Time between DNS propagation check in seconds (Default: 2)
HURRICANE_PROPAGATION_TIMEOUT
Maximum waiting time for DNS propagation (Default: 300)
HURRICANE_SEQUENCE_INTERVAL
Time between sequential requests in seconds (Default: 60)
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Before using lego to request a certificate for a given domain or wildcard (such as my.example.org or *.my.example.org),
create a TXT record named _acme-challenge.my.example.org, and enable dynamic updates on it.
Generate a token for each URL with Hurricane Electric’s UI, and copy it down.
Stick to alphanumeric tokens for greatest reliability.
To authenticate with the Hurricane Electric API,
add each record name/token pair you want to update to the HURRICANE_TOKENS environment variable, as shown in the examples.
Record names (without the _acme-challenge. component) and their tokens are separated with colons,
while the credential pairs are concatenated into a comma-separated list, like so:
If you are issuing both a wildcard certificate and a standard certificate for a given subdomain,
you should not have repeat entries for that name, as both will use the same credential.
‘DMAPI’ or ‘SVC’. DMAPI is for resellers accounts. (Default: DMAPI)
JOKER_PASSWORD
Joker.com password
JOKER_USERNAME
Joker.com username
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Additional Configuration
Environment Variable Name
Description
JOKER_HTTP_TIMEOUT
API request timeout in seconds (Default: 60)
JOKER_POLLING_INTERVAL
Time between DNS propagation check in seconds (Default: 2)
JOKER_PROPAGATION_TIMEOUT
Maximum waiting time for DNS propagation in seconds (Default: 120)
JOKER_SEQUENCE_INTERVAL
Time between sequential requests in seconds (Default: 60), only with ‘SVC’ mode
JOKER_TTL
The TTL of the TXT record used for the DNS challenge in seconds (Default: 120)
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
SVC mode
In the SVC mode, username and password are not your email and account passwords, but those displayed in Joker.com domain dashboard when enabling Dynamic DNS.
please log in at Joker.com, visit ‘My Domains’,
find the domain you want to add Let’s Encrypt certificate for, and chose “DNS” in the menu
on the top right, you will find the setting for ‘Dynamic DNS’.
If not already active, please activate it.
It will not affect any other already existing DNS records of this domain.
please take a note of the credentials which are now shown as ‘Dynamic DNS Authentication’, consisting of a ‘username’ and a ‘password’.
this is all you have to do here - and only once per domain.
Here is an example bash command using the Manual provider:
lego run --dns manual -d '*.example.com' -d example.com
Additional Configuration
Environment Variable Name
Description
MANUAL_POLLING_INTERVAL
Time between DNS propagation check in seconds (Default: 2)
MANUAL_PROPAGATION_TIMEOUT
Maximum waiting time for DNS propagation in seconds (Default: 60)
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Example
To start using the CLI prompt “provider”, start lego with --dns manual:
$ lego run --dns manual -d example.com
What follows are a few log print-outs, interspersed with some prompts, asking for you to do perform some actions:
No key found for account you@example.com. Generating a P256 key.
Saved key to ./.lego/accounts/acme-v02.api.letsencrypt.org/you@example.com/keys/you@example.com.key
Please review the TOS at https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
Do you accept the TOS? Y/n
If you accept the linked Terms of Service, hit Enter.
[INFO] acme: Registering account for you@example.com
!!!! HEADS UP !!!!
Your account credentials have been saved in your
configuration directory at "./.lego/accounts".
You should make a secure backup of this folder now. This
configuration directory will also contain private keys
generated by lego and certificates obtained from the ACME
server. Making regular backups of this folder is ideal.
[INFO] [example.com] acme: Obtaining bundled SAN certificate
[INFO] [example.com] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz-v3/2345678901
[INFO] [example.com] acme: Could not find solver for: tls-alpn-01
[INFO] [example.com] acme: Could not find solver for: http-01
[INFO] [example.com] acme: use dns-01 solver
[INFO] [example.com] acme: Preparing to solve DNS-01
lego: Please create the following TXT record in your example.com. zone:
_acme-challenge.example.com. 120 IN TXT "hX0dPkG6Gfs9hUvBAchQclkyyoEKbShbpvJ9mY5q2JQ"
lego: Press 'Enter' when you are done
Do as instructed, and create the TXT records, and hit Enter.
[INFO] [example.com] acme: Trying to solve DNS-01
[INFO] [example.com] acme: Checking DNS record propagation using [192.168.8.1:53]
[INFO] Wait for propagation [timeout: 1m0s, interval: 2s]
[INFO] [example.com] acme: Waiting for DNS record propagation.
[INFO] [example.com] The server validated our request
[INFO] [example.com] acme: Cleaning DNS-01 challenge
lego: You can now remove this TXT record from your example.com. zone:
_acme-challenge.example.com. 120 IN TXT "hX0dPkG6Gfs9hUvBAchQclkyyoEKbShbpvJ9mY5q2JQ"
[INFO] [example.com] acme: Validations succeeded; requesting certificates
[INFO] [example.com] Server responded with a certificate.
As mentioned, you can now remove the TXT record again.
To enable API access on the Namecheap production environment, some opaque requirements must be met.
More information in the section Enabling API Access of the Namecheap documentation.
(2020-08: Account balance of $50+, 20+ domains in your account, or purchases totaling $50+ within the last 2 years.)
Code: namecheap
Since: v0.3.0
Here is an example bash command using the Namecheap provider:
Here is an example bash command using the Nicmanager provider:
## Login using emailNICMANAGER_API_EMAIL ="you@example.com"\
NICMANAGER_API_PASSWORD ="password"\
# Optionally, if your account has TOTP enabled, set the secret hereNICMANAGER_API_OTP ="long-secret"\
lego run --dns nicmanager -d '*.example.com' -d example.com
## Login using account name + usernameNICMANAGER_API_LOGIN ="myaccount"\
NICMANAGER_API_USERNAME ="myuser"\
NICMANAGER_API_PASSWORD ="password"\
# Optionally, if your account has TOTP enabled, set the secret hereNICMANAGER_API_OTP ="long-secret"\
lego run --dns nicmanager -d '*.example.com' -d example.com
Credentials
Environment Variable Name
Description
NICMANAGER_API_EMAIL
Email-based login
NICMANAGER_API_LOGIN
Login, used for Username-based login
NICMANAGER_API_PASSWORD
Password, always required
NICMANAGER_API_USERNAME
Username, used for Username-based login
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Additional Configuration
Environment Variable Name
Description
NICMANAGER_API_MODE
mode: ‘anycast’ or ‘zones’ (for FreeDNS) (default: ‘anycast’)
NICMANAGER_API_OTP
TOTP Secret (optional)
NICMANAGER_HTTP_TIMEOUT
API request timeout in seconds (Default: 10)
NICMANAGER_POLLING_INTERVAL
Time between DNS propagation check in seconds (Default: 2)
NICMANAGER_PROPAGATION_TIMEOUT
Maximum waiting time for DNS propagation in seconds (Default: 300)
NICMANAGER_TTL
The TTL of the TXT record used for the DNS challenge in seconds (Default: 900)
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Description
You can log in using your account name + username or using your email address.
Optionally, if TOTP is configured for your account, set NICMANAGER_API_OTP.
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Additional Configuration
Environment Variable Name
Description
PDNS_API_VERSION
Skip API version autodetection and use the provided version number.
PDNS_HTTP_TIMEOUT
API request timeout in seconds (Default: 30)
PDNS_POLLING_INTERVAL
Time between DNS propagation check in seconds (Default: 2)
PDNS_PROPAGATION_TIMEOUT
Maximum waiting time for DNS propagation in seconds (Default: 120)
PDNS_SERVER_NAME
Name of the server in the URL, ’localhost’ by default
PDNS_TTL
The TTL of the TXT record used for the DNS challenge in seconds (Default: 120)
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Information
Tested and confirmed to work with PowerDNS authoritative server 3.4.8 and 4.0.1. Refer to PowerDNS documentation instructions on how to enable the built-in API interface.
PowerDNS Notes:
PowerDNS API does not currently support SSL, therefore you should take care to ensure that traffic between lego and the PowerDNS API is over a trusted network, VPN etc.
In order to have the SOA serial automatically increment each time the _acme-challenge record is added/modified via the API, set SOA-EDIT-API to INCEPTION-INCREMENT for the zone in the domainmetadata table
Some PowerDNS servers doesn’t have root API endpoints enabled and API version autodetection will not work. In that case version number can be defined using PDNS_API_VERSION.
Record IDs mapping with domains (ex: example.com:123:456,example.org:789,foo.example.com:147)
SELFHOSTDE_USERNAME
Username
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Additional Configuration
Environment Variable Name
Description
SELFHOSTDE_HTTP_TIMEOUT
API request timeout in seconds (Default: 30)
SELFHOSTDE_POLLING_INTERVAL
Time between DNS propagation check in seconds (Default: 30)
SELFHOSTDE_PROPAGATION_TIMEOUT
Maximum waiting time for DNS propagation in seconds (Default: 240)
SELFHOSTDE_TTL
The TTL of the TXT record used for the DNS challenge in seconds (Default: 120)
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
SelfHost.de doesn’t have an API to create or delete TXT records,
there is only an “unofficial” and undocumented endpoint to update an existing TXT record.
So, before using lego to request a certificate for a given domain or wildcard (such as my.example.org or *.my.example.org),
you must create:
one TXT record named _acme-challenge.my.example.org if you are not using wildcard for this domain.
two TXT records named _acme-challenge.my.example.org if you are using wildcard for this domain.
After that you must edit the TXT record(s) to get the ID(s).
You then must prepare the SELFHOSTDE_RECORDS_MAPPING environment variable with the following format:
Here is an example bash command using the Technitium provider:
TECHNITIUM_SERVER_BASE_URL="https://localhost:5380"\
TECHNITIUM_API_TOKEN="xxxxxxxxxxxxxxxxxxxxx"\
lego run --dns technitium -d '*.example.com' -d example.com
Credentials
Environment Variable Name
Description
TECHNITIUM_API_TOKEN
API token
TECHNITIUM_SERVER_BASE_URL
Server base URL
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Additional Configuration
Environment Variable Name
Description
TECHNITIUM_HTTP_TIMEOUT
API request timeout in seconds (Default: 30)
TECHNITIUM_POLLING_INTERVAL
Time between DNS propagation check in seconds (Default: 2)
TECHNITIUM_PROPAGATION_TIMEOUT
Maximum waiting time for DNS propagation in seconds (Default: 60)
TECHNITIUM_TTL
The TTL of the TXT record used for the DNS challenge in seconds (Default: 120)
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Technitium DNS Server supports Dynamic Updates (RFC2136) for primary zones,
so you can also use the RFC2136 provider.
RFC2136 provider is much better compared to the HTTP API option from security perspective.
Technitium recommends to use it in production over the HTTP API.
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Additional Configuration
Environment Variable Name
Description
VINYLDNS_HTTP_TIMEOUT
API request timeout in seconds (Default: 30)
VINYLDNS_POLLING_INTERVAL
Time between DNS propagation check in seconds (Default: 4)
VINYLDNS_PROPAGATION_TIMEOUT
Maximum waiting time for DNS propagation in seconds (Default: 120)
VINYLDNS_QUOTE_VALUE
Adds quotes around the TXT record value (Default: false)
VINYLDNS_TTL
The TTL of the TXT record used for the DNS challenge in seconds (Default: 30)
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
The vinyldns integration makes use of dotted hostnames to ease permission management.
Users are required to have DELETE ACL level or zone admin permissions on the VinylDNS zone containing the target host.
Here is an example bash command using the webnames.ru provider:
WEBNAMESRU_API_KEY=xxxxxx \
lego run --dns webnamesru -d '*.example.com' -d example.com
Credentials
Environment Variable Name
Description
WEBNAMESRU_API_KEY
Domain API key
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
Additional Configuration
Environment Variable Name
Description
WEBNAMESRU_HTTP_TIMEOUT
API request timeout in seconds (Default: 30)
WEBNAMESRU_POLLING_INTERVAL
Time between DNS propagation check in seconds (Default: 2)
WEBNAMESRU_PROPAGATION_TIMEOUT
Maximum waiting time for DNS propagation in seconds (Default: 60)
The environment variable names can be suffixed by _FILE to reference a file instead of a value.
More information here.
API Key
To obtain the key, you need to change the DNS server to *.nameself.com: Personal account / My domains and services / Select the required domain / DNS servers
The API key can be found: Personal account / My domains and services / Select the required domain / Zone management / acme.sh or certbot settings
This section contains some tips and tricks for using lego.
Subsections of Advanced usages
Hooks
This section describes how to use hooks.
There are three hooks available:
pre-hook
deploy-hook
post-hook
Pre-Hook
This hook is executed, before the creation or the renewal, in cases where a certificate will be effectively created/renewed.
Execute the following command:
lego run -d 'example.com' --pre-hook='./my-pre-hook.sh'
Define the following section in your .lego.yaml file:
hooks:
pre:
command: './my-pre-hook.sh'
Deploy-Hook
This hook is executed after the successful creation or the renewal of a certificate.
Execute the following command:
lego run -d 'example.com' --deploy-hook='./my-deploy-hook.sh'
Define the following section in your .lego.yaml file:
hooks:
deploy:
command: './my-deploy-hook.sh'
Post-Hook
This hook is executed, after the creation or the renewal, in cases where a certificate is created/renewed, regardless of whether any errors occurred.
Execute the following command:
lego run -d 'example.com' --post-hook='./my-post-hook.sh'
Define the following section in your .lego.yaml file:
hooks:
post:
command: './my-post-hook.sh'
Environment Variables
Some details are passed through environment variables to help you with your hooks:
Environment Variable
Description
LEGO_HOOK_ACCOUNT_ID
The account ID.
LEGO_HOOK_ACCOUNT_EMAIL
The account email (if available).
LEGO_HOOK_ACCOUNT_SERVER
The server related to the account.
LEGO_HOOK_CERT_NAME
The name/ID of the certificate.
LEGO_HOOK_CERT_NAME_SANITIZED
The sanitized name/ID of the certificate.
LEGO_HOOK_CERT_KEY_TYPE
The type of the certificate key.
LEGO_HOOK_CERT_DOMAINS
The domains of the certificate.
LEGO_HOOK_CERT_PATH
The path of the certificate.
LEGO_HOOK_CERT_KEY_PATH
The path of the certificate key.
LEGO_HOOK_ISSUER_CERT_PATH
The path of the issuer certificate.
LEGO_HOOK_CERT_PEM_PATH
(only with --pem) The path to the PEM certificate.
LEGO_HOOK_CERT_PFX_PATH
(only with --pfx) The path to the PFX certificate.
Use Case
A typical use case is distributing the certificate for other services and reload them if necessary.
Since many programs understand PEM-formatted TLS certificates, it is relatively simple to use certificates for more than a web server.
This example script installs the new certificate for a mail server and reloads it.
Beware: this is just a starting point, error checking is omitted for brevity.
#!/bin/bash
# copy certificates to a directory controlled by Postfixpostfix_cert_dir="/etc/postfix/certificates"# our Postfix server only handles mail for @example.com domainif["$LEGO_HOOK_CERT_NAME"="example.com"]; then install -u postfix -g postfix -m 0644"$LEGO_HOOK_CERT_PATH""$postfix_cert_dir" install -u postfix -g postfix -m 0640"$LEGO_HOOK_CERT_KEY_PATH""$postfix_cert_dir" systemctl reload postfix@-service
fi
Certificate Operations
This section describes certificate operations.
List Certificates
You can list all certificates managed by lego with:
lego certificates list
Output:
Found the following certificates:
_.example.com
├── Status: this certificate is expired.
├── Domains: *.example.com, example.com
├── Expiration Date: 2026-04-08 21:02:27 +0000 UTC
├── Issuer: CN=(STAGING) Puzzling Parsnip E7,O=(STAGING) Let's Encrypt,C=US
└── Certificate Path: /path/to/.lego/certificates/_.example.com.crt
...
The account will be imported and added to .lego/accounts/.
Options
This section describes advanced options that can be used to configure lego.
LEGO_CA_CERTIFICATES
The environment variable LEGO_CA_CERTIFICATES allows to specify the path to PEM-encoded CA certificates
that can be used to authenticate an ACME server with an HTTPS certificate not issued by a CA in the system-wide trusted root list.
Multiple file paths can be added by using : (unix) or ; (Windows) as a separator.
Example:
# On Unix systemLEGO_CA_CERTIFICATES=/foo/cert1.pem:/foo/cert2.pem
LEGO_CA_SYSTEM_CERT_POOL
The environment variable LEGO_CA_SYSTEM_CERT_POOL can be used to define if the certificates pool must use a copy of the system cert pool.
Example:
LEGO_CA_SYSTEM_CERT_POOL=true
LEGO_CA_SERVER_NAME
The environment variable LEGO_CA_SERVER_NAME allows to specify the CA server name used to authenticate an ACME server
with an HTTPS certificate not issued by a CA in the system-wide trusted root list.
Example:
LEGO_CA_SERVER_NAME=foo
LEGO_DISABLE_CNAME_SUPPORT
By default, lego follows CNAME, the environment variable LEGO_DISABLE_CNAME_SUPPORT allows to disable this support.
Example:
LEGO_DISABLE_CNAME_SUPPORT=true
There is a Let’s Encrypt blog post about the behavior of CNAMEs.
LEGO_DEBUG_CLIENT_VERBOSE_ERROR
The environment variable LEGO_DEBUG_CLIENT_VERBOSE_ERROR allows to enrich error messages from some of the DNS clients.
Example:
LEGO_DEBUG_CLIENT_VERBOSE_ERROR=true
LEGO_DEBUG_DNS_API_HTTP_CLIENT
⚠️ WARNING: This will expose credentials in the log output! ⚠️
Do not run this in production environments, or if you can’t be sure that logs aren’t accessed by third parties or tools (like log collectors).
You have been warned. Here be dragons.
The environment variable LEGO_DEBUG_DNS_API_HTTP_CLIENT allows debugging the DNS API interaction.
It will dump the full request and response to the log output.
Some DNS providers don’t support this option.
Example:
LEGO_DEBUG_DNS_API_HTTP_CLIENT=true
LEGO_DEBUG_ACME_HTTP_CLIENT
The environment variable LEGO_DEBUG_ACME_HTTP_CLIENT allows debug the calls to the ACME server.
Example:
LEGO_DEBUG_ACME_HTTP_CLIENT=true
CA servers
This page describes the usage of CA servers (ACME servers).
Note
Any CA server that follow RFC 8855 can be used with lego.
Let’s Encrypt ACME server
lego defaults to communicating with the production Let’s Encrypt ACME server.
If you’d like to test something without issuing real certificates, consider using the staging endpoint instead:
lego run --server='letsencrypt-staging' …
CA Server short-codes
To ease the usage of the CA server in most of cases, we provide a short-code for each already known CA server.
lego supports three different ways to authenticate with ZeroSSL.
Access key: if the environment variable ZERO_SSL_ACCESS_KEY is set.
Email: if the email address is set and the environment variable ZERO_SSL_ACCESS_KEY is not set.
External Account Binding (EAB): if none of the above elements are defined.
Archives
This section describes operations on the archives.
List
You can list all the backuped accounts and certificates with the following command:
lego archives list
Restore
You can restore a backup of an account or a certificate with the following command:
lego archives restore
The command will ask you for the backup file to restore.
Tips
This section contains some tips and tricks for using lego.
Automatic Renewal
It is tempting to create a cron job (or systemd timer) to automatically renew all you certificates.
When doing so, please note that some cron defaults will cause a measurable load on the ACME provider’s infrastructure.
Notably @daily jobs run at midnight.
To both counteract load spikes (caused by all lego users) and reduce subsequent renewal failures, we were asked to implement a small random delay for non-interactive renewals.1
Since v4.8.0, lego will pause for up to 8 minutes to help spread the load.
You can help further, by adjusting your crontab entry, like so:
# avoid:#@daily /usr/bin/lego ...#@midnight /usr/bin/lego ...#0 0 * * * /usr/bin/lego ...# instead, use a randomly chosen time:353***/usr/bin/lego ...
If you use systemd timers, consider doing something similar, and/or introduce a RandomizedDelaySec:
[Unit]Description=Renew certificates[Timer]Persistent=true# avoid:#OnCalendar=*-*-* 00:00:00#OnCalendar=daily# instead, use a randomly chosen time:OnCalendar=*-*-* 3:35# add extra delay, here up to 1 hour:RandomizedDelaySec=1h[Install]WantedBy=timers.target
Running without root privileges
The CLI does not require root permissions but needs to bind to port 80 and 443 for certain challenges.
To run the CLI without sudo, you have four options:
Use setcap 'cap_net_bind_service=+ep' /path/to/lego (Linux only)
Pass the --http.address or/and the --tls.address option and specify a custom port to bind to. In this case you have to forward port 80/443 to these custom ports (see Port Usage).
Pass the --http.webroot option and specify the path to your webroot folder. In this case the challenge will be written in a file in .well-known/acme-challenge/ inside your webroot.
Pass the --dns option and specify a DNS provider.
Port Usage
By default, lego assumes it is able to bind to ports 80 and 443 to solve challenges.
If this is not possible in your environment, you can use the --http.address and --tls.address options to instruct
lego to listen on that interface:port for any incoming challenges.
If you are using either of these options, make sure you setup a proxy to redirect traffic to the chosen ports.
HTTP Port: All plaintext HTTP requests to port 80 which begin with a request path of /.well-known/acme-challenge/ for the HTTP challenge2.
TLS Port: All TLS handshakes on port 443 for the TLS-ALPN challenge.
This traffic redirection is only needed as long as lego solves challenges. As soon as you have received your certificates you can deactivate the forwarding.
DNS Resolvers and Challenge Verification
When using a DNS challenge provider (via --dns <name>), Lego tries to ensure the ACME challenge token is properly setup before instructing the ACME provider to perform the validation.
This involves a few DNS queries to different servers:
Determining the DNS zone and resolving CNAMEs.
The DNS zone for a given domain is determined by the SOA record, which contains the authoritative name server for the domain and all its subdomains.
For simple domains like example.com, this is usually example.com itself.
For other domains (like fra.eu.cdn.example.com), this can get complicated, as cdn.example.com may be delegated to the CDN provider, which means for cdn.example.com must exist a different SOA record.
To find the correct zone, Lego requests the SOA record for each DNS label (starting on the leaf domain, i.e. the left-most DNS label).
If there is no SOA record, Lego requests the SOA record of the parent label, then for its parent, etc., until it reaches the apex domain3.
Should any DNS label on the way be a CNAME, it is resolved as per usual.
In the default configuration, Lego uses the system name servers for this, and falls back to Google’s DNS servers, should they be absent.
Verifying the challenge token.
The _acme-challenge.<yourdomain> TXT record must be correctly installed.
Lego verifies this by directly querying the authoritative name server for this record (as detected in the previous step).
Strictly speaking, this verification step is not necessary, but helps to protect your ACME account.
Remember that some ACME providers impose a rate limit on certain actions (at the time of writing, Let’s Encrypt allows 300 new certificate orders per account per 3 hours).
There are also situations where this verification step doesn’t work as expected:
A “split DNS” setup gives different answers to clients on the internal network (Lego) vs. on the public internet (ACME server).
With “hidden master” setups, Lego may be able to directly talk to the primary DNS server, while the _acme-challenge record might not have fully propagated to the (public) secondary servers, yet.
The effect is the same: Lego determined the challenge token to be installed correctly, while the ACME server has a different view and rejects the certificate order.
In these cases, you can instruct Lego to use a different DNS resolver, using the --dns.resolvers flag.
You should prefer one on the public internet, otherwise you might be susceptible to the same problem.
You must ensure that incoming validation requests contains the correct value for the HTTP Host header. If you operate lego behind a non-transparent reverse proxy (such as Apache or NGINX), you might need to alter the header field using --http.proxy-header X-Forwarded-Host. ↩︎
The apex domain is the domain you have registered with your domain registrar. For gTLDs (.com, .fyi) this is the 2nd level domain, but for ccTLDs, this can either be the 2nd level (.de) or 3rd level domain (.co.uk). ↩︎
References
This section contains references to command, flags, and the configuration file.
This page lists all the available commands and flags.
Subsections of References
Configuration file
This describes the configuration file format.
lego looks for configuration files in the following paths from the current working directory:
.lego.yml
.lego.yaml
The configuration file can be validated with the JSON Schema: lego.jsonschema.json
Global configuration
# Path to the directory to use for storing the data.## Default: ./legostorage: /tmp/lego/# The network stack to use.# It can be:# - ipv6only# - ipv4only## Default: bothnetworkStack: ipv6only# The user agent to use when connecting to the ACME server.## Default: information related to lego.userAgent: foo
Certificates
# When a certificate definition is removed from the configuration file, the corresponding certificate files are archived.# The archives are deleted after 30 days.certificates:
# The ID/Name of the certificate.myCert:
# The challenge type.# It can be:# 1. `http-01` (This is a special name to use the default HTTP challenge provider)# 2. `tls-alpn-01` (This is a special name to use the default TLS-ALPN-01 challenge provider)# 3. a reference to the ID of a challenge provider defined in the configuration section `challenges`.## Required.challenge: one# The account ID/Name.# If there is no account defined in the configuration file, the default account is used.# If there is only one account defined in the configuration file, the account ID can be omitted.## Required.account: foo# The key type used to generate the certificate.# If not set, use the account key type, or EC256 if no account key type is defined.## Required.keyType: RSA2048# The domains to request a certificate for.## Mutually exclusive with `csr`.domains:
- example.com - '*.example.com'# The path to a Certificate Signing Request (CSR) file.## Mutually exclusive with `domains`.csr: /tmp/foo.csr# The preferred chain to use.## Optional.preferredChain: "ISRG Root X1"# The ACME server profile## Optional.profile: "tls"# Enable the use of the Common Name (CN) in the certificate.# CN is deprecated and should not be used.## Optional.# Default: falseenableCommonName: true# The notBefore field in the certificate.## Optional.notBefore: ""# The notAfter field in the certificate.## Optional.notAfter: ""# Do not create a certificate bundle by adding the issuers certificate to the new certificate.## Default: falsenoBundle: true# Include the OCSP must staple TLS extension in the CSR and generated certificate.# Only works if the CSR is generated by lego.## Default: truemustStaple: false# Force the authorizations to be relinquished even if the certificate request was successful.## Default: falsealwaysDeactivateAuthorizations: true# Options for the certificate renewal.## Optional.renew:
# Reuse the private key if it exists.## Optional.# Default: falsereuseKey: true# The number of days left on a certificate to renew it.# # By default, compute dynamically, based on the lifetime of the certificate(s), when to renew:# use 1/3rd of the lifetime left, or 1/2 of the lifetime for short-lived certificates.days: 1# Do not add a random sleep before the renewal.## We do not recommend using this option if you are doing your renewals in an automated way.## Default: falsedisableRandomSleep: true# ARI configuration.## Optional.ari:
# Disable the ARI mechanism.## Default: falsedisable: true# The maximum duration you're willing to sleep for a renewal time returned by the renewalInfo endpoint.# # Default: 0swaitToRenewDuration: 1m# Generate an additional .pfx (PKCS#12) file by concatenating the .key and .crt and issuer .crt files together.# # Optional.pfx:
# The password used to encrypt the .pfx (PCKS#12) file.## Required.password: xxx# The encoding format to use when encrypting the .pfx (PCKS#12) file.## Supported:# - DES# - RC2# - SHA256# - PBMAC1## Optional.# Default: RC2format: PBMAC1
Challenges
# The challenge configurations.challenges:
# The ID/Name of the challenge.## Required.one:
# The HTTP-01 challenge configuration.## Optional.http:
# The address to listen on.## Default: ":80"address: ":80"# Delay between the starts of the HTTP server (use for HTTP-01 based challenges) and the validation of the challenge.## Default: 0sdelay: 6s# Validate against this HTTP header when solving HTTP-01 based challenges behind a reverse proxy.## Optional.proxyHeader: Host# The webroot folder to use for HTTP-01 based challenges to write directly to the .well-known/acme-challenge file.# This disables the built-in server and expects the given directory to be publicly served with access to .well-known/acme-challenge".## Optional.webroot: /tmp/webroot# The memcached host(s) to use for HTTP-01 based challenges. Challenges will be written to all specified hosts.## Optional.memcachedHosts:
- memcached:11211# Tthe S3 bucket name to use for HTTP-01 based challenges. Challenges will be written to the S3 bucket.s3Bucket: 's3-bucket'# The ID/Name of the challenge.## Required.two:
# The TLS-ALPN-01 challenge configuration.## Optional.tls:
# The address to listen on.## Default: ":443"address: ":443"# Delay between the start of the TLS listener (use for TLSALPN-01 based challenges) and the validation of the challenge.## Default: 0sdelay: 6s# The ID/Name of the challenge.## Required.three:
# The DNS-01 challenge configuration.## Optional.dns:
# The DNS provider.## Required.provider: cloudflare# The path to the dotenv file containing the credentials.## Optional.envFile: /tmp/secrets/.env# The configuration related to propagation check.## Optional.propagation:
# By setting this option to true,# disables the need to await propagation of the TXT record to all authoritative name servers.## Default: falsedisableAuthoritativeNameservers: true# By setting this option to true,# disables the need to await propagation of the TXT record to all recursive name servers (aka resolvers).## Default: falsedisableRecursiveNameservers: true# Disables all the propagation checks of the TXT record and uses a wait duration instead.## This option is strongly discouraged.## Default: 0wait: 5s# Set the DNS timeout value to a specific value in seconds. Used only when performing authoritative name server queries.## Default: 10dnsTimeout: 30# Set the resolvers to use for performing (recursive) CNAME resolving and apex domain determination.## For DNS-01 challenge verification, the authoritative DNS server is queried directly.## Supported syntax: host:port.## Optional.# The default is to use the system resolvers, or Google's DNS resolvers if the system ones cannot be determined.resolvers:
- 1.1.1.1:53# The ID/Name of the challenge.## Required.four:
# The DNS-PERSIST-01 challenge configuration.## Optional.dnsPersist:
# Override the issuer-domain-name to use for DNS-PERSIST-01 when multiple are offered.# Must be offered by the challenge.## Optional.issuerDomainName: example.com# Set the optional `persistUntil` for DNS-PERSIST-01 records as an RFC3339 timestamp.## Optional.persistUntil: 2020-01-01T00:00:00Z# The configuration related to propagation check.## Optional.propagation:
# By setting this option to true,# disables the need to await propagation of the TXT record to all authoritative name servers.## Default: falsedisableAuthoritativeNameservers: true# By setting this option to true,# disables the need to await propagation of the TXT record to all recursive name servers (aka resolvers).## Default: falsedisableRecursiveNameservers: true# Disables all the propagation checks of the TXT record and uses a wait duration instead.## This option is strongly discouraged.## Default: 0wait: 5s
Accounts
Defining an account is optional: lego will create one for you by default on the Let’s Encrypt ACME server.
If you want to use a different ACME server, or if you want to customize the account, you can define it in the configuration file.
# When an account definition is removed from the configuration file, the corresponding account files are archived.# The archives are deleted after 30 days.accounts:
# The ID/Name of the account.## Required.myAccount:
# The ACME server.## It can be:# 1. a URL# 2. a short code (see the shortcode section)# 3. a reference to the ID of a server defined in the servers configuration section## Default: https://acme-v02.api.letsencrypt.org/directoryserver: https://example.com/dir# The account email.## Optional.email: foo@example.com# The key type used to generate the account private key.## Default: EC256keyType: RSA2048# The acceptance of the terms of service.## Default: falseacceptsTermsOfService: true# The External Account Binding (EAB) configuration.## Optional.eab:
# The External Account Binding (EAB) KID.## Required.kid: foo# The External Account Binding (EAB) HMAC key.## Required.hmacKey: foo
Servers
servers:
# The ID/Name of the server.## Required.myServer:
# The ACME server URL.## Required.url: https://example.com/dir# ACME overall requests limit.## Default: 18overallRequestLimit: 7# Skip the TLS verification of the ACME server.## Default: falsetlsSkipVerify: true# The HTTP timeout value to a specific value in seconds.## Default: 30httpTimeout: 60# The certificate timeout value to a specific value in seconds.# Only used when getting certificates.## Default: 30certTimeout: 60
# Hooks configuration.## Optional.hooks:
# The pre-hook.## Optional.pre:
# The command to execute.## Required.command: "./my-pre-hook.sh"# The timeout of the command.## optional.timeout: 3s# The deploy-hook.## Optional.deploy:
# The command to execute.## Required.command: "./my-deploy-hook.sh"# The timeout of the command.## optional.timeout: 3s# The post-hook.## Optional.post:
# The command to execute.## Required.command: "./my-post-hook.sh"# The timeout of the command.## optional.timeout: 3s
Commands & Flags
This page lists all the available commands and flags.
Main Command
NAME:
lego - ACME client written in Go
USAGE:
lego [global options] [command [command options]]
COMMANDS:
run Get or renew a certificate
certificates Certificates management.
accounts Accounts management.
archives Archives management.
dnshelp Shows additional help for the '--dns' global option
migrate Migrate certificates and accounts.
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--help, -h show help
Flags related to logs:
--log.format string Set the logging format. Supported values: 'colored', 'text', 'json'. (default: "colored") [$LEGO_LOG_FORMAT]
--log.level string Set the logging level. Supported values: 'debug', 'info', 'warn', 'error'. (default: "info") [$LEGO_LOG_LEVEL]
Flags related to the configuration file:
--config string Path to the configuration file. [$LEGO_CONFIG]
run command
NAME:
lego run - Get or renew a certificate
USAGE:
lego run [options]
OPTIONS:
--accept-tos, -a By setting this flag to true, you indicate that you accept the current CA terms of service. [$LEGO_ACCEPT_TOS]
--domains string, -d string [ --domains string, -d string ] Add a domain. For multiple domains either repeat the option or provide a comma-separated list. [$LEGO_DOMAINS]
--email string, -m string Email used for registration and recovery contact. [$LEGO_EMAIL]
--help, -h show help
--key-type string, -k string Key type to use for private keys. Supported: EC256, EC384, RSA2048, RSA3072, RSA4096, RSA8192. (default: "EC256") [$LEGO_KEY_TYPE]
--server string, -s string CA (ACME server). It can be either a URL or a shortcode.
(available shortcodes: actalis, digicert, freessl, globalsign, googletrust, googletrust-staging, letsencrypt, letsencrypt-staging, litessl, peeringhub, sslcomecc, sslcomrsa, sectigo, sectigoev, sectigoov, zerossl) (default: "https://acme-v02.api.letsencrypt.org/directory") [$LEGO_SERVER]
Flags related to External Account Binding:
--eab Use External Account Binding for account registration. Requires eab.kid and eab.hmac. [$LEGO_EAB]
--eab.hmac string MAC key for External Account Binding. Should be in Base64 URL Encoding without padding format. [$LEGO_EAB_HMAC]
--eab.kid string Key identifier for External Account Binding. [$LEGO_EAB_KID]
Flags related to advanced options:
--always-deactivate-authorizations string Force the authorizations to be relinquished even if the certificate request was successful. [$LEGO_ALWAYS_DEACTIVATE_AUTHORIZATIONS]
--cert.timeout int Set the certificate timeout value to a specific value in seconds. Only used when obtaining certificates. (default: 30) [$LEGO_CERT_TIMEOUT]
--csr string Certificate signing request filename, if an external CSR is to be used. [$LEGO_CSR]
--enable-cn Enable the use of the common name. (Not recommended) [$LEGO_ENABLE_CN]
--ipv4only, -4 Use IPv4 only. [$LEGO_IPV4ONLY]
--ipv6only, -6 Use IPv6 only. [$LEGO_IPV6ONLY]
--must-staple Include the OCSP must staple TLS extension in the CSR and generated certificate. Only works if the CSR is generated by lego. [$LEGO_MUST_STAPLE]
--no-bundle Do not create a certificate bundle by adding the issuers certificate to the new certificate. [$LEGO_NO_BUNDLE]
--not-after time Set the notAfter field in the certificate (RFC3339 format) [$LEGO_NOT_AFTER]
--not-before time Set the notBefore field in the certificate (RFC3339 format) [$LEGO_NOT_BEFORE]
--preferred-chain string If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name. If no match, the default offered chain will be used. [$LEGO_PREFERRED_CHAIN]
--private-key string Path to a private key (in PEM encoding) for the certificate. By default, a private key is generated. [$LEGO_PRIVATE_KEY]
--profile string If the CA offers multiple certificate profiles (draft-ietf-acme-profiles), choose this one. [$LEGO_PROFILE]
Flags related to certificate renewal:
--ari-disable (ARI) Do not use the renewalInfo endpoint (RFC9773) to check if a certificate should be renewed. [$LEGO_ARI_DISABLE]
--ari-wait-to-renew-duration duration (ARI) The maximum duration you're willing to sleep for a renewal time returned by the renewalInfo endpoint. (default: 0s) [$LEGO_ARI_WAIT_TO_RENEW_DURATION]
--force-cert-domains Check and ensure that the cert's domain list matches those passed in the domains argument. [$LEGO_FORCE_CERT_DOMAINS]
--no-random-sleep Do not add a random sleep before the renewal. We do not recommend using this flag if you are doing your renewals in an automated way. [$LEGO_NO_RANDOM_SLEEP]
--renew-days int The number of days left on a certificate to renew it.
By default, compute dynamically, based on the lifetime of the certificate(s), when to renew: use 1/3rd of the lifetime left, or 1/2 of the lifetime for short-lived certificates). (default: 0) [$LEGO_RENEW_DAYS]
--renew-force Force the renewal of the certificate even if it is not due for renewal yet. [$LEGO_RENEW_FORCE]
--reuse-key Used to indicate you want to reuse the current certificate private key for the new certificate. [$LEGO_REUSE_KEY]
Flags related to hooks:
--deploy-hook string Define a hook. The hook runs, after the creation or the renewal, in cases where a certificate is successfully created/renewed. [$LEGO_DEPLOY_HOOK]
--deploy-hook-timeout duration Define the timeout for the deploy-hook execution. (default: 2m0s) [$LEGO_DEPLOY_HOOK_TIMEOUT]
--post-hook string Define a post-hook. This hook runs, after the creation or the renewal, in cases where a certificate is created/renewed, regardless of whether any errors occurred. [$LEGO_POST_HOOK]
--post-hook-timeout duration Define the timeout for the post-hook execution. (default: 2m0s) [$LEGO_POST_HOOK_TIMEOUT]
--pre-hook string Define a pre-hook. This hook runs, before the creation or the renewal, in cases where a certificate will be effectively created/renewed. [$LEGO_PRE_HOOK]
--pre-hook-timeout duration Define the timeout for the pre-hook execution. (default: 2m0s) [$LEGO_PRE_HOOK_TIMEOUT]
Flags related to the ACME client:
--http-timeout int Set the HTTP timeout value to a specific value in seconds. (default: 0) [$LEGO_HTTP_TIMEOUT]
--overall-request-limit int ACME overall requests limit. (default: 18) [$LEGO_OVERALL_REQUEST_LIMIT]
--tls-skip-verify Skip the TLS verification of the ACME server. [$LEGO_TLS_SKIP_VERIFY]
--user-agent string Add to the user-agent sent to the CA to identify an application embedding lego-cli [$LEGO_USER_AGENT]
Flags related to the DNS-01 challenge:
--dns string Solve a DNS-01 challenge using the specified provider. Can be mixed with other types of challenges. Run 'lego dnshelp' for help on usage. [$LEGO_DNS]
--dns.propagation.disable-ans By setting this flag to true, disables the need to await propagation of the TXT record to all authoritative name servers. [$LEGO_DNS_PROPAGATION_DISABLE_ANS]
--dns.propagation.disable-rns By setting this flag to true, disables the need to await propagation of the TXT record to all recursive name servers (aka resolvers). [$LEGO_DNS_PROPAGATION_DISABLE_RNS]
--dns.propagation.wait duration By setting this flag, disables all the propagation checks of the TXT record and uses a wait duration instead. (default: 0s) [$LEGO_DNS_PROPAGATION_WAIT]
--dns.resolvers string [ --dns.resolvers string ] Set the nameservers to use for performing (recursive) CNAME resolving and apex domain determination. For DNS-01 challenge verification, the authoritative DNS server is queried directly. Supported: host:port. The default is to use the system nameservers, or Cloudflare's nameservers if the system's cannot be determined. [$LEGO_DNS_RESOLVERS]
--dns.timeout int Set the DNS timeout value to a specific value in seconds. Used only when performing authoritative name server queries. (default: 10) [$LEGO_DNS_TIMEOUT]
Flags related to the DNS-PERSIST-01 challenge:
--dns-persist Use the DNS-PERSIST-01 challenge to solve challenges. Manual verification only. Can be mixed with other types of challenges. [$LEGO_DNS_PERSIST]
--dns-persist.issuer-domain-name string Override the issuer-domain-name to use for DNS-PERSIST-01 when multiple are offered. Must be offered by the challenge. [$LEGO_DNS_PERSIST_ISSUER_DOMAIN_NAME]
--dns-persist.persist-until time Set the optional persistUntil for DNS-PERSIST-01 records as an RFC3339 timestamp (for example, 2026-03-01T00:00:00Z). [$LEGO_DNS_PERSIST_PERSIST_UNTIL]
--dns-persist.propagation.disable-ans By setting this flag to true, disables the need to await propagation of the TXT record to all authoritative name servers. [$LEGO_DNS_PERSIST_PROPAGATION_DISABLE_ANS]
--dns-persist.propagation.disable-rns By setting this flag to true, disables the need to await propagation of the TXT record to all recursive name servers (aka resolvers). [$LEGO_DNS_PERSIST_PROPAGATION_DISABLE_RNS]
--dns-persist.propagation.wait duration By setting this flag, disables all the propagation checks of the TXT record and uses a wait duration instead. (default: 0s) [$LEGO_DNS_PERSIST_PROPAGATION_WAIT]
--dns-persist.resolvers string [ --dns-persist.resolvers string ] Set the resolvers to use for DNS-PERSIST-01 TXT lookups. Supported: host:port. The default is to use the system nameservers, or Cloudflare's nameservers if the system's cannot be determined. [$LEGO_DNS_PERSIST_RESOLVERS]
--dns-persist.timeout int Set the DNS timeout value to a specific value in seconds. Used for DNS-PERSIST-01 lookups. (default: 0) [$LEGO_DNS_PERSIST_TIMEOUT]
Flags related to the HTTP-01 challenge:
--http Use the HTTP-01 challenge to solve challenges. Can be mixed with other types of challenges. [$LEGO_HTTP]
--http.address string Set the address to use for HTTP-01 based challenges to listen on. Supported: interface:port or :port. (default: ":80") [$LEGO_HTTP_ADDRESS]
--http.delay duration Delay between the starts of the HTTP server (use for HTTP-01 based challenges) and the validation of the challenge. (default: 0s) [$LEGO_HTTP_DELAY]
--http.memcached-host string [ --http.memcached-host string ] Set the memcached host(s) to use for HTTP-01 based challenges. Challenges will be written to all specified hosts. [$LEGO_HTTP_MEMCACHED_HOST]
--http.proxy-header string Validate against this HTTP header when solving HTTP-01 based challenges behind a reverse proxy. (default: "Host") [$LEGO_HTTP_PROXY_HEADER]
--http.s3-bucket string Set the S3 bucket name to use for HTTP-01 based challenges. Challenges will be written to the S3 bucket. [$LEGO_HTTP_S3_BUCKET]
--http.webroot string Set the webroot folder to use for HTTP-01 based challenges to write directly to the .well-known/acme-challenge file. This disables the built-in server and expects the given directory to be publicly served with access to .well-known/acme-challenge [$LEGO_HTTP_WEBROOT]
Flags related to the TLS-ALPN-01 challenge:
--tls Use the TLS-ALPN-01 challenge to solve challenges. Can be mixed with other types of challenges. [$LEGO_TLS]
--tls.address string Set the address to use for TLS-ALPN-01 based challenges to listen on. Supported: interface:port or :port. (default: ":443") [$LEGO_TLS_ADDRESS]
--tls.delay duration Delay between the start of the TLS listener (use for TLSALPN-01 based challenges) and the validation of the challenge. (default: 0s) [$LEGO_TLS_DELAY]
Flags related to the storage:
--account-id string Account identifier (The email is used if the account ID is undefined). [$LEGO_ACCOUNT_ID]
--cert.name string, -c string The certificate ID/Name, used to store and retrieve a certificate. By default, it uses the first domain name. [$LEGO_CERT_NAME]
--env-file string The path to the dotenv file. [$LEGO_ENV_FILE]
--path string Directory to use for storing the data. [$LEGO_PATH]
--pem Generate an additional .pem (base64) file by concatenating the .key and .crt files together. [$LEGO_PEM]
--pfx Generate an additional .pfx (PKCS#12) file by concatenating the .key and .crt and issuer .crt files together. [$LEGO_PFX]
--pfx.format string The encoding format to use when encrypting the .pfx (PCKS#12) file. Supported: DES, RC2, SHA256, PBMAC1. (default: "RC2") [$LEGO_PFX_FORMAT]
--pfx.password string The password used to encrypt the .pfx (PCKS#12) file. (default: "changeit") [$LEGO_PFX_PASSWORD]
GLOBAL OPTIONS:
--log.level string Set the logging level. Supported values: 'debug', 'info', 'warn', 'error'. (default: "info") [$LEGO_LOG_LEVEL]
--log.format string Set the logging format. Supported values: 'colored', 'text', 'json'. (default: "colored") [$LEGO_LOG_FORMAT]
certificates revoke command
NAME:
lego certificates revoke - Revoke a certificate
USAGE:
lego certificates revoke [options]
OPTIONS:
--cert.name string, -c string [ --cert.name string, -c string ] The certificate IDs/Names, used to retrieve the certificates. [$LEGO_CERT_NAME]
--email string, -m string Email used for registration and recovery contact. [$LEGO_EMAIL]
--help, -h show help
--keep Keep the certificates after the revocation instead of archiving them. [$LEGO_KEEP]
--key-type string, -k string Key type to use for private keys. Supported: EC256, EC384, RSA2048, RSA3072, RSA4096, RSA8192. (default: "EC256") [$LEGO_KEY_TYPE]
--reason uint Identifies the reason for the certificate revocation. See https://www.rfc-editor.org/rfc/rfc5280.html#section-5.3.1.
Valid values are: 0 (unspecified), 1 (keyCompromise), 2 (cACompromise), 3 (affiliationChanged), 4 (superseded), 5 (cessationOfOperation), 6 (certificateHold), 8 (removeFromCRL), 9 (privilegeWithdrawn), or 10 (aACompromise). (default: 0) [$LEGO_REASON]
--server string, -s string CA (ACME server). It can be either a URL or a shortcode.
(available shortcodes: actalis, digicert, freessl, globalsign, googletrust, googletrust-staging, letsencrypt, letsencrypt-staging, litessl, peeringhub, sslcomecc, sslcomrsa, sectigo, sectigoev, sectigoov, zerossl) (default: "https://acme-v02.api.letsencrypt.org/directory") [$LEGO_SERVER]
Flags related to External Account Binding:
--eab Use External Account Binding for account registration. Requires eab.kid and eab.hmac. [$LEGO_EAB]
--eab.hmac string MAC key for External Account Binding. Should be in Base64 URL Encoding without padding format. [$LEGO_EAB_HMAC]
--eab.kid string Key identifier for External Account Binding. [$LEGO_EAB_KID]
Flags related to advanced options:
--cert.timeout int Set the certificate timeout value to a specific value in seconds. Only used when obtaining certificates. (default: 30) [$LEGO_CERT_TIMEOUT]
--enable-cn Enable the use of the common name. (Not recommended) [$LEGO_ENABLE_CN]
Flags related to the ACME client:
--http-timeout int Set the HTTP timeout value to a specific value in seconds. (default: 0) [$LEGO_HTTP_TIMEOUT]
--overall-request-limit int ACME overall requests limit. (default: 18) [$LEGO_OVERALL_REQUEST_LIMIT]
--tls-skip-verify Skip the TLS verification of the ACME server. [$LEGO_TLS_SKIP_VERIFY]
--user-agent string Add to the user-agent sent to the CA to identify an application embedding lego-cli [$LEGO_USER_AGENT]
Flags related to the configuration file:
--config string Path to the configuration file. [$LEGO_CONFIG]
Flags related to the storage:
--account-id string Account identifier (The email is used if the account ID is undefined). [$LEGO_ACCOUNT_ID]
--path string Directory to use for storing the data. [$LEGO_PATH]
GLOBAL OPTIONS:
--log.level string Set the logging level. Supported values: 'debug', 'info', 'warn', 'error'. (default: "info") [$LEGO_LOG_LEVEL]
--log.format string Set the logging format. Supported values: 'colored', 'text', 'json'. (default: "colored") [$LEGO_LOG_FORMAT]
certificates list command
NAME:
lego certificates list - Display information about certificates.
USAGE:
lego certificates list [options]
OPTIONS:
--help, -h show help
--json Format the output as JSON.
Flags related to the storage:
--path string Directory to use for storing the data. [$LEGO_PATH]
GLOBAL OPTIONS:
--log.level string Set the logging level. Supported values: 'debug', 'info', 'warn', 'error'. (default: "info") [$LEGO_LOG_LEVEL]
--log.format string Set the logging format. Supported values: 'colored', 'text', 'json'. (default: "colored") [$LEGO_LOG_FORMAT]
accounts register command
NAME:
lego accounts register - Register an account.
USAGE:
lego accounts register [options]
OPTIONS:
--accept-tos, -a By setting this flag to true, you indicate that you accept the current CA terms of service. [$LEGO_ACCEPT_TOS]
--email string, -m string Email used for registration and recovery contact. [$LEGO_EMAIL]
--help, -h show help
--key-type string, -k string Key type to use for private keys. Supported: EC256, EC384, RSA2048, RSA3072, RSA4096, RSA8192. (default: "EC256") [$LEGO_KEY_TYPE]
--server string, -s string CA (ACME server). It can be either a URL or a shortcode.
(available shortcodes: actalis, digicert, freessl, globalsign, googletrust, googletrust-staging, letsencrypt, letsencrypt-staging, litessl, peeringhub, sslcomecc, sslcomrsa, sectigo, sectigoev, sectigoov, zerossl) (default: "https://acme-v02.api.letsencrypt.org/directory") [$LEGO_SERVER]
Flags related to External Account Binding:
--eab Use External Account Binding for account registration. Requires eab.kid and eab.hmac. [$LEGO_EAB]
--eab.hmac string MAC key for External Account Binding. Should be in Base64 URL Encoding without padding format. [$LEGO_EAB_HMAC]
--eab.kid string Key identifier for External Account Binding. [$LEGO_EAB_KID]
Flags related to advanced options:
--cert.timeout int Set the certificate timeout value to a specific value in seconds. Only used when obtaining certificates. (default: 30) [$LEGO_CERT_TIMEOUT]
--enable-cn Enable the use of the common name. (Not recommended) [$LEGO_ENABLE_CN]
Flags related to the ACME client:
--http-timeout int Set the HTTP timeout value to a specific value in seconds. (default: 0) [$LEGO_HTTP_TIMEOUT]
--overall-request-limit int ACME overall requests limit. (default: 18) [$LEGO_OVERALL_REQUEST_LIMIT]
--tls-skip-verify Skip the TLS verification of the ACME server. [$LEGO_TLS_SKIP_VERIFY]
--user-agent string Add to the user-agent sent to the CA to identify an application embedding lego-cli [$LEGO_USER_AGENT]
Flags related to the storage:
--account-id string Account identifier (The email is used if the account ID is undefined). [$LEGO_ACCOUNT_ID]
--path string Directory to use for storing the data. [$LEGO_PATH]
GLOBAL OPTIONS:
--log.level string Set the logging level. Supported values: 'debug', 'info', 'warn', 'error'. (default: "info") [$LEGO_LOG_LEVEL]
--log.format string Set the logging format. Supported values: 'colored', 'text', 'json'. (default: "colored") [$LEGO_LOG_FORMAT]
accounts recover command
NAME:
lego accounts recover - Recover/import an account from the private key.
USAGE:
lego accounts recover [options]
OPTIONS:
--email string, -m string Email used for registration and recovery contact. [$LEGO_EMAIL]
--help, -h show help
--key-type string, -k string Key type to use for private keys. Supported: EC256, EC384, RSA2048, RSA3072, RSA4096, RSA8192. (default: "EC256") [$LEGO_KEY_TYPE]
--private-key string Path to the account private key (PEM encoded). [$LEGO_PRIVATE_KEY]
--server string, -s string CA (ACME server). It can be either a URL or a shortcode.
(available shortcodes: actalis, digicert, freessl, globalsign, googletrust, googletrust-staging, letsencrypt, letsencrypt-staging, litessl, peeringhub, sslcomecc, sslcomrsa, sectigo, sectigoev, sectigoov, zerossl) (default: "https://acme-v02.api.letsencrypt.org/directory") [$LEGO_SERVER]
Flags related to External Account Binding:
--eab Use External Account Binding for account registration. Requires eab.kid and eab.hmac. [$LEGO_EAB]
--eab.hmac string MAC key for External Account Binding. Should be in Base64 URL Encoding without padding format. [$LEGO_EAB_HMAC]
--eab.kid string Key identifier for External Account Binding. [$LEGO_EAB_KID]
Flags related to advanced options:
--cert.timeout int Set the certificate timeout value to a specific value in seconds. Only used when obtaining certificates. (default: 30) [$LEGO_CERT_TIMEOUT]
--enable-cn Enable the use of the common name. (Not recommended) [$LEGO_ENABLE_CN]
Flags related to the ACME client:
--http-timeout int Set the HTTP timeout value to a specific value in seconds. (default: 0) [$LEGO_HTTP_TIMEOUT]
--overall-request-limit int ACME overall requests limit. (default: 18) [$LEGO_OVERALL_REQUEST_LIMIT]
--tls-skip-verify Skip the TLS verification of the ACME server. [$LEGO_TLS_SKIP_VERIFY]
--user-agent string Add to the user-agent sent to the CA to identify an application embedding lego-cli [$LEGO_USER_AGENT]
Flags related to the storage:
--account-id string Account identifier (The email is used if the account ID is undefined). [$LEGO_ACCOUNT_ID]
--path string Directory to use for storing the data. [$LEGO_PATH]
GLOBAL OPTIONS:
--log.level string Set the logging level. Supported values: 'debug', 'info', 'warn', 'error'. (default: "info") [$LEGO_LOG_LEVEL]
--log.format string Set the logging format. Supported values: 'colored', 'text', 'json'. (default: "colored") [$LEGO_LOG_FORMAT]
accounts keyrollover command
NAME:
lego accounts keyrollover - Update the account private key.
USAGE:
lego accounts keyrollover [options]
OPTIONS:
--email string, -m string Email used for registration and recovery contact. [$LEGO_EMAIL]
--help, -h show help
--key-type string, -k string Key type to use for private keys. Supported: EC256, EC384, RSA2048, RSA3072, RSA4096, RSA8192. (default: "EC256") [$LEGO_KEY_TYPE]
--key-type string, -k string Key type to use for the new private key of the account. Supported: EC256, EC384, RSA2048, RSA3072, RSA4096, RSA8192. (default: "EC256") [$LEGO_KEY_TYPE]
--private-key string Path to the new account private key (PEM encoded). If not specified, the private key will be generated. [$LEGO_PRIVATE_KEY]
--server string, -s string CA (ACME server). It can be either a URL or a shortcode.
(available shortcodes: actalis, digicert, freessl, globalsign, googletrust, googletrust-staging, letsencrypt, letsencrypt-staging, litessl, peeringhub, sslcomecc, sslcomrsa, sectigo, sectigoev, sectigoov, zerossl) (default: "https://acme-v02.api.letsencrypt.org/directory") [$LEGO_SERVER]
Flags related to External Account Binding:
--eab Use External Account Binding for account registration. Requires eab.kid and eab.hmac. [$LEGO_EAB]
--eab.hmac string MAC key for External Account Binding. Should be in Base64 URL Encoding without padding format. [$LEGO_EAB_HMAC]
--eab.kid string Key identifier for External Account Binding. [$LEGO_EAB_KID]
Flags related to advanced options:
--cert.timeout int Set the certificate timeout value to a specific value in seconds. Only used when obtaining certificates. (default: 30) [$LEGO_CERT_TIMEOUT]
--enable-cn Enable the use of the common name. (Not recommended) [$LEGO_ENABLE_CN]
Flags related to the ACME client:
--http-timeout int Set the HTTP timeout value to a specific value in seconds. (default: 0) [$LEGO_HTTP_TIMEOUT]
--overall-request-limit int ACME overall requests limit. (default: 18) [$LEGO_OVERALL_REQUEST_LIMIT]
--tls-skip-verify Skip the TLS verification of the ACME server. [$LEGO_TLS_SKIP_VERIFY]
--user-agent string Add to the user-agent sent to the CA to identify an application embedding lego-cli [$LEGO_USER_AGENT]
Flags related to the storage:
--account-id string Account identifier (The email is used if the account ID is undefined). [$LEGO_ACCOUNT_ID]
--path string Directory to use for storing the data. [$LEGO_PATH]
GLOBAL OPTIONS:
--log.level string Set the logging level. Supported values: 'debug', 'info', 'warn', 'error'. (default: "info") [$LEGO_LOG_LEVEL]
--log.format string Set the logging format. Supported values: 'colored', 'text', 'json'. (default: "colored") [$LEGO_LOG_FORMAT]
accounts list command
NAME:
lego accounts list - Display information about accounts.
USAGE:
lego accounts list [options]
OPTIONS:
--help, -h show help
--json Format the output as JSON.
Flags related to the storage:
--path string Directory to use for storing the data. [$LEGO_PATH]
GLOBAL OPTIONS:
--log.level string Set the logging level. Supported values: 'debug', 'info', 'warn', 'error'. (default: "info") [$LEGO_LOG_LEVEL]
--log.format string Set the logging format. Supported values: 'colored', 'text', 'json'. (default: "colored") [$LEGO_LOG_FORMAT]
archives restore command
NAME:
lego archives restore - Restore an archive.
USAGE:
lego archives restore [options]
OPTIONS:
--help, -h show help
Flags related to the storage:
--path string Directory to use for storing the data. [$LEGO_PATH]
GLOBAL OPTIONS:
--log.level string Set the logging level. Supported values: 'debug', 'info', 'warn', 'error'. (default: "info") [$LEGO_LOG_LEVEL]
--log.format string Set the logging format. Supported values: 'colored', 'text', 'json'. (default: "colored") [$LEGO_LOG_FORMAT]
archives list command
NAME:
lego archives list - List all archives.
USAGE:
lego archives list [options]
OPTIONS:
--help, -h show help
Flags related to the storage:
--path string Directory to use for storing the data. [$LEGO_PATH]
GLOBAL OPTIONS:
--log.level string Set the logging level. Supported values: 'debug', 'info', 'warn', 'error'. (default: "info") [$LEGO_LOG_LEVEL]
--log.format string Set the logging format. Supported values: 'colored', 'text', 'json'. (default: "colored") [$LEGO_LOG_FORMAT]
migrate command
NAME:
lego migrate - Migrate certificates and accounts.
USAGE:
lego migrate [options]
OPTIONS:
--account-only Only migrate accounts. [$LEGO_ACCOUNT_ONLY]
--help, -h show help
Flags related to the storage:
--path string Directory to use for storing the data. [$LEGO_PATH]
GLOBAL OPTIONS:
--log.level string Set the logging level. Supported values: 'debug', 'info', 'warn', 'error'. (default: "info") [$LEGO_LOG_LEVEL]
--log.format string Set the logging format. Supported values: 'colored', 'text', 'json'. (default: "colored") [$LEGO_LOG_FORMAT]
A valid, but bare-bones example use of the acme package:
packagemainimport (
"context""crypto""crypto/ecdsa""crypto/elliptic""crypto/rand""fmt""log""github.com/go-acme/lego/v5/acme""github.com/go-acme/lego/v5/certcrypto""github.com/go-acme/lego/v5/certificate""github.com/go-acme/lego/v5/challenge/http01""github.com/go-acme/lego/v5/challenge/tlsalpn01""github.com/go-acme/lego/v5/lego""github.com/go-acme/lego/v5/registration")
// You'll need a user or account type that implements acme.UsertypeAccountstruct {
EmailstringRegistration*acme.ExtendedAccountkeycrypto.Signer}
func (u*Account) GetEmail() string {
returnu.Email}
func (u*Account) GetRegistration() *acme.ExtendedAccount {
returnu.Registration}
func (u*Account) GetPrivateKey() crypto.Signer {
returnu.key}
funcmain() {
// Create a user. New accounts need an email and private key to start.privateKey, err:=ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
iferr!=nil {
log.Fatal(err)
}
account:=&Account{
key: privateKey,
}
config:=lego.NewConfig(account)
// This CA URL is configured for a local dev instance of Boulder running in Docker in a VM.config.CADirURL = "http://192.168.99.100:4000/directory"// A client facilitates communication with the CA server.client, err:=lego.NewClient(config)
iferr!=nil {
log.Fatal(err)
}
// We specify an HTTP port of 5002 and an TLS port of 5001 on all interfaces// because we aren't running as root and can't bind a listener to port 80 and 443// (used later when we attempt to pass challenges). Keep in mind that you still// need to proxy challenge traffic to port 5002 and 5001.err = client.Challenge.SetHTTP01Provider(http01.NewProviderServer("", "5002"))
iferr!=nil {
log.Fatal(err)
}
err = client.Challenge.SetTLSALPN01Provider(tlsalpn01.NewProviderServer("", "5001"))
iferr!=nil {
log.Fatal(err)
}
ctx:=context.Background()
// New users will need to registerreg, err:=client.Registration.Register(ctx, registration.RegisterOptions{TermsOfServiceAgreed: true})
iferr!=nil {
log.Fatal(err)
}
account.Registration = regrequest:=certificate.ObtainRequest{
Domains: []string{"mydomain.com"},
KeyType: certcrypto.RSA2048,
Bundle: true,
}
certificates, err:=client.Certificate.Obtain(ctx, request)
iferr!=nil {
log.Fatal(err)
}
// Each certificate comes back with the cert bytes, the bytes of the client's// private key, and a certificate URL. SAVE THESE TO DISK.fmt.Printf("%#v\n", certificates)
// ... all done.}
Subsections of Library
Writing a Challenge Solver
Lego can solve multiple ACME challenge types out of the box, but sometimes you have custom requirements.
For example, you may want to write a solver for the DNS-01 challenge that works with a different DNS provider (lego already supports CloudFlare, AWS, DigitalOcean, and others).
The DNS-01 challenge is advantageous when other challenge types are impossible.
For example, the HTTP-01 challenge doesn’t work well behind a load balancer or CDN and the TLS-ALPN-01 challenge breaks behind TLS termination.
But even if using HTTP-01 or TLS-ALPN-01 challenges, you may have specific needs that lego does not consider by default.
You can write something called a challenge.Provider that implements this interface:
This provides the means to solve a challenge.
First you present a token to the ACME server in a way defined by the challenge type you’re solving for, then you “clean up” after the challenge finishes.
Writing a challenge.Provider
Pretend we want to write our own DNS-01 challenge provider (other challenge types have different requirements but the same principles apply).
This will let us prove ownership of domain names parked at a new, imaginary DNS service called BestDNS without having to start our own HTTP server.
BestDNS has an API that, given an authentication token, allows us to manipulate DNS records.
This simplistic example has only one field to store the auth token, but in reality you may need to keep more state.
Now we need to implement the interface.
We’ll start with the Present method.
You’ll be passed the domain name for which you’re proving ownership, a token, and a keyAuth string.
How your provider uses token and keyAuth, or if you even use them at all, depends on the challenge type.
For DNS-01, we’ll just use domain and keyAuth.
func (d*DNSProviderBestDNS) Present(ctxcontext.Context, domain, token, keyAuthstring) error {
info:=dns01.GetChallengeInfo(ctx, domain, keyAuth)
// make API request to set a TXT record on fqdn with value and TTLreturnnil}
After calling dns01.GetChallengeInfo(domain, keyAuth), we now have the information we need to make our API request and set the TXT record:
FQDN is the fully qualified domain name on which to set the TXT record.
EffectiveFQDN is the fully qualified domain name after the CNAMEs resolutions on which to set the TXT record.
Value is the record’s value to set on the record.
So then you make an API request to the DNS service according to their docs.
Once the TXT record is set on the domain, you may return and the challenge will proceed.
The ACME server will then verify that you did what it required you to do, and once it is finished, lego will call your CleanUp method.
In our case, we want to remove the TXT record we just created.
func (d*DNSProviderBestDNS) CleanUp(ctxcontext.Context, domain, token, keyAuthstring) error {
// clean up any state you created in Present, like removing the TXT record}
In our case, we’d just make another API request to have the DNS record deleted; no need to keep it and clutter the zone file.
Using your new challenge.Provider
To use your new challenge provider, call client.Challenge.SetDNS01Provider to tell lego, “For this challenge, use this provider”.
In our case: