Skip to content
This repository has been archived by the owner on Nov 26, 2024. It is now read-only.

Commit

Permalink
Add the ability to talk to Kong when the admin endpoint sits behind a…
Browse files Browse the repository at this point in the history
… self signed cert
  • Loading branch information
luispabon committed Aug 26, 2021
1 parent 23489d4 commit 97c71cc
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 19 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,14 @@ docker run -it --rm \
-e TEST_CERT=true \
phpdockerio/kong-certbot-agent

# Get a certificate for a single domain, and submit to kong
# Kong's admin API is behind a self-signed certificate
docker run -it --rm \
-e KONG_ENDPOINT=http://kong-admin:8001 \
-e [email protected] \
-e DOMAINS=bar.com \
-e ALLOW_SELF_SIGNED_CERT_KONG=true \
phpdockerio/kong-certbot-agent
```

## FAQ
Expand Down
4 changes: 4 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@ if [[ ! -z "${TEST_CERT}" ]]; then
EXTRA_PARAMS="--test-cert"
fi;

if [[ ! -z "${ALLOW_SELF_SIGNED_CERT_KONG}" ]]; then
EXTRA_PARAMS="--allow-self-signed-cert-kong"
fi;

exec /workdir/certbot-agent certs:update ${EXTRA_PARAMS} ${KONG_ENDPOINT} ${EMAIL} ${DOMAINS}
2 changes: 1 addition & 1 deletion src/Certbot/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public function acquireCertificate(array $domains, string $email, bool $testCert
}

// Ensure certs are readable
$fullChain = file_get_contents($fullChainPath);
$fullChain = file_get_contents($fullChainPath);
$privateKey = file_get_contents($privateKeyPath);

return new Certificate(
Expand Down
37 changes: 23 additions & 14 deletions src/Command/UpdateCertificatesCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,25 +56,31 @@ protected function configure(): void
$this
->setDescription('Requests certificates from Let\'s Encrypt for the given domains and notifies Kong')
->addArgument(
'kong-endpoint',
InputArgument::REQUIRED,
'Base URL to Kong Admin API; eg: https://foo:8001'
name: 'kong-endpoint',
mode: InputArgument::REQUIRED,
description: 'Base URL to Kong Admin API; eg: https://foo:8001'
)
->addArgument(
'email',
InputArgument::REQUIRED,
'Email the set of domains is to be associated with at Let\'s Encrypt'
name: 'email',
mode: InputArgument::REQUIRED,
description: 'Email the set of domains is to be associated with at Let\'s Encrypt'
)
->addArgument(
'domains',
InputArgument::REQUIRED,
'Comma separated list of domains to request certs for; eg: bar.com,foo.bar.com'
name: 'domains',
mode: InputArgument::REQUIRED,
description: 'Comma separated list of domains to request certs for; eg: bar.com,foo.bar.com'
)
->addOption(
'test-cert',
't',
InputOption::VALUE_NONE,
'Require test certificate from staging-letsencrypt'
name: 'test-cert',
shortcut: 't',
mode: InputOption::VALUE_NONE,
description: 'Require test certificate from staging-letsencrypt'
)
->addOption(
name: 'allow-self-signed-cert-kong',
shortcut: '-s',
mode: InputOption::VALUE_NONE,
description: "Allow self signed certs in Kong's admin endpoint",
);
}

Expand Down Expand Up @@ -107,6 +113,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
/** @var bool $testCert */
$testCert = $input->getOption('test-cert');

/** @var bool $allowSelfSignedCert */
$allowSelfSignedCert = $input->getOption('allow-self-signed-cert-kong');

$this->validateInput($email, $kongAdminUri, $domains);

// Acquire certificates from certbot. This is not all-or-nothing, whatever certs we acquire come out here
Expand All @@ -116,7 +125,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$certificate = $this->certbot->acquireCertificate($domains, $email, $testCert);

// Store certs into kong via the admin UI. Again, not all-or-nothing
if ($this->kong->store($certificate, $kongAdminUri) === true) {
if ($this->kong->store($certificate, $kongAdminUri, $allowSelfSignedCert) === true) {
$certOrCerts = count($certificate->getDomains()) > 1 ? 'Certificates' : 'Certificate';

$output->writeln(sprintf('%s for %s correctly sent to Kong', $certOrCerts, $outputDomains));
Expand Down
9 changes: 5 additions & 4 deletions src/Kong/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function __construct(private ClientInterface $guzzle)
/**
* Stores the given certificate in Kong.
*/
public function store(Certificate $certificate, string $kongAdminUri): bool
public function store(Certificate $certificate, string $kongAdminUri, bool $allowSelfSignedCert): bool
{
$payload = [
'headers' => [
Expand All @@ -39,16 +39,17 @@ public function store(Certificate $certificate, string $kongAdminUri): bool
'key' => $certificate->getKey(),
'snis' => $certificate->getDomains(),
],
'verify' => !$allowSelfSignedCert,
];

// From Kong 0.14, they finally fixed PUT as UPSERT
// Any domain can be used on the endpoint, as they're aliased internally to the single
// certificate object within Kong
try {
$this->guzzle->request(
'put',
sprintf('%s/certificates/%s', $kongAdminUri, $certificate->getDomains()[0]),
$payload
method: 'put',
uri: sprintf('%s/certificates/%s', $kongAdminUri, $certificate->getDomains()[0]),
options: $payload,
);
} catch (BadResponseException $ex) {
$request = $ex->getRequest();
Expand Down

0 comments on commit 97c71cc

Please sign in to comment.