<?php if (!defined("PHP_VERSION_ID") || PHP_VERSION_ID < 50300 || !extension_loaded('openssl') || !extension_loaded('curl')) { die("You need at least PHP 5.3.0 with OpenSSL and curl extension\n"); } require 'Lescript.php'; // you can use any logger according to Psr\Log\LoggerInterface class Logger { function __call($name, $arguments) { echo date('Y-m-d H:i:s') . " [{$name}] {$arguments[0]}\n"; } } $logger = new Logger(); try { $le = new Analogic\ACME\Lescript('/certificate/storage', '/var/www/test.com', $logger); # or without logger: # $le = new Analogic\ACME\Lescript('/certificate/storage', '/var/www/test.com'); $le->contact = array('mailto:test@test.com'); // optional $le->initAccount(); $le->signDomains(array('test.com', 'www.test.com')); } catch (\Exception $e) { $logger->error($e->getMessage()); $logger->error($e->getTraceAsString()); }
/** * Update or Add Let's Encrypt * @param string $host The hostname (MUST BE A VALID FQDN) * @param boolean $staging Whether to use the staging server or not * @return boolean True if success, false if not */ public function updateLE($host, $countryCode = 'US', $state = 'Wisconsin', $staging = false) { $countryCode = !empty($countryCode) ? $countryCode : 'US'; $state = !empty($state) ? $state : 'Wisconsin'; $location = $this->PKCS->getKeysLocation(); $logger = new Certman\Logger(); $host = basename($host); $needsgen = false; $certfile = $location . "/" . $host . "/cert.pem"; if (!file_exists($certfile)) { // We don't have a cert, so we need to request one. $needsgen = true; } else { // We DO have a certificate. $certdata = openssl_x509_parse(file_get_contents($certfile)); // If it expires in less than a month, we want to renew it. $renewafter = $certdata['validTo_time_t'] - 86400 * 30; if (time() > $renewafter) { // Less than a month left, we need to renew. $needsgen = true; } } //check freepbx.org first if ($needsgen) { $basePathCheck = "/.freepbx-known"; if (!file_exists($this->FreePBX->Config->get("AMPWEBROOT") . $basePathCheck)) { $mkdirok = @mkdir($this->FreePBX->Config->get("AMPWEBROOT") . $basePathCheck, 0777); if (!$mkdirok) { throw new \Exception("Unable to create directory " . $this->FreePBX->Config->get("AMPWEBROOT") . $basePathCheck); } } $token = bin2hex(openssl_random_pseudo_bytes(16)); $pathCheck = $basePathCheck . "/" . $token; file_put_contents($this->FreePBX->Config->get("AMPWEBROOT") . $pathCheck, $token); $pest = new \PestJSON('http://mirror1.freepbx.org'); $pest->curl_opts[CURLOPT_FOLLOWLOCATION] = true; $thing = $pest->get('/lechecker.php', array('host' => $host, 'path' => $pathCheck, 'token' => $token)); if (empty($thing)) { throw new \Exception("No valid response from http://mirror1.freepbx.org"); } if (!$thing['status']) { throw new \Exception($thing['message']); } @unlink($this->FreePBX->Config->get("AMPWEBROOT") . $pathCheck); } //Now check let's encrypt if ($needsgen) { $le = new \Analogic\ACME\Lescript($location, $this->FreePBX->Config->get("AMPWEBROOT"), $logger); if ($staging) { $le->ca = 'https://acme-staging.api.letsencrypt.org'; } $le->countryCode = $countryCode; $le->state = $state; $le->initAccount(); $le->signDomains(array($host)); } if (file_exists($location . "/" . $host)) { copy($location . "/" . $host . "/private.pem", $location . "/" . $host . ".key"); //webserver.key copy($location . "/" . $host . "/chain.pem", $location . "/" . $host . "-ca-bundle.crt"); //ca-bundle.crt copy($location . "/" . $host . "/cert.pem", $location . "/" . $host . ".crt"); //webserver.crt $key = file_get_contents($location . "/" . $host . ".key"); $cert = file_get_contents($location . "/" . $host . ".crt"); $bundle = file_get_contents($location . "/" . $host . "-ca-bundle.crt"); file_put_contents($location . "/" . $host . ".pem", $key . "\n" . $cert . "\n" . $bundle); //should the chain be in here?? chmod($location . "/" . $host . ".crt", 0600); chmod($location . "/" . $host . ".key", 0600); chmod($location . "/" . $host . ".pem", 0600); chmod($location . "/" . $host . "-ca-bundle.crt", 0600); } return true; }
// If it expires in less than a month, we want to renew it. $renewafter = $certdata['validTo_time_t'] - 86400 * 30; if (time() > $renewafter) { // Less than a month left, we need to renew. $needsgen = true; } } } // Do we need to generate a certificate? if ($needsgen) { try { $le = new Analogic\ACME\Lescript($certlocation, $webroot, $logger); # or without logger: # $le = new Analogic\ACME\Lescript($certlocation, $webroot); $le->initAccount(); $le->signDomains($domains); } catch (\Exception $e) { $logger->error($e->getMessage()); $logger->error($e->getTraceAsString()); // Exit with an error code, something went wrong. exit(1); } } // Create a complete .pem file for use with haproxy or apache 2.4, // and save it as domain.name.pem for easy reference. It doesn't // matter that this is updated each time, as it'll be exactly // the same. foreach ($domains as $d) { $pem = file_get_contents("{$certlocation}/{$d}/fullchain.pem") . "\n" . file_get_contents("{$certlocation}/{$d}/private.pem"); file_put_contents("{$certlocation}/{$d}.pem", $pem); }
<?php error_reporting(E_ALL); ini_set('display_errors', 1); if (!defined("PHP_VERSION_ID") || PHP_VERSION_ID < 50300 || !extension_loaded('openssl') || !extension_loaded('curl')) { die("You need at least PHP 5.3.0 with OpenSSL and curl extension\n"); } require 'Lescript.php'; $certificatesDir = './certs'; $le = new Analogic\ACME\Lescript($certificatesDir); $le->initAccount(); $domainWebroots = ['example.com' => '/home/username/www', 'www.example.com' => '/home/username/www', 'example.org' => '/home/username/example.org', 'www.example.org' => '/home/username/example.org']; $le->setDomainWebroots($domainWebroots); $le->signDomains(array_keys($domainWebroots));