diff --git a/admin_domains.php b/admin_domains.php index c6f99ea7..6ce5490e 100644 --- a/admin_domains.php +++ b/admin_domains.php @@ -589,6 +589,11 @@ if ($page == 'domains' standard_error('nowildcardwithletsencrypt'); } + // Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated + if ($ssl_redirect > 0 && $letsencrypt == 1) { + $ssl_redirect = 2; + } + if (!preg_match('/^https?\:\/\//', $documentroot)) { if (strstr($documentroot, ":") !== false) { standard_error('pathmaynotcontaincolon'); @@ -1176,8 +1181,8 @@ if ($page == 'domains' $caneditdomain = isset($_POST['caneditdomain']) ? intval($_POST['caneditdomain']) : 0; $registration_date = trim($_POST['registration_date']); $registration_date = validate($registration_date, 'registration_date', '/^(19|20)\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])$/', '', array('0000-00-00', '0', '')); - $termination_date = trim($_POST['termination_date']); - $termination_date = validate($termination_date, 'termination_date', '/^(19|20)\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])$/', '', array('0000-00-00', '0', '')); + $termination_date = trim($_POST['termination_date']); + $termination_date = validate($termination_date, 'termination_date', '/^(19|20)\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])$/', '', array('0000-00-00', '0', '')); $isemaildomain = 0; if (isset($_POST['isemaildomain'])) { @@ -1376,6 +1381,11 @@ if ($page == 'domains' standard_error('nowildcardwithletsencrypt'); } + // Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated + if ($ssl_redirect > 0 && $letsencrypt == 1 && $result['letsencrypt'] != $letsencrypt) { + $ssl_redirect = 2; + } + if (!preg_match('/^https?\:\/\//', $documentroot)) { $documentroot = makeCorrectDir($documentroot); } @@ -1490,7 +1500,8 @@ if ($page == 'domains' 'mod_fcgid_maxrequests' => $mod_fcgid_maxrequests, 'specialsettings' => $specialsettings, 'registration_date' => $registration_date, - 'termination_date' => $termination_date, 'issubof' => $issubof, + 'termination_date' => $termination_date, + 'issubof' => $issubof, 'speciallogfile' => $speciallogfile, 'speciallogverified' => $speciallogverified, 'ipandport' => serialize($ipandports), @@ -1665,7 +1676,7 @@ if ($page == 'domains' $update_data['mod_fcgid_maxrequests'] = $mod_fcgid_maxrequests; $update_data['specialsettings'] = $specialsettings; $update_data['registration_date'] = $registration_date; - $update_data['termination_date'] = $termination_date; + $update_data['termination_date'] = $termination_date; $update_data['ismainbutsubto'] = $issubof; $update_data['letsencrypt'] = $letsencrypt; $update_data['id'] = $id; @@ -1693,7 +1704,7 @@ if ($page == 'domains' `mod_fcgid_maxrequests` = :mod_fcgid_maxrequests, `specialsettings` = :specialsettings, `registration_date` = :registration_date, - `termination_date` = :termination_date, + `termination_date` = :termination_date, `ismainbutsubto` = :ismainbutsubto, `letsencrypt` = :letsencrypt WHERE `id` = :id @@ -1929,6 +1940,11 @@ if ($page == 'domains' } elseif ($result['wwwserveralias'] == '1') { $_value = '1'; } + + // Fudge the result for ssl_redirect to hide the Let's Encrypt steps + $result['temporary_ssl_redirect'] = $result['ssl_redirect']; + $result['ssl_redirect'] = ($result['ssl_redirect'] == 0 ? 0 : 1); + $serveraliasoptions .= makeoption($lng['domains']['serveraliasoption_wildcard'], '0', $_value, true, true); $serveraliasoptions .= makeoption($lng['domains']['serveraliasoption_www'], '1', $_value, true, true); $serveraliasoptions .= makeoption($lng['domains']['serveraliasoption_none'], '2', $_value, true, true); diff --git a/customer_domains.php b/customer_domains.php index 10e9b3af..3f16022c 100644 --- a/customer_domains.php +++ b/customer_domains.php @@ -340,6 +340,11 @@ if ($page == 'overview') { } } + // Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated + if ($ssl_redirect > 0 && $letsencrypt == 1) { + $ssl_redirect = 2; + } + if ($path == '') { standard_error('patherror'); } elseif ($subdomain == '') { @@ -598,6 +603,11 @@ if ($page == 'overview') { $letsencrypt = '0'; } + // Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated + if ($ssl_redirect > 0 && $letsencrypt == 1 && $result['letsencrypt'] != $letsencrypt) { + $ssl_redirect = 2; + } + if ($path == '') { standard_error('patherror'); } else { @@ -715,6 +725,10 @@ if ($page == 'overview') { $ssl_ipsandports = 'notempty'; } + // Fudge the result for ssl_redirect to hide the Let's Encrypt steps + $result['temporary_ssl_redirect'] = $result['ssl_redirect']; + $result['ssl_redirect'] = ($result['ssl_redirect'] == 0 ? 0 : 1); + $openbasedir = makeoption($lng['domain']['docroot'], 0, $result['openbasedir_path'], true) . makeoption($lng['domain']['homedir'], 1, $result['openbasedir_path'], true); // create serveralias options diff --git a/lib/classes/ssl/class.lescript.php b/lib/classes/ssl/class.lescript.php index c219e022..cf2963ee 100644 --- a/lib/classes/ssl/class.lescript.php +++ b/lib/classes/ssl/class.lescript.php @@ -46,6 +46,7 @@ class lescript $ca = 'https://acme-staging.api.letsencrypt.org'; } $this->client = new Client($ca); + $this->log("Using '$ca' to generate certificate"); } public function initAccount($certrow) @@ -368,7 +369,7 @@ keyUsage = nonRepudiation, digitalSignature, keyEncipherment'); protected function log($message) { - fwrite($this->debugHandler, 'letsencrypt ' . $message . "\n"); + $this->debugHandler->logAction(CRON_ACTION, LOG_INFO, "letsencrypt " . $message); } } diff --git a/lib/formfields/admin/domains/formfield.domains_edit.php b/lib/formfields/admin/domains/formfield.domains_edit.php index 566c294a..14d16fce 100644 --- a/lib/formfields/admin/domains/formfield.domains_edit.php +++ b/lib/formfields/admin/domains/formfield.domains_edit.php @@ -124,7 +124,7 @@ return array( 'ssl_redirect' => array( 'visible' => (Settings::Get('system.use_ssl') == '1' ? ($ssl_ipsandports != '' ? true : false) : false), 'label' => $lng['domains']['ssl_redirect']['title'], - 'desc' => $lng['domains']['ssl_redirect']['description'], + 'desc' => $lng['domains']['ssl_redirect']['description'] . ($result['temporary_ssl_redirect'] > 1 ? $lng['domains']['ssl_redirect_temporarilydisabled'] : ''), 'type' => 'checkbox', 'values' => array( array ('label' => $lng['panel']['yes'], 'value' => '1') diff --git a/lib/formfields/customer/domains/formfield.domains_edit.php b/lib/formfields/customer/domains/formfield.domains_edit.php index abd4905a..e7e9f86e 100644 --- a/lib/formfields/customer/domains/formfield.domains_edit.php +++ b/lib/formfields/customer/domains/formfield.domains_edit.php @@ -79,7 +79,7 @@ return array( 'ssl_redirect' => array( 'visible' => (Settings::Get('system.use_ssl') == '1' ? ($ssl_ipsandports != '' ? (domainHasSslIpPort($result['id']) ? true : false) : false) : false), 'label' => $lng['domains']['ssl_redirect']['title'], - 'desc' => $lng['domains']['ssl_redirect']['description'], + 'desc' => $lng['domains']['ssl_redirect']['description'] . ($result['temporary_ssl_redirect'] > 1 ? $lng['domains']['ssl_redirect_temporarilydisabled'] : ''), 'type' => 'checkbox', 'values' => array( array ('label' => $lng['panel']['yes'], 'value' => '1') diff --git a/lng/english.lng.php b/lng/english.lng.php index 0277b0fd..bdc1f5e7 100644 --- a/lng/english.lng.php +++ b/lng/english.lng.php @@ -1941,6 +1941,7 @@ $lng['serversettings']['letsencryptcountrycode']['title'] = "Let's Encrypt count $lng['serversettings']['letsencryptcountrycode']['description'] = "2 letter country code used to generate Let's Encrypt certificates.
ATTENTION:Let's Encrypt is still in beta"; $lng['serversettings']['letsencryptstate']['title'] = "Let's Encrypt state"; $lng['serversettings']['letsencryptstate']['description'] = "State used to generate Let's Encrypt certificates.
ATTENTION:Let's Encrypt is still in beta"; +$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."; // Autoupdate $lng['admin']['autoupdate'] = 'Auto-Update'; @@ -1959,4 +1960,4 @@ $lng['admin']['server_php'] = 'PHP'; // Added for Termination-date $lng['domains']['termination_date'] = 'Date of termination'; -$lng['domains']['termination_date_overview'] = 'canceled until '; \ No newline at end of file +$lng['domains']['termination_date_overview'] = 'canceled until '; diff --git a/lng/german.lng.php b/lng/german.lng.php index 673106f2..b1fab0ec 100644 --- a/lng/german.lng.php +++ b/lng/german.lng.php @@ -1596,6 +1596,7 @@ $lng['serversettings']['letsencryptcountrycode']['title'] = "Let's Encrypt L&aum $lng['serversettings']['letsencryptcountrycode']['description'] = "2 - stelliger Ländercode, welcher benutzt wird um Let's Encrypt - Zertifikate zu bestellen.
ATTENTION:Let's Encrypt befindet sich noch im Test"; $lng['serversettings']['letsencryptstate']['title'] = "Let's Encrypt Bundesland"; $lng['serversettings']['letsencryptstate']['description'] = "Bundesland, welches benutzt wird um Let's Encrypt - Zertifikate zu bestellen.
ATTENTION:Let's Encrypt befindet sich noch im Test"; +$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."; // Added for Termination-date $lng['domains']['termination_date'] = 'Kündigungsdatum'; diff --git a/scripts/jobs/cron_letsencrypt.php b/scripts/jobs/cron_letsencrypt.php index 046d03e7..9240ffc6 100644 --- a/scripts/jobs/cron_letsencrypt.php +++ b/scripts/jobs/cron_letsencrypt.php @@ -18,31 +18,36 @@ * */ -fwrite($debugHandler, "updating let's encrypt certificates\n"); +$cronlog->logAction(CRON_ACTION, LOG_INFO, "Updated Let's Encrypt certificates"); $certificates_stmt = Database::query(" SELECT domssl.`id`, domssl.`domainid`, domssl.expirationdate, domssl.`ssl_cert_file`, domssl.`ssl_key_file`, domssl.`ssl_ca_file`, dom.`domain`, dom.`iswildcarddomain`, dom.`wwwserveralias`, - dom.`documentroot`, dom.`id` as 'domainid', cust.`leprivatekey`, cust.`lepublickey`, cust.customerid + dom.`documentroot`, dom.`id` as 'domainid', dom.`ssl_redirect`, cust.`leprivatekey`, cust.`lepublickey`, cust.customerid 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) "); -$upd_stmt = Database::prepare(" +$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` = :fullchain, expirationdate = :expirationdate "); +$upddom_stmt = Database::prepare(" + UPDATE `".TABLE_PANEL_DOMAINS."` SET `ssl_redirect` = '1' WHERE `id` = :domainid +"); + $changedetected = 0; while ($certrow = $certificates_stmt->fetch(PDO::FETCH_ASSOC)) { // Only renew let's encrypt certificate for domains where a documentroot // already exists if (file_exists($certrow['documentroot']) - && is_dir($certrow['documentroot']) + && is_dir($certrow['documentroot'] + && $certrow['ssl_redirect'] != 2) ) { - fwrite($debugHandler, "updating " . $certrow['domain'] . "\n"); + $cronlog->logAction(CRON_ACTION, LOG_DEBUG, "Updating " . $certrow['domain']); if ($certrow['ssl_cert_file']) { - fwrite($debugHandler, "letsencrypt using old key / SAN for " . $certrow['domain'] . "\n"); + $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']); @@ -53,7 +58,7 @@ while ($certrow = $certificates_stmt->fetch(PDO::FETCH_ASSOC)) { $domains[] = substr($dnsname, 4); } } else { - fwrite($debugHandler, "letsencrypt generating new key / SAN for " . $certrow['domain'] . "\n"); + $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) { @@ -63,7 +68,7 @@ while ($certrow = $certificates_stmt->fetch(PDO::FETCH_ASSOC)) { try { // Initialize Lescript with documentroot - $le = new lescript($certrow['documentroot'], $debugHandler); + $le = new lescript($certrow['documentroot'], $cronlog); // Initialize Lescript $le->initAccount($certrow); @@ -75,7 +80,7 @@ while ($certrow = $certificates_stmt->fetch(PDO::FETCH_ASSOC)) { $newcert = openssl_x509_parse($return['crt']); // Store the new data - Database::pexecute($upd_stmt, array( + Database::pexecute($updcert_stmt, array( 'id' => $certrow['id'], 'domainid' => $certrow['domainid'], 'crt' => $return['crt'], @@ -85,6 +90,13 @@ while ($certrow = $certificates_stmt->fetch(PDO::FETCH_ASSOC)) { 'expirationdate' => date('Y-m-d H:i:s', $newcert['validTo_time_t']) ) ); + + if ($certrow['ssl_redirect'] == 3) { + Database::pexecute($upddom_stmt, array( + 'domainid' => $certrow['domainid'] + ) + ); + } $cronlog->logAction(CRON_ACTION, LOG_INFO, "Updated Let's Encrypt certificate for " . $certrow['domain']); @@ -92,10 +104,11 @@ while ($certrow = $certificates_stmt->fetch(PDO::FETCH_ASSOC)) { } catch (Exception $e) { $cronlog->logAction(CRON_ACTION, LOG_ERR, "Could not get Let's Encrypt certificate for " . $certrow['domain'] . ": " . $e->getMessage()); - fwrite($debugHandler, 'letsencrypt exception: ' . $e->getMessage() . "\n"); } + } elseif ($certrow['ssl_redirect'] == '2') { + $cronlog->logAction(CRON_ACTION, LOG_WARNING, "Skipping Let's Encrypt generation for " . $certrow['ssl_redirect'] . " due to an enabled ssl_redirect"); } else { - fwrite($debugHandler, 'letsencrypt skipped because documentroot ' . $certrow['documentroot'] . ' does not exist' . "\n"); + $cronlog->logAction(CRON_ACTION, LOG_WARNING, "Skipping Let's Encrypt generation for " . $certrow['ssl_redirect'] . " due to a missing documentroot"); } } diff --git a/scripts/jobs/cron_tasks.php b/scripts/jobs/cron_tasks.php index 8d5abaf7..d17c59b3 100644 --- a/scripts/jobs/cron_tasks.php +++ b/scripts/jobs/cron_tasks.php @@ -106,6 +106,9 @@ while ($row = $result_tasks_stmt->fetch(PDO::FETCH_ASSOC)) { } } + // Tell the Let's Encrypt cron it's okay to generate the certificate and enable the redirect afterwards + $upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `ssl_redirect` = '3' WHERE `ssl_redirect` = '2'"); + Database::pexecute($upd_stmt); } /**