10 Commits

Author SHA1 Message Date
Niklas Keller
35070bb70a Add logging support for debugging 2018-06-09 19:00:02 +02:00
Niklas Keller
6da46ddaf6 Upgrade dependencies 2018-06-06 21:50:52 +02:00
Niklas Keller
51acff5bd3 Implement --rekey option
Closes #65.
Closes #19.
2018-04-15 19:14:36 +02:00
Niklas Keller
ea3e9dc68c Update LICENSE date 2018-04-15 18:27:00 +02:00
Niklas Keller
6f01055884 Upgrade to amphp/process v0.3.x 2018-04-15 18:19:40 +02:00
Niklas Keller
297e1aa9b1 Update dependencies 2018-04-15 18:12:32 +02:00
Niklas Keller
b7cfe3c0f1 Update to amphp/parallel v0.2.5
This fixes running as PHAR if the PHAR doesn't end with '.phar'.
2018-03-21 15:52:05 +01:00
Niklas Keller
4053094860 Update .travis.yml 2018-03-21 13:06:30 +01:00
Niklas Keller
a80b7b8497 Remove BlockingDriver usage, as parallel has been fixed 2018-03-21 12:55:25 +01:00
Niklas Keller
f13b0856c7 Update dependencies 2018-03-21 12:54:21 +01:00
11 changed files with 509 additions and 288 deletions

View File

@@ -28,7 +28,10 @@ certificates:
# user: User running the web server. Challenge files are world readable,
# but some servers might require to be owner of files they serve.
#
# rekey: Regenerate certificate key pairs even if a key pair already exists.
#
- bits: 4096
rekey: true
paths:
/var/www/example:
- example.org

View File

@@ -12,10 +12,7 @@ cache:
install:
- phpenv config-rm xdebug.ini || true
- composer config --global discard-changes true
- composer update
- composer require satooshi/php-coveralls dev-master --dev
- composer show --installed
- composer install
script:
- find -name "*.php" -not -path "./vendor/*" -print0 | xargs -n 1 -0 php -l
@@ -23,4 +20,6 @@ script:
- PHP_CS_FIXER_IGNORE_ENV=1 php vendor/bin/php-cs-fixer --diff --dry-run -v fix
after_script:
- php vendor/bin/coveralls -v
- curl -OL https://github.com/php-coveralls/php-coveralls/releases/download/v1.0.0/coveralls.phar
- chmod +x coveralls.phar
- ./coveralls.phar -v

View File

@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2015-2017 Niklas Keller
Copyright (c) 2015-2018 Niklas Keller
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,12 +1,10 @@
#!/usr/bin/env php
<?php
use Amp\File\BlockingDriver;
use Amp\Loop;
use Auryn\Injector;
use Kelunik\AcmeClient\AcmeFactory;
use League\CLImate\CLImate;
use function Amp\File\filesystem;
$logo = <<<LOGO
____ __________ ___ ___
@@ -107,9 +105,6 @@ if (!array_key_exists($argv[1], $commands)) {
exit(1);
}
// Use blocking driver for now, as amphp/parallel doesn't work inside PHARs
filesystem(new BlockingDriver);
/** @var \Kelunik\AcmeClient\Commands\Command $class */
$class = "Kelunik\\AcmeClient\\Commands\\" . ucfirst($argv[1]);
$definition = $class::getDefinition();

View File

