docs: refactoring and cleanup (#1658)

This commit is contained in:
Dominik Menke 2022-06-17 00:25:42 +02:00 committed by GitHub
parent 257dfa777e
commit 85f616f85b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
220 changed files with 1597 additions and 863 deletions

View file

@ -0,0 +1,17 @@
---
title: General Instructions
date: 2019-03-03T16:39:46+01:00
draft: false
summary: Read this first to clarify some assumptions made by the following guides.
weight: 1
---
These examples assume you have [lego installed]({{< ref "installation" >}}).
You can get a pre-built binary from the [releases](https://github.com/go-acme/lego/releases) page.
The web server examples require that the `lego` binary has permission to bind to ports 80 and 443.
If your environment does not allow you to bind to these ports, please read [Running without root privileges]({{< ref "usage/cli/Options#running-without-root-privileges" >}}) and [Port Usage]({{< ref "usage/cli/Options#port-usage" >}}).
Unless otherwise instructed with the `--path` command line flag, lego will look for a directory named `.lego` in the *current working directory*.
If you run `cd /dir/a && lego ... run`, lego will create a directory `/dir/a/.lego` where it will save account registration and certificate files into.
If you later try to renew a certificate with `cd /dir/b && lego ... renew`, lego will likely produce an error.

View file

@ -0,0 +1,129 @@
---
title: Obtain a Certificate
date: 2019-03-03T16:39:46+01:00
draft: false
weight: 2
---
This guide explains various ways to obtain a new certificate.
<!--more-->
## Using the built-in web server
Open a terminal, and execute the following command (insert your own email address and domain):
```bash
lego --email="you@example.com" --domains="example.com" --http run
```
You will find your certificate in the `.lego` folder of the current working directory:
```console
$ 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 DNS provider
If you can't or don't want to start a web server, you need to use a DNS provider.
lego comes with [support for many]({{< ref "dns#dns-providers" >}}) 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.
For this example, let's assume you have setup CloudFlare for your domain.
Execute this command:
```bash
CLOUDFLARE_EMAIL="you@example.com" \
CLOUDFLARE_API_KEY="yourprivatecloudflareapikey" \
lego --email "you@example.com" --dns cloudflare --domains "example.org" run
```
## 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:
```bash
lego --email="you@example.com" --http --csr="/path/to/csr.pem" run
```
lego will infer the domains to be validated based on the contents of the CSR, so make sure the CSR's Common Name and optional SubjectAltNames are set correctly.
## Using an existing, running web server
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:
```bash
lego --accept-tos --email you@example.com --http --http.webroot /path/to/webroot --domains example.com run
```
## Running a script afterward
You can easily hook into the certificate-obtaining process by providing the path to a script:
```bash
lego --email="you@example.com" --domains="example.com" --http run --run-hook="./myscript.sh"
```
Some information is provided through environment variables:
- `LEGO_ACCOUNT_EMAIL`: the email of the account.
- `LEGO_CERT_DOMAIN`: the main domain of the certificate.
- `LEGO_CERT_PATH`: the path of the certificate.
- `LEGO_CERT_KEY_PATH`: the path of the certificate key.
### Use case
A typical use case is distribute the certificate for other services and reload them if necessary.
Since PEM-formatted TLS certificates are understood by many programs, 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.
```bash
#!/bin/bash
# copy certificates to a directory controlled by Postfix
postfix_cert_dir="/etc/postfix/certificates"
# our Postfix server only handles mail for @example.com domain
if [ "$LEGO_CERT_DOMAIN" = "example.com" ]; then
install -u postfix -g postfix -m 0644 "$LEGO_CERT_PATH" "$postfix_cert_dir"
install -u postfix -g postfix -m 0640 "$LEGO_KEY_PATH" "$postfix_cert_dir"
systemctl reload postfix@-service
fi
```

View file

@ -0,0 +1,133 @@
---
title: "Options"
date: 2019-03-03T16:39:46+01:00
draft: false
summary: This page describes various command line options.
weight: 4
---
## Usage
{{< tabs >}}
{{% tab name="lego --help" %}}
```slim
NAME:
lego - Let's Encrypt client written in Go
USAGE:
lego [global options] command [command options] [arguments...]
COMMANDS:
run Register an account, then create and install a certificate
revoke Revoke a certificate
renew Renew a certificate
dnshelp Shows additional help for the '--dns' global option
list Display certificates and accounts information.
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--domains value, -d value Add a domain to the process. Can be specified multiple times.
--server value, -s value CA hostname (and optionally :port). The server certificate must be trusted in order to avoid further modifications to the client. (default: "https://acme-v02.api.letsencrypt.org/directory")
--accept-tos, -a By setting this flag to true you indicate that you accept the current Let's Encrypt terms of service. (default: false)
--email value, -m value Email used for registration and recovery contact.
--csr value, -c value Certificate signing request filename, if an external CSR is to be used.
--eab Use External Account Binding for account registration. Requires --kid and --hmac. (default: false)
--kid value Key identifier from External CA. Used for External Account Binding.
--hmac value MAC key from External CA. Should be in Base64 URL Encoding without padding format. Used for External Account Binding.
--key-type value, -k value Key type to use for private keys. Supported: rsa2048, rsa4096, rsa8192, ec256, ec384. (default: "ec256")
--filename value (deprecated) Filename of the generated certificate.
--path value Directory to use for storing the data. (default: "./.lego") [$LEGO_PATH]
--http Use the HTTP challenge to solve challenges. Can be mixed with other types of challenges. (default: false)
--http.port value Set the port and interface to use for HTTP based challenges to listen on.Supported: interface:port or :port. (default: ":80")
--http.proxy-header value Validate against this HTTP header when solving HTTP based challenges behind a reverse proxy. (default: "Host")
--http.webroot value Set the webroot folder to use for HTTP based challenges to write directly in a file in .well-known/acme-challenge. This disables the built-in server and expects the given directory to be publicly served with access to .well-known/acme-challenge
--http.memcached-host value Set the memcached host(s) to use for HTTP based challenges. Challenges will be written to all specified hosts.
--tls Use the TLS challenge to solve challenges. Can be mixed with other types of challenges. (default: false)
--tls.port value Set the port and interface to use for TLS based challenges to listen on. Supported: interface:port or :port. (default: ":443")
--dns value Solve a DNS challenge using the specified provider. Can be mixed with other types of challenges. Run 'lego dnshelp' for help on usage.
--dns.disable-cp By setting this flag to true, disables the need to wait the propagation of the TXT record to all authoritative name servers. (default: false)
--dns.resolvers value Set the resolvers to use for performing recursive DNS queries. Supported: host:port. The default is to use the system resolvers, or Google's DNS resolvers if the system's cannot be determined.
--http-timeout value Set the HTTP timeout value to a specific value in seconds. (default: 0)
--dns-timeout value Set the DNS timeout value to a specific value in seconds. Used only when performing authoritative name servers queries. (default: 10)
--pem Generate a .pem file by concatenating the .key and .crt files together. (default: false)
--pfx Generate a .pfx (PKCS#12) file by with the .key and .crt and issuer .crt files together. (default: false)
--pfx.pass value The password used to encrypt the .pfx (PCKS#12) file. (default: "changeit")
--cert.timeout value Set the certificate timeout value to a specific value in seconds. Only used when obtaining certificates. (default: 30)
--help, -h show help (default: false)
--version, -v print the version (default: false)
```
{{% /tab %}}
{{% tab name="lego run --help" %}}
```slim
NAME:
lego run - Register an account, then create and install a certificate
USAGE:
lego run [command options] [arguments...]
OPTIONS:
--no-bundle Do not create a certificate bundle by adding the issuers certificate to the new certificate. (default: false)
--must-staple Include the OCSP must staple TLS extension in the CSR and generated certificate. Only works if the CSR is generated by lego. (default: false)
--run-hook value Define a hook. The hook is executed when the certificates are effectively created.
--preferred-chain value 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.
--always-deactivate-authorizations value Force the authorizations to be relinquished even if the certificate request was successful.
```
{{% /tab %}}
{{% tab name="lego renew --help" %}}
```slim
NAME:
lego renew - Renew a certificate
USAGE:
lego renew [command options] [arguments...]
OPTIONS:
--days value The number of days left on a certificate to renew it. (default: 30)
--reuse-key Used to indicate you want to reuse your current private key for the new certificate. (default: false)
--no-bundle Do not create a certificate bundle by adding the issuers certificate to the new certificate. (default: false)
--must-staple Include the OCSP must staple TLS extension in the CSR and generated certificate. Only works if the CSR is generated by lego. (default: false)
--renew-hook value Define a hook. The hook is executed only when the certificates are effectively renewed.
--preferred-chain value 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.
--always-deactivate-authorizations value Force the authorizations to be relinquished even if the certificate request was successful.
--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. (default: false)
```
{{% /tab %}}
{{< /tabs >}}
When using the standard `--path` option, all certificates and account configurations are saved to a folder `.lego` in the current working directory.
## 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:
```bash
lego --server=https://acme-staging-v02.api.letsencrypt.org/directory …
```
## 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.port` or/and the `--tls.port` 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](#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.port` and `--tls.port` options to instruct
lego to listen on that interface:port for any incoming challenges.
If you are using this option, make sure you proxy all of the following traffic to these ports.
**HTTP Port:** All plaintext HTTP requests to port **80** which begin with a request path of `/.well-known/acme-challenge/` for the HTTP challenge.[^header]
**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.
[^header]: 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`.

View file

@ -0,0 +1,110 @@
---
title: Renew a Certificate
date: 2019-03-03T16:39:46+01:00
draft: false
weight: 3
---
This guide describes how to renew existing certificates.
<!--more-->
Certificates issues by Let's Encrypt are valid for a period of 90 days.
To avoid certificate errors, you need to ensure that you renew your certificate *before* it expires.
In order to renew a certificate, follow the general instructions laid out under [Obtain a Certificate]({{< ref "usage/cli/Obtain-a-Certificate" >}}), and replace `lego ... run` with `lego ... renew`.
Note that the `renew` sub-command supports a slightly different set of some command line flags.
## Using the built-in web server
By default, and following best practices, a certificate is only renewed if its expiry date is less than 30 days in the future.
```bash
lego --email="you@example.com" --domains="example.com" --http renew
```
If the certificate needs to renewed earlier, you can specify the number of remaining days:
```bash
lego --email="you@example.com" --domains="example.com" --http renew --days 45
```
## Using a DNS provider
If you can't or don't want to start a web server, you need to use a DNS provider.
lego comes with [support for many]({{< ref "dns#dns-providers" >}}) 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.
For this example, let's assume you have setup CloudFlare for your domain.
Execute this command:
```bash
CLOUDFLARE_EMAIL="you@example.com" \
CLOUDFLARE_API_KEY="yourprivatecloudflareapikey" \
lego --email "you@example.com" --dns cloudflare --domains "example.org" renew
```
## Running a script afterward
You can easily hook into the certificate-obtaining process by providing the path to a script.
The hook is executed only when the certificates are effectively renewed.
```bash
lego --email="you@example.com" --domains="example.com" --http renew --renew-hook="./myscript.sh"
```
Some information is provided through environment variables:
- `LEGO_ACCOUNT_EMAIL`: the email of the account.
- `LEGO_CERT_DOMAIN`: the main domain of the certificate.
- `LEGO_CERT_PATH`: the path of the certificate.
- `LEGO_CERT_KEY_PATH`: the path of the certificate key.
See [Obtain a Certificate → Use case]({{< ref "usage/cli/Obtain-a-Certificate#use-case" >}}) for an example script.
## 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 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.[^loadspikes]
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:
```ruby
# avoid:
#@daily /usr/bin/lego ... renew
#@midnight /usr/bin/lego ... renew
#0 0 * * * /usr/bin/lego ... renew
# instead, use a randomly chosen time:
3 35 * * * /usr/bin/lego ... renew
```
If you use systemd timers, consider doing something similar, and/or introduce a `RandomizedDelaySec`:
```ini
[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
```
[^loadspikes]: See [Github issue #1656](https://github.com/go-acme/lego/issues/1656) for an excellent problem description.

View file

@ -8,89 +8,4 @@ Lego can be use as a CLI.
<!--more-->
## Usage
```slim
NAME:
lego - Let's Encrypt client written in Go
USAGE:
lego [global options] command [command options] [arguments...]
COMMANDS:
run Register an account, then create and install a certificate
revoke Revoke a certificate
renew Renew a certificate
dnshelp Shows additional help for the '--dns' global option
list Display certificates and accounts information.
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--domains value, -d value Add a domain to the process. Can be specified multiple times.
--server value, -s value CA hostname (and optionally :port). The server certificate must be trusted in order to avoid further modifications to the client. (default: "https://acme-v02.api.letsencrypt.org/directory")
--accept-tos, -a By setting this flag to true you indicate that you accept the current Let's Encrypt terms of service. (default: false)
--email value, -m value Email used for registration and recovery contact.
--csr value, -c value Certificate signing request filename, if an external CSR is to be used.
--eab Use External Account Binding for account registration. Requires --kid and --hmac. (default: false)
--kid value Key identifier from External CA. Used for External Account Binding.
--hmac value MAC key from External CA. Should be in Base64 URL Encoding without padding format. Used for External Account Binding.
--key-type value, -k value Key type to use for private keys. Supported: rsa2048, rsa4096, rsa8192, ec256, ec384. (default: "ec256")
--filename value (deprecated) Filename of the generated certificate.
--path value Directory to use for storing the data. (default: "./.lego") [$LEGO_PATH]
--http Use the HTTP challenge to solve challenges. Can be mixed with other types of challenges. (default: false)
--http.port value Set the port and interface to use for HTTP based challenges to listen on.Supported: interface:port or :port. (default: ":80")
--http.proxy-header value Validate against this HTTP header when solving HTTP based challenges behind a reverse proxy. (default: "Host")
--http.webroot value Set the webroot folder to use for HTTP based challenges to write directly in a file in .well-known/acme-challenge. This disables the built-in server and expects the given directory to be publicly served with access to .well-known/acme-challenge
--http.memcached-host value Set the memcached host(s) to use for HTTP based challenges. Challenges will be written to all specified hosts.
--tls Use the TLS challenge to solve challenges. Can be mixed with other types of challenges. (default: false)
--tls.port value Set the port and interface to use for TLS based challenges to listen on. Supported: interface:port or :port. (default: ":443")
--dns value Solve a DNS challenge using the specified provider. Can be mixed with other types of challenges. Run 'lego dnshelp' for help on usage.
--dns.disable-cp By setting this flag to true, disables the need to wait the propagation of the TXT record to all authoritative name servers. (default: false)
--dns.resolvers value Set the resolvers to use for performing recursive DNS queries. Supported: host:port. The default is to use the system resolvers, or Google's DNS resolvers if the system's cannot be determined.
--http-timeout value Set the HTTP timeout value to a specific value in seconds. (default: 0)
--dns-timeout value Set the DNS timeout value to a specific value in seconds. Used only when performing authoritative name servers queries. (default: 10)
--pem Generate a .pem file by concatenating the .key and .crt files together. (default: false)
--pfx Generate a .pfx (PKCS#12) file by with the .key and .crt and issuer .crt files together. (default: false)
--pfx.pass value The password used to encrypt the .pfx (PCKS#12) file. (default: "changeit")
--cert.timeout value Set the certificate timeout value to a specific value in seconds. Only used when obtaining certificates. (default: 30)
--help, -h show help (default: false)
--version, -v print the version (default: false)
```
When using the standard `--path` option, all certificates and account configurations are saved to a folder `.lego` in the current working directory.
## 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:
```bash
lego --server=https://acme-staging-v02.api.letsencrypt.org/directory …
```
## 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.port` or/and the `--tls.port` 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](#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.port` and `--tls.port` options to instruct
lego to listen on that interface:port for any incoming challenges.
If you are using this option, make sure you proxy all of the following traffic to these ports.
**HTTP Port:** All plaintext HTTP requests to port **80** which begin with a request path of `/.well-known/acme-challenge/` for the HTTP challenge.[^header]
**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.
[^header]: 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`.
{{% children style="h2" description="true" %}}

View file

@ -1,119 +1,30 @@
---
title: "Examples"
date: 2019-11-15T23:25:46+01:00
title: Examples
date: 2019-03-03T16:39:46+01:00
draft: false
hidden: true
---
## CLI Examples
{{% notice note %}}
**Heads up!** We've restructured the content a bit.
{{% /notice %}}
Assumes the `lego` binary has permission to bind to ports 80 and 443.
You can get a pre-built binary from the [releases](https://github.com/go-acme/lego/releases) page.
If your environment does not allow you to bind to these ports, please read [Port Usage](usage/cli#port-usage).
You'll find the content now at one of these pages:
### Obtain a certificate
```bash
lego --email="foo@bar.com" --domains="example.com" --http run
```
You will find your certificate in the `.lego` folder of the current working directory:
```console
$ 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.
Please note, that 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`.
### Obtain a certificate (and hook)
The hook is executed only when the certificates are effectively created.
```bash
lego --email="foo@bar.com" --domains="example.com" --http run --run-hook="./myscript.sh"
```
Some information are added to the environment variables when the hook is used:
- `LEGO_ACCOUNT_EMAIL`: the email of the account.
- `LEGO_CERT_DOMAIN`: the main domain of the certificate.
- `LEGO_CERT_PATH`: the path of the certificate.
- `LEGO_CERT_KEY_PATH`: the path of the certificate key.
### To renew the certificate
```bash
lego --email="foo@bar.com" --domains="example.com" --http renew
```
### To renew the certificate only if it expires within 45 days
```bash
lego --email="foo@bar.com" --domains="example.com" --http renew --days 45
```
### To renew the certificate (and hook)
The hook is executed only when the certificates are effectively renewed.
```bash
lego --email="foo@bar.com" --domains="example.com" --http renew --renew-hook="./myscript.sh"
```
Some information are added to the environment variables when the hook is used:
- `LEGO_ACCOUNT_EMAIL`: the email of the account.
- `LEGO_CERT_DOMAIN`: the main domain of the certificate.
- `LEGO_CERT_PATH`: the path of the certificate.
- `LEGO_CERT_KEY_PATH`: the path of the certificate key.
### Obtain a certificate using the DNS challenge
```bash
AWS_REGION=us-east-1 \
AWS_ACCESS_KEY_ID=my_id \
AWS_SECRET_ACCESS_KEY=my_key \
lego --email="foo@bar.com" --domains="example.com" --dns="route53" run
```
### Obtain a certificate given a certificate signing request (CSR) generated by something else
```bash
lego --email="foo@bar.com" --http --csr=/path/to/csr.pem run
```
(lego will infer the domains to be validated based on the contents of the CSR, so make sure the CSR's Common Name and optional SubjectAltNames are set correctly.)
## Misc HTTP-01 CLI Examples
### Write HTTP-01 token to already "served" directory
If you have an existing server running on port 80 the `--http` option needs to also use the `--http.webroot` option.
This just writes the 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:
```bash
lego --accept-tos -m foo@bar.com --http --http.webroot /path/to/webroot -d example.com run
```
- Guide: [**How to obtain a certificate**]({{< ref "usage/cli/Obtain-a-Certificate" >}})
- Using the built-in web server
- Using a DNS provider
- Using a custom certificate signing request (CSR)
- Using an existing, running web server
- Running a script afterward
- Use case
- Guide: [**How to renew a certificate**]({{< ref "usage/cli/Renew-a-Certificate" >}})
- Using the built-in web server
- Using a DNS provider
- Running a script afterward
- Automatic renewal
- Reference: [**Command line options**]({{< ref "usage/cli/Options" >}})
- Usage
- Let's Encrypt ACME server
- Running without root privileges
- Port Usage