Skip to content

Commit

Permalink
Merge branch 'master' of github.com:luispabon/kong-certbot-agent
Browse files Browse the repository at this point in the history
  • Loading branch information
Luis Pabon committed Dec 12, 2018
2 parents cd898f3 + 325b957 commit fc18bfc
Show file tree
Hide file tree
Showing 16 changed files with 331 additions and 117 deletions.
112 changes: 84 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ Let's Encrypt integration with Kong
This repository provides with a cron-based certbot agent that will attempt to acquire Let's Encrypt certificates you control
for a list of subdomains you provide, and provision Kong with them.

There's an example [Kubernetes deployment configuration](kubernetes/certbot-cron.yml) you can use as a guide to deploy wherever you need.
Ideal for integrating a Kong deployment in Kubernetes with Let's Encrypt.

There's an example [kubernetes cronjob](kubernetes/certbot-cronjob.yml) you can use as a guide to deploy wherever you need.

## Compatibility

* Kong >= 0.14: use Kong Certbot Agent 2.x.
* Kong <= 0.13: use Kong Certbot Agent 1.x.

## How to

### Run the container
Expand All @@ -26,54 +28,77 @@ There's an example [Kubernetes deployment configuration](kubernetes/certbot-cron

### Kong configuration

In order for the challenge to work correctly, you need to open an API in Kong pointing to the container at a very
In order for the challenge to work correctly, you need to open up a service and a route in Kong pointing to the container at a very
specific URL path. It MUST respond on every domain you're requesting certs for.

When it comes the time to run certbot, it will open an HTTP server, put some stuff on a specific path, then ping
Let's Encrypt, which will attempt to read that from the domain requested. If successful, a certificate is generated.

This is an API definition example in Kong admin:
This is a service definition example in Kong admin:

```json
{
"methods": [
"GET",
"OPTIONS"
],
"uris": [
"/.well-known/acme-challenge"
],
"id": "asdasdasnd.asd",
"upstream_read_timeout": 60000,
"preserve_host": false,
"created_at": 1500911044000,
"upstream_connect_timeout": 60000,
"upstream_url": "http://kong-certbot-agent/.well-known/acme-challenge/",
"strip_uri": true,
"https_only": false,
"name": "certbot",
"http_if_terminated": true,
"upstream_send_timeout": 60000,
"retries": 5
"host": "kong-certbot-agent",
"created_at": 1543512083,
"connect_timeout": 60000,
"id": "service-id-foo",
"protocol": "http",
"name": "KongCertbot",
"read_timeout": 60000,
"port": 80,
"updated_at": 1543513810,
"retries": 5,
"write_timeout": 60000
}
```

This assumes that `http://kong-certbot-agent` is correctly pointing to the agent's container.

Then, associate this route to it:

```json
{
"created_at": 1543512115,
"strip_path": false,
"hosts": [
"your.list",
"of.domains",
"for.the",
"same.certificate"
],
"preserve_host": false,
"regex_priority": 0,
"updated_at": 1543513584,
"paths": [
"/.well-known/acme-challenge"
],
"service": {
"id": "service-id-foo"
},
"methods": [
"GET"
],
"protocols": [
"http"
],
"id": "route-id-foo"
}
```

## Kubernetes

Head off to the [Kubernetes deployment configuration](kubernetes) for examples, using a Kubernetes service
plus either a [deployment](kubernetes/certbot-cron.yml), or a [kubernetes cronjob](kubernetes/certbot-cronjob.yml).
plus either a [deployment (deprecated)](kubernetes/certbot-cron.yml), or a [kubernetes cronjob](kubernetes/certbot-cronjob.yml).

Cronjobs (formerly `scheduledjob`) are a relatively new thing in Kubernetes and won't be available unless you're on
Kubernetes 1.4+.
Note that the cron deployment is legacy stuff, from before Kubernetes had `CronJob` (pre 1.4). Please use a proper kubernetes
`CronJob` object for scheduling.

Note: your k8s service will always time out since there's nothing listening on HTTP except for when certbot itself is
running and requesting certs from LE.

## Command line tool

You can, alternatively, simply run the actual command yourself. This will allow you to use your own scheduling around
You can, alternatively, run the actual command yourself. This will allow you to use your own scheduling around
it, as it's done on the [kubernetes cronjob example](kubernetes/certbot-cronjob.yml).

```bash
Expand All @@ -86,9 +111,40 @@ docker run -it --rm phpdockerio/kong-certbot-agent \

# Get a TEST certificate for three subdomains, and submit to kong
docker run -it --rm phpdockerio/kong-certbot-agent \
./certbot-agent certs:update -t \
./certbot-agent certs:update \
--test-cert \
http://kong-admin:8001 \
foo@bar.com \
bar.com,foo.bar.com,www.bar.com

```

## FAQ

### How many domains can I get certs for?

You can give the agent a pretty big list of domains to acquire certificates for (100), but bear in mind it will be one certificate
shared among all of them. You might want to set up different cronjobs for different sets of certificates, grouped in a manner
that makes sense to you.

### How about wildcard certs?

Unfortunately, certbot does not support http challenges on wildcard certs, needing to resort to other types (like DNS).
Due to the way certbot agent works, this will never be supported by the agent.

### Any considerations on a first time set up?

Yes. Certbot has a limit of 50 certificate requests per hostname per week - it is very easy to go over this limit during
your initial set up while you manage to get all your stuff lined up together nicely:

* Use test certs initially, allowances are more generous. You can modify the command to `command: [ "/workdir/certbot-agent", "certs:update", "$(KONG_ENDPOINT)", "$(EMAIL)", "$(DOMAINS)", "--test-cert" ]` until you have everything right.
* Ensure your scheduling does not retry a failed command. It's very unlikely it will succeed a second time with the same parameters
and you'll go over the limit quicker than fast, especially in Kubernetes which by default will retry until your cluster goes down. The
[example kubernetes cronjob](kubernetes/certbot-cronjob.yml) specifically stops this from happening

### How often should I renew my certs?

By default, certbot has a limit of 50 certificate requests, so bear this in mind. Also, certs are good for 3 months. Let's Encrypt themselves recommend once every 60 days. [The example kubernetes cronjob](kubernetes/certbot-cronjob.yml)
is setup like so.

You can certainly do it more often, but there's no point in spamming Let's Encrypt with extra requests - remember this is a shared resource, free as in freedom and beer, and someone surely pays for it. Be considerate.
8 changes: 6 additions & 2 deletions certbot-agent
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@
declare(strict_types=1);

use GuzzleHttp\Client;
use PhpDockerIo\KongCertbot\Certbot\Handler as Certbot;
use PhpDockerIo\KongCertbot\Certbot\ShellExec;
use PhpDockerIo\KongCertbot\Command\UpdateCertificatesCommand;
use Symfony\Component\Console\Application;
use PhpDockerIo\KongCertbot\Kong\Handler as Kong;

include __DIR__ . '/vendor/autoload.php';

$app = new Application('Kong certbot agent');
$app->add(new UpdateCertificatesCommand(new Client(), new ShellExec()));
$app = new Application('Kong certbot agent');
$kong = new Kong(new Client());
$certbot = new Certbot(new ShellExec());
$app->add(new UpdateCertificatesCommand($kong, $certbot));
$app->run();
11 changes: 0 additions & 11 deletions certbot-agent-old

This file was deleted.

Loading

0 comments on commit fc18bfc

Please sign in to comment.