@@ -13,13 +13,15 @@
"require": {
"php": ">=7",
"ext-openssl": "*",
"amphp/process": "^0.2",
"amphp/process": "^0.3.3",
"amphp/parallel": "^0.2.5",
"kelunik/acme": "^0.5",
"kelunik/certificate": "^1",
"league/climate": "^3.2",
"rdlowrey/auryn": "^1.4.2",
"webmozart/assert": "^1.2",
"symfony/yaml": "^3.0"
"symfony/yaml": "^3.0",
"amphp/log": "^1.0"
},
"require-dev": {
"phpunit/phpunit": "^6",

713
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -24,7 +24,7 @@ You can separate multiple domains (`-d`) with `,`, `:` or `;`. You can separate
If you specify less paths than domains, the last one will be used for the remaining domains.
Please note that Let's Encrypt has rate limits. Currently it's five certificates per domain per seven days. If you combine multiple subdomains in a single certificate, they count as just one certificate. If you just want to test things out, you can use their staging server, which has way higher rate limits by appending `--s letsencrypt:staging`.
Please note that Let's Encrypt has rate limits. Currently it's five certificates per domain per seven days. If you combine multiple subdomains in a single certificate, they count as just one certificate. If you just want to test things out, you can use their staging server, which has way higher rate limits by appending `--server letsencrypt:staging`.
## Revoke a Certificate

View File

@@ -53,7 +53,10 @@ certificates:
# user: User running the web server. Challenge files are world readable,
# but some servers might require to be owner of files they serve.
#
# rekey: Regenerate certificate key pairs even if a key pair already exists.
#
- bits: 4096
rekey: true
paths:
/var/www/example:
- example.org

View File

@@ -2,12 +2,27 @@
namespace Kelunik\AcmeClient;
use Amp\ByteStream\ResourceOutputStream;
use Amp\Log\ConsoleFormatter;
use Amp\Log\StreamHandler;
use Kelunik\Acme\AcmeClient;
use Kelunik\Acme\AcmeService;
use Kelunik\Acme\Crypto\PrivateKey;
use Monolog\Logger;
use Monolog\Processor\PsrLogMessageProcessor;
class AcmeFactory {
public function build(string $directory, PrivateKey $keyPair): AcmeService {
return new AcmeService(new AcmeClient($directory, $keyPair));
$logger = null;
if (\getenv('ACME_LOG')) {
$logger = new Logger('acme');
$logger->pushProcessor(new PsrLogMessageProcessor);
$handler = new StreamHandler(new ResourceOutputStream(\STDERR));
$handler->setFormatter(new ConsoleFormatter(null, null, true, true));
$logger->pushHandler($handler);
}
return new AcmeService(new AcmeClient($directory, $keyPair, null, null, $logger));
}
}

View File

@@ -86,6 +86,13 @@ class Auto implements Command {
return self::EXIT_CONFIG_ERROR;
}
foreach ($config['certificates'] as $certificateConfig) {
if (isset($certificateConfig['rekey']) && !\is_bool($certificateConfig['rekey'])) {
$this->climate->error("Config file ({$configPath}) defines an invalid 'rekey' value.");
return self::EXIT_CONFIG_ERROR;
}
}
$concurrency = isset($config['challenge-concurrency']) ? (int) $config['challenge-concurrency'] : null;
$process = new Process([
@@ -179,8 +186,7 @@ class Auto implements Command {
$domainPathMap = $this->toDomainPathMap($certificate['paths']);
$domains = \array_keys($domainPathMap);
$commonName = \reset($domains);
$process = new Process([
$processArgs = [
PHP_BINARY,
$GLOBALS['argv'][0],
'check',
@@ -192,7 +198,13 @@ class Auto implements Command {
$commonName,
'--names',
\implode(',', $domains),
]);
];
if ($certificate['rekey'] ?? false) {
$processArgs[] = '--rekey';
}
$process = new Process($processArgs);
$process->start();
$exit = yield $process->join();

View File

@@ -97,14 +97,20 @@ class Issue implements Command {
throw new AcmeException('Issuance failed, not all challenges could be solved.');
}
$path = 'certs/' . $keyFile . '/' . \reset($domains) . '/key.pem';
$keyPath = 'certs/' . $keyFile . '/' . \reset($domains) . '/key.pem';
$bits = $args->get('bits');
$regenerateKey = $args->get('rekey');
try {
$key = yield $keyStore->get($path);
$key = yield $keyStore->get($keyPath);
} catch (KeyStoreException $e) {
$regenerateKey = true;
}
if ($regenerateKey) {
$this->climate->whisper(' Generating new key pair ...');
$key = (new RsaKeyGenerator($bits))->generateKey();
$key = yield $keyStore->put($path, $key);
}
$this->climate->br();
@@ -117,6 +123,8 @@ class Issue implements Command {
$path = AcmeClient\normalizePath($args->get('storage')) . '/certs/' . $keyFile;
$certificateStore = new CertificateStore($path);
yield $keyStore->put($keyPath, $key);
yield $certificateStore->put($certificates);
$this->climate->info(' Successfully issued certificate.');
@@ -232,6 +240,11 @@ class Issue implements Command {
'defaultValue' => 10,
'castTo' => 'int',
],
'rekey' => [
'longPrefix' => 'rekey',
'description' => 'Regenerate the key pair even if a key pair already exists.',
'noValue' => true,
],
];
}
}