diff --git a/admin_customers.php b/admin_customers.php
index dd7add11..0c96941c 100644
--- a/admin_customers.php
+++ b/admin_customers.php
@@ -940,7 +940,8 @@ if ($page == 'customers'
WHERE `id` = :defaultip
");
$default_ips = Settings::Get('system.defaultip');
- $srv_ip = Database::pexecute_first($srv_ip_stmt, array('defaultip' => reset(explode(',', $default_ips))));
+ $default_ips = explode(',', $default_ips);
+ $srv_ip = Database::pexecute_first($srv_ip_stmt, array('defaultip' => reset($default_ips)));
$replace_arr = array(
'FIRSTNAME' => $firstname,
diff --git a/admin_domains.php b/admin_domains.php
index 51de4672..be9f508e 100644
--- a/admin_domains.php
+++ b/admin_domains.php
@@ -245,6 +245,8 @@ if ($page == 'domains' || $page == 'overview') {
'domainid' => $id
));
+ triggerLetsEncryptCSRForAliasDestinationDomain($result['aliasdomain'], $log);
+
$log->logAction(ADM_ACTION, LOG_INFO, "deleted domain/subdomains (#" . $result['id'] . ")");
updateCounters();
inserttask('1');
@@ -672,10 +674,6 @@ if ($page == 'domains' || $page == 'overview') {
$issubof = '0';
}
- if ($aliasdomain != 0 && $letsencrypt != 0) {
- standard_error('letsencryptdoesnotworkwithaliasdomains');
- }
-
if ($domain == '') {
standard_error(array(
'stringisempty',
@@ -843,6 +841,9 @@ elseif (Settings::Get('system.validate_domain') && ! validateDomain($domain)) {
Database::pexecute($ins_stmt, $ins_data);
}
}
+
+ triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $log);
+
$log->logAction(ADM_ACTION, LOG_INFO, "added domain '" . $domain . "'");
inserttask('1');
@@ -1472,10 +1473,6 @@ elseif (Settings::Get('system.validate_domain') && ! validateDomain($domain)) {
$issubof = '0';
}
- if ($aliasdomain != 0 && $letsencrypt != 0) {
- standard_error('letsencryptdoesnotworkwithaliasdomains');
- }
-
if ($serveraliasoption != '1' && $serveraliasoption != '2') {
$serveraliasoption = '0';
}
@@ -1802,6 +1799,15 @@ elseif (Settings::Get('system.validate_domain') && ! validateDomain($domain)) {
}
}
}
+ if ($result['aliasdomain'] != $aliasdomain) {
+ // trigger when domain id for alias destination has changed: both for old and new destination
+ triggerLetsEncryptCSRForAliasDestinationDomain($result['aliasdomain'], $log);
+ triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $log);
+ } else
+ if ($result['wwwserveralias'] != $wwwserveralias || $result['letsencrypt'] != $letsencrypt) {
+ // or when wwwserveralias or letsencrypt was changed
+ triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $log);
+ }
$log->logAction(ADM_ACTION, LOG_INFO, "edited domain #" . $id);
redirectTo($filename, array(
diff --git a/customer_domains.php b/customer_domains.php
index 28f4833a..daccf9f5 100644
--- a/customer_domains.php
+++ b/customer_domains.php
@@ -171,7 +171,7 @@ if ($page == 'overview') {
eval("echo \"" . getTemplate("domains/domainlist") . "\";");
} elseif ($action == 'delete' && $id != 0) {
- $stmt = Database::prepare("SELECT `id`, `customerid`, `domain`, `documentroot`, `isemaildomain`, `parentdomainid` FROM `" . TABLE_PANEL_DOMAINS . "`
+ $stmt = Database::prepare("SELECT `id`, `customerid`, `domain`, `documentroot`, `isemaildomain`, `parentdomainid`, `aliasdomain` FROM `" . TABLE_PANEL_DOMAINS . "`
WHERE `customerid` = :customerid
AND `id` = :id"
);
@@ -197,6 +197,8 @@ if ($page == 'overview') {
}
}
+ triggerLetsEncryptCSRForAliasDestinationDomain($result['aliasdomain'], $log);
+
$log->logAction(USR_ACTION, LOG_INFO, "deleted subdomain '" . $idna_convert->decode($result['domain']) . "'");
$stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DOMAINS . "` WHERE
`customerid` = :customerid
@@ -290,6 +292,7 @@ if ($page == 'overview') {
ORDER BY `d`.`domain` ASC;"
);
$aliasdomain_check = Database::pexecute_first($aliasdomain_stmt, array("id" => $aliasdomain, "customerid" => $userinfo['customerid']));
+ triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $log);
}
if (isset($_POST['url']) && $_POST['url'] != '' && validateUrl($idna_convert->encode($_POST['url']))) {
@@ -342,11 +345,6 @@ if ($page == 'overview') {
}
}
- if ($aliasdomain != 0 && $letsencrypt != 0)
- {
- standard_error('letsencryptdoesnotworkwithaliasdomains');
- }
-
// Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated
if ($ssl_redirect > 0 && $letsencrypt == 1) {
$ssl_redirect = 2;
@@ -610,11 +608,6 @@ if ($page == 'overview') {
$letsencrypt = '0';
}
- if ($aliasdomain != 0 && $letsencrypt != 0)
- {
- standard_error('letsencryptdoesnotworkwithaliasdomains');
- }
-
// We can't enable let's encrypt for wildcard - domains
if ($iswildcarddomain == '1' && $letsencrypt == '1') {
standard_error('nowildcardwithletsencrypt');
@@ -677,6 +670,17 @@ if ($page == 'overview') {
"id" => $id
);
Database::pexecute($stmt, $params);
+
+ if ($result['aliasdomain'] != $aliasdomain) {
+ // trigger when domain id for alias destination has changed: both for old and new destination
+ triggerLetsEncryptCSRForAliasDestinationDomain($result['aliasdomain'], $log);
+ triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $log);
+ } else
+ if ($result['wwwserveralias'] != $wwwserveralias || $result['letsencrypt'] != $letsencrypt) {
+ // or when wwwserveralias or letsencrypt was changed
+ triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $log);
+ }
+
inserttask('1');
// Using nameserver, insert a task which rebuilds the server config
diff --git a/lib/classes/ssl/class.lescript.php b/lib/classes/ssl/class.lescript.php
index 189d2333..3bf8b6af 100644
--- a/lib/classes/ssl/class.lescript.php
+++ b/lib/classes/ssl/class.lescript.php
@@ -62,16 +62,23 @@ class lescript
$keys = $this->generateKey();
// Only store the accountkey in production, in staging always generate a new key
if (Settings::Get('system.letsencryptca') == 'production') {
- $upd_stmt = Database::prepare("
- UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `lepublickey` = :public, `leprivatekey` = :private WHERE `customerid` = :customerid;
- ");
- Database::pexecute($upd_stmt, array(
- 'public' => $keys['public'],
- 'private' => $keys['private'],
- 'customerid' => $certrow['customerid']
- ));
+ $upd_stmt = Database::prepare(
+ "UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `lepublickey` = :public, `leprivatekey` = :private " .
+ "WHERE `customerid` = :customerid;");
+ Database::pexecute($upd_stmt,
+ array(
+ 'public' => $keys['public'],
+ 'private' => $keys['private'],
+ 'customerid' => $certrow['customerid']
+ ));
}
$this->accountKey = $keys['private'];
+
+ $response = $this->postNewReg();
+ if ($this->client->getLastCode() != 201) {
+ throw new \RuntimeException("Account not initialized, probably due to rate limiting. Whole response: " . $response);
+ }
+
$this->postNewReg();
$this->log('New account certificate registered');
} else {
@@ -83,7 +90,7 @@ class lescript
public function signDomains(array $domains, $domainkey = null, $csr = null)
{
if (! $this->accountKey) {
- throw new \RuntimeException("Account not initiated");
+ throw new \RuntimeException("Account not initialized");
}
$this->log('Starting certificate generation process for domains');
@@ -101,13 +108,14 @@ class lescript
$this->log("Requesting challenge for $domain");
- $response = $this->signedRequest("/acme/new-authz", array(
- "resource" => "new-authz",
- "identifier" => array(
- "type" => "dns",
- "value" => $domain
- )
- ));
+ $response = $this->signedRequest("/acme/new-authz",
+ array(
+ "resource" => "new-authz",
+ "identifier" => array(
+ "type" => "dns",
+ "value" => $domain
+ )
+ ));
// if response is not an array but a string, it's most likely a server-error, e.g.
//
ErrorAn error occurred while processing your request.
@@ -121,9 +129,10 @@ class lescript
}
// choose http-01 challenge only
- $challenge = array_reduce($response['challenges'], function ($v, $w) {
- return $v ? $v : ($w['type'] == 'http-01' ? $w : false);
- });
+ $challenge = array_reduce($response['challenges'],
+ function ($v, $w) {
+ return $v ? $v : ($w['type'] == 'http-01' ? $w : false);
+ });
if (! $challenge)
throw new RuntimeException("HTTP Challenge for $domain is not available. Whole response: " . json_encode($response));
@@ -145,8 +154,7 @@ class lescript
"e" => Base64UrlSafeEncoder::encode($accountKeyDetails["rsa"]["e"]),
"kty" => "RSA",
"n" => Base64UrlSafeEncoder::encode($accountKeyDetails["rsa"]["n"])
- )
- ;
+ );
$payload = $challenge['token'] . '.' . Base64UrlSafeEncoder::encode(hash('sha256', json_encode($header), true));
file_put_contents($tokenPath, $payload);
@@ -174,12 +182,13 @@ class lescript
$this->log("Sending request to challenge");
// send request to challenge
- $result = $this->signedRequest($challenge['uri'], array(
- "resource" => "challenge",
- "type" => "http-01",
- "keyAuthorization" => $payload,
- "token" => $challenge['token']
- ));
+ $result = $this->signedRequest($challenge['uri'],
+ array(
+ "resource" => "challenge",
+ "type" => "http-01",
+ "keyAuthorization" => $payload,
+ "token" => $challenge['token']
+ ));
// waiting loop
// we wait for a maximum of 30 seconds to avoid endless loops
@@ -218,9 +227,7 @@ class lescript
$this->client->getLastLinks();
- if (empty($csrfile) || Settings::Get('system.letsencryptreuseold') == 0) {
- $csr = $this->generateCSR($privateDomainKey, $domains);
- }
+ $csr = $this->generateCSR($privateDomainKey, $domains);
// request certificates creation
$result = $this->signedRequest("/acme/new-cert", array(
@@ -306,7 +313,8 @@ class lescript
$tmpConfPath = $tmpConfMeta["uri"];
// workaround to get SAN working
- fwrite($tmpConf, 'HOME = .
+ fwrite($tmpConf,
+ 'HOME = .
RANDFILE = $ENV::HOME/.rnd
[ req ]
default_bits = ' . Settings::Get('system.letsencryptkeysize') . '
@@ -320,15 +328,16 @@ basicConstraints = CA:FALSE
subjectAltName = ' . $san . '
keyUsage = nonRepudiation, digitalSignature, keyEncipherment');
- $csr = openssl_csr_new(array(
- "CN" => $domain,
- "ST" => Settings::Get('system.letsencryptstate'),
- "C" => Settings::Get('system.letsencryptcountrycode'),
- "O" => "Unknown"
- ), $privateKey, array(
- "config" => $tmpConfPath,
- "digest_alg" => "sha256"
- ));
+ $csr = openssl_csr_new(
+ array(
+ "CN" => $domain,
+ "ST" => Settings::Get('system.letsencryptstate'),
+ "C" => Settings::Get('system.letsencryptcountrycode'),
+ "O" => "Unknown"
+ ), $privateKey, array(
+ "config" => $tmpConfPath,
+ "digest_alg" => "sha256"
+ ));
if (! $csr)
throw new \RuntimeException("CSR couldn't be generated! " . openssl_error_string());
@@ -343,10 +352,11 @@ keyUsage = nonRepudiation, digitalSignature, keyEncipherment');
private function generateKey()
{
- $res = openssl_pkey_new(array(
- "private_key_type" => OPENSSL_KEYTYPE_RSA,
- "private_key_bits" => (int) Settings::Get('system.letsencryptkeysize')
- ));
+ $res = openssl_pkey_new(
+ array(
+ "private_key_type" => OPENSSL_KEYTYPE_RSA,
+ "private_key_bits" => (int) Settings::Get('system.letsencryptkeysize')
+ ));
if (! openssl_pkey_export($res, $privateKey)) {
throw new \RuntimeException("Key export failed!");
diff --git a/lib/configfiles/jessie.xml b/lib/configfiles/jessie.xml
index 3ab1c2b5..27050f9b 100644
--- a/lib/configfiles/jessie.xml
+++ b/lib/configfiles/jessie.xml
@@ -40,14 +40,14 @@
-
-
//service[@type='http']/general/commands
+
+
{{settings.phpfpm.enabled}}
@@ -4022,7 +4022,7 @@ aliases: files
-
+
/etc/insserv/overrides
diff --git a/lib/configfiles/precise.xml b/lib/configfiles/precise.xml
index 54b8fd38..885c3522 100644
--- a/lib/configfiles/precise.xml
+++ b/lib/configfiles/precise.xml
@@ -40,8 +40,6 @@
-
-
@@ -49,6 +47,8 @@
default="true">
//service[@type='http']/general/commands
+
+
{{settings.phpfpm.enabled}}
diff --git a/lib/configfiles/rhel_centos.xml b/lib/configfiles/rhel_centos.xml
index b43e5a03..9057fba5 100644
--- a/lib/configfiles/rhel_centos.xml
+++ b/lib/configfiles/rhel_centos.xml
@@ -40,8 +40,6 @@
-
-
diff --git a/lib/configfiles/trusty.xml b/lib/configfiles/trusty.xml
index fd961f62..770c93b0 100644
--- a/lib/configfiles/trusty.xml
+++ b/lib/configfiles/trusty.xml
@@ -40,8 +40,6 @@
-
-
@@ -49,6 +47,8 @@
default="true">
//service[@type='http']/general/commands
+
+
{{settings.phpfpm.enabled}}
@@ -83,6 +83,8 @@ Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}
//service[@type='http']/general/commands
+
+
{{settings.phpfpm.enabled}}
diff --git a/lib/configfiles/wheezy.xml b/lib/configfiles/wheezy.xml
index 782c41fb..c3824096 100644
--- a/lib/configfiles/wheezy.xml
+++ b/lib/configfiles/wheezy.xml
@@ -40,8 +40,6 @@
-
-
@@ -49,6 +47,8 @@
default="true">
//service[@type='http']/general/commands
+
+
{{settings.phpfpm.enabled}}
@@ -83,6 +83,8 @@ Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}
//service[@type='http']/general/commands
+
+
{{settings.phpfpm.enabled}}
diff --git a/lib/functions/froxlor/function.triggerLetsEncryptCSRForAliasDestinationDomain.php b/lib/functions/froxlor/function.triggerLetsEncryptCSRForAliasDestinationDomain.php
new file mode 100644
index 00000000..cda8ac98
--- /dev/null
+++ b/lib/functions/froxlor/function.triggerLetsEncryptCSRForAliasDestinationDomain.php
@@ -0,0 +1,34 @@
+ (2016-)
+ * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
+ * @package Functions
+ *
+ */
+
+function triggerLetsEncryptCSRForAliasDestinationDomain($aliasDestinationDomainID, $log)
+{
+ if (isset($aliasDestinationDomainID) && $aliasDestinationDomainID > 0) {
+ $log->logAction(ADM_ACTION, LOG_INFO, "LetsEncrypt CSR triggered for domain ID " . $aliasDestinationDomainID);
+ $upd_stmt = Database::prepare(
+ "UPDATE
+ `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
+ SET
+ `expirationdate` = null
+ WHERE
+ domainid = :domainid
+ ");
+ Database::pexecute($upd_stmt, array(
+ 'domainid' => $aliasDestinationDomainID
+ ));
+ }
+}
diff --git a/lng/english.lng.php b/lng/english.lng.php
index 43538921..bb2043e5 100644
--- a/lng/english.lng.php
+++ b/lng/english.lng.php
@@ -1936,7 +1936,6 @@ $lng['customer']['letsencrypt']['title'] = 'Use Let\'s Encrypt';
$lng['customer']['letsencrypt']['description'] = 'Get a free certificate from Let\'s Encrypt. The certificate will be created and renewed automatically.
ATTENTION: This feature is still in beta.';
$lng['error']['sslredirectonlypossiblewithsslipport'] = 'Using Let\'s Encrypt is only possible when the domain has at least one ssl-enabled IP/port combination assigned.';
$lng['error']['nowildcardwithletsencrypt'] = 'Let\'s Encrypt cannot (yet) handle wildcard-domains. Please set the ServerAlias to WWW or disable it completely';
-$lng['error']['letsencryptdoesnotworkwithaliasdomains'] = "Usage of Let's Encrypt is not possible for aliasdomains at the moment. Please disable Let's Encrypt or AliasDomain";
$lng['panel']['letsencrypt'] = 'Using Let\'s encrypt';
$lng['crondesc']['cron_letsencrypt'] = 'updating Let\'s Encrypt certificates';
$lng['serversettings']['letsencryptca']['title'] = "Let's Encrypt environment";
@@ -1949,8 +1948,8 @@ $lng['serversettings']['letsencryptchallengepath']['title'] = "Path for Let's En
$lng['serversettings']['letsencryptchallengepath']['description'] = "Directory where the Let's Encrypt challenges should be offered from via a global alias.
ATTENTION: Let's Encrypt is still in beta";
$lng['serversettings']['letsencryptkeysize']['title'] = "Key size for new Let's Encrypt certificates";
$lng['serversettings']['letsencryptkeysize']['description'] = "Size of the key in Bits for new Let's Encrypt certificates.
ATTENTION: Let's Encrypt is still in beta";
-$lng['serversettings']['letsencryptreuseold']['title'] = "Re-use Let's Encrypt key / CSR";
-$lng['serversettings']['letsencryptreuseold']['description'] = "If activated, the same key and CSR will be used for every renew, otherwise a new key / CSR will be generated every time.
ATTENTION: Let's Encrypt is still in beta";
+$lng['serversettings']['letsencryptreuseold']['title'] = "Re-use Let's Encrypt key";
+$lng['serversettings']['letsencryptreuseold']['description'] = "If activated, the same key will be used for every renew, otherwise a new key will be generated every time.
ATTENTION: Let's Encrypt is still in beta";
$lng['serversettings']['leenabled']['title'] = "Enable Let's Encrypt";
$lng['serversettings']['leenabled']['description'] = "If activated, customers are able to let froxlor automatically generate and renew Let's Encrypt ssl-certificates for domains with a ssl IP/port.
Please remember that you need to go through the webserver-configuration when eabled because this feature needs a special configuration.";
$lng['domains']['ssl_redirect_temporarilydisabled'] = "
The SSL redirect is temporarily deactivated while a new Let's Encrypt certificate is generated. It will be activated again after the certificate was generated.";
diff --git a/lng/german.lng.php b/lng/german.lng.php
index 70e483ad..36be1a7c 100644
--- a/lng/german.lng.php
+++ b/lng/german.lng.php
@@ -1590,7 +1590,6 @@ $lng['customer']['letsencrypt']['title'] = 'Benutze Let\'s Encrypt';
$lng['customer']['letsencrypt']['description'] = 'Holt ein kostenloses Zertifikat von Let\'s Encrypt. Das Zertifikat wird automatisch erstellt und verlängert.
ACHTUNG: Dieses Feature befindet sich noch im Test.';
$lng['error']['sslredirectonlypossiblewithsslipport'] = 'Die Nutzung von Let\'s Encrypt ist nur möglich, wenn die Domain mindestens eine IP/Port - Kombination mit aktiviertem SSL zugewiesen hat.';
$lng['error']['nowildcardwithletsencrypt'] = 'Let\'s Encrypt kann (noch) nicht mit Wildcard-Domains umgehen. Bitte den ServerAlias auf WWW setzen oder deaktivieren';
-$lng['error']['letsencryptdoesnotworkwithaliasdomains'] = "Die Nutzung von Let's Encrypt ist mit AliasDomains derzeit nicht möglich. Bitte Let's Encrypt oder AliasDomain deaktivieren";
$lng['panel']['letsencrypt'] = 'Benutzt Let\'s encrypt';
$lng['crondesc']['cron_letsencrypt'] = 'aktualisiert Let\'s Encrypt Zertifikate';
$lng['serversettings']['letsencryptca']['title'] = "Let's Encrypt Umgebung";
@@ -1603,8 +1602,8 @@ $lng['serversettings']['letsencryptchallengepath']['title'] = "Verzeichnis für
$lng['serversettings']['letsencryptchallengepath']['description'] = "Let's Encrypt challenges werden aus diesem Verzeichnis über einen globalen Alias ausgeliefert.
ACHTUNG: Let's Encrypt befindet sich noch im Test";
$lng['serversettings']['letsencryptkeysize']['title'] = "Schlüsselgröße für neue Let's Encrypt Zertifikate";
$lng['serversettings']['letsencryptkeysize']['description'] = "Größe des Schlüssels in Bit für neue Let's Encrypt Zertifikate.
ACHTUNG: Let's Encrypt befindet sich noch im Test";
-$lng['serversettings']['letsencryptreuseold']['title'] = "Let's Encrypt Schlüssel / CSR wiederverwenden";
-$lng['serversettings']['letsencryptreuseold']['description'] = "Wenn dies aktiviert ist, werden der alte Schlüssel und CSR bei jeder Verlängerung verwendet, andernfalls wird ein neues Paar generiert.
ACHTUNG: Let's Encrypt befindet sich noch im Test";
+$lng['serversettings']['letsencryptreuseold']['title'] = "Let's Encrypt Schlüssel wiederverwenden";
+$lng['serversettings']['letsencryptreuseold']['description'] = "Wenn dies aktiviert ist, wird der alte Schlüssel bei jeder Verlängerung verwendet, andernfalls wird ein neues Paar generiert.
ACHTUNG: Let's Encrypt befindet sich noch im Test";
$lng['serversettings']['leenabled']['title'] = "Let's Encrypt verwenden";
$lng['serversettings']['leenabled']['description'] = "Wenn dies aktiviert ist, können Kunden durch Froxlor automatisch generierte und verlängerbare Let's Encrypt SSL-Zertifikate für Domains mit SSL IP/port nutzen.
Bitte die Webserver-Konfiguration beachten wenn aktiviert, da dieses Feature eine spezielle Konfiguration benötigt.";
$lng['domains']['ssl_redirect_temporarilydisabled'] = "
Die SSL-Umleitung ist, während ein neues Let's Encrypt - Zertifikat erstellt wird, temporär deaktiviert. Die Umleitung wird nach der Zertifikatserstellung wieder aktiviert.";
diff --git a/scripts/jobs/cron_letsencrypt.php b/scripts/jobs/cron_letsencrypt.php
index 1848480f..8fe3d5af 100644
--- a/scripts/jobs/cron_letsencrypt.php
+++ b/scripts/jobs/cron_letsencrypt.php
@@ -1,5 +1,4 @@
logAction(CRON_ACTION, LOG_INFO, "Updating Let's Encrypt certificates"
if (! extension_loaded('curl')) {
$cronlog->logAction(CRON_ACTION, LOG_ERR, "Let's Encrypt requires the php cURL extension to be installed.");
- exit;
+ exit();
}
-$certificates_stmt = Database::query("
- SELECT domssl.`id`, domssl.`domainid`, domssl.expirationdate, domssl.`ssl_cert_file`, domssl.`ssl_key_file`, domssl.`ssl_ca_file`, domssl.`ssl_csr_file`, dom.`domain`, dom.`iswildcarddomain`, dom.`wwwserveralias`,
- dom.`documentroot`, dom.`id` as 'domainid', dom.`ssl_redirect`, cust.`leprivatekey`, cust.`lepublickey`, cust.customerid, cust.loginname
- FROM `" . TABLE_PANEL_CUSTOMERS . "` as cust, `" . TABLE_PANEL_DOMAINS . "` dom LEFT JOIN `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` domssl ON (dom.id = domssl.domainid)
- WHERE dom.customerid = cust.customerid AND dom.letsencrypt = 1 AND (domssl.expirationdate < DATE_ADD(NOW(), INTERVAL 30 DAY) OR domssl.expirationdate IS NULL)
-");
+$certificates_stmt = Database::query(
+ "
+ SELECT
+ domssl.`id`,
+ domssl.`domainid`,
+ domssl.expirationdate,
+ domssl.`ssl_cert_file`,
+ domssl.`ssl_key_file`,
+ domssl.`ssl_ca_file`,
+ domssl.`ssl_csr_file`,
+ dom.`domain`,
+ dom.`wwwserveralias`,
+ dom.`documentroot`,
+ dom.`id` AS 'domainid',
+ dom.`ssl_redirect`,
+ cust.`leprivatekey`,
+ cust.`lepublickey`,
+ cust.`customerid`,
+ cust.`loginname`
+ FROM
+ `" . TABLE_PANEL_CUSTOMERS . "` AS cust,
+ `" . TABLE_PANEL_DOMAINS . "` AS dom
+ LEFT JOIN
+ `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` AS domssl ON
+ dom.`id` = domssl.`domainid`
+ WHERE
+ dom.`customerid` = cust.`customerid`
+ AND dom.`letsencrypt` = 1
+ AND dom.`aliasdomain` IS NULL
+ AND dom.`iswildcarddomain` = 0
+ AND (
+ domssl.`expirationdate` < DATE_ADD(NOW(), INTERVAL 30 DAY)
+ OR domssl.`expirationdate` IS NULL
+ )
+ ");
-$updcert_stmt = Database::prepare("
- REPLACE INTO `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` SET `id` = :id, `domainid` = :domainid, `ssl_cert_file` = :crt, `ssl_key_file` = :key, `ssl_ca_file` = :ca, `ssl_cert_chainfile` = :chain, `ssl_csr_file` = :csr, expirationdate = :expirationdate
-");
+$aliasdomains_stmt = Database::prepare(
+ "
+ SELECT
+ dom.`id` as domainid,
+ dom.`domain`,
+ dom.`wwwserveralias`
+ FROM `" . TABLE_PANEL_DOMAINS . "` AS dom
+ WHERE
+ dom.`aliasdomain` = :id
+ AND dom.`letsencrypt` = 1
+ AND dom.`iswildcarddomain` = 0
+ ");
-$upddom_stmt = Database::prepare("
- UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `ssl_redirect` = '1' WHERE `id` = :domainid
-");
+$updcert_stmt = Database::prepare(
+ "
+ REPLACE INTO
+ `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
+ SET
+ `id` = :id,
+ `domainid` = :domainid,
+ `ssl_cert_file` = :crt,
+ `ssl_key_file` = :key,
+ `ssl_ca_file` = :ca,
+ `ssl_cert_chainfile` = :chain,
+ `ssl_csr_file` = :csr,
+ `expirationdate` = :expirationdate
+ ");
+
+$upddom_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `ssl_redirect` = '1' WHERE `id` = :domainid");
$changedetected = 0;
$certrows = $certificates_stmt->fetchAll(PDO::FETCH_ASSOC);
@@ -56,25 +106,27 @@ foreach ($certrows as $certrow) {
if ($certrow['ssl_redirect'] != 2) {
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, "Updating " . $certrow['domain']);
- if ($certrow['ssl_cert_file']) {
- $cronlog->logAction(CRON_ACTION, LOG_DEBUG, "letsencrypt using old key / SAN for " . $certrow['domain']);
- // Parse the old certificate
- $x509data = openssl_x509_parse($certrow['ssl_cert_file']);
+ $cronlog->logAction(CRON_ACTION, LOG_DEBUG, "Adding SAN entry: " . $certrow['domain']);
+ $domains = array(
+ $certrow['domain']
+ );
+ // add www. to SAN list
+ if ($certrow['wwwserveralias'] == 1) {
+ $cronlog->logAction(CRON_ACTION, LOG_DEBUG, "Adding SAN entry: www." . $certrow['domain']);
+ $domains[] = 'www.' . $certrow['domain'];
+ }
- // We are interessted in the old SAN - data
- $san = explode(', ', $x509data['extensions']['subjectAltName']);
- $domains = array();
- foreach ($san as $dnsname) {
- $domains[] = substr($dnsname, 4);
- }
- } else {
- $cronlog->logAction(CRON_ACTION, LOG_DEBUG, "letsencrypt generating new key / SAN for " . $certrow['domain']);
- $domains = array(
- $certrow['domain']
- );
- // Add www. for SAN
- if ($certrow['wwwserveralias'] == 1) {
- $domains[] = 'www.' . $certrow['domain'];
+ // add alias domains (and possibly www.) to SAN list
+ Database::pexecute($aliasdomains_stmt, array(
+ 'id' => $certrow['domainid']
+ ));
+ $aliasdomains = $aliasdomains_stmt->fetchAll(PDO::FETCH_ASSOC);
+ foreach ($aliasdomains as $aliasdomain) {
+ $cronlog->logAction(CRON_ACTION, LOG_DEBUG, "Adding SAN entry: " . $aliasdomain['domain']);
+ $domains[] = $aliasdomain['domain'];
+ if ($aliasdomain['wwwserveralias'] == 1) {
+ $cronlog->logAction(CRON_ACTION, LOG_DEBUG, "Adding SAN entry: www." . $aliasdomain['domain']);
+ $domains[] = 'www.' . $aliasdomain['domain'];
}
}
@@ -92,16 +144,17 @@ foreach ($certrows as $certrow) {
$newcert = openssl_x509_parse($return['crt']);
// Store the new data
- Database::pexecute($updcert_stmt, array(
- 'id' => $certrow['id'],
- 'domainid' => $certrow['domainid'],
- 'crt' => $return['crt'],
- 'key' => $return['key'],
- 'ca' => $return['chain'],
- 'chain' => $return['chain'],
- 'csr' => $return['csr'],
- 'expirationdate' => date('Y-m-d H:i:s', $newcert['validTo_time_t'])
- ));
+ Database::pexecute($updcert_stmt,
+ array(
+ 'id' => $certrow['id'],
+ 'domainid' => $certrow['domainid'],
+ 'crt' => $return['crt'],
+ 'key' => $return['key'],
+ 'ca' => $return['chain'],
+ 'chain' => $return['chain'],
+ 'csr' => $return['csr'],
+ 'expirationdate' => date('Y-m-d H:i:s', $newcert['validTo_time_t'])
+ ));
if ($certrow['ssl_redirect'] == 3) {
Database::pexecute($upddom_stmt, array(
@@ -113,10 +166,12 @@ foreach ($certrows as $certrow) {
$changedetected = 1;
} catch (Exception $e) {
- $cronlog->logAction(CRON_ACTION, LOG_ERR, "Could not get Let's Encrypt certificate for " . $certrow['domain'] . ": " . $e->getMessage());
+ $cronlog->logAction(CRON_ACTION, LOG_ERR,
+ "Could not get Let's Encrypt certificate for " . $certrow['domain'] . ": " . $e->getMessage());
}
} else {
- $cronlog->logAction(CRON_ACTION, LOG_WARNING, "Skipping Let's Encrypt generation for " . $certrow['domain'] . " due to an enabled ssl_redirect");
+ $cronlog->logAction(CRON_ACTION, LOG_WARNING,
+ "Skipping Let's Encrypt generation for " . $certrow['domain'] . " due to an enabled ssl_redirect");
}
}