Temporarily deactivate ssl_redirect if a new Let's Encrypt certificate needs to be generated

Signed-off-by: Florian Aders <eleras@froxlor.org>
This commit is contained in:
Florian Aders
2016-02-16 14:31:07 +01:00
parent f65af0067d
commit ddaadf81d6
9 changed files with 69 additions and 20 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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')

View File

@@ -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')

View File

@@ -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.<br><strong class=\"red\">ATTENTION:</strong>Let's Encrypt is still in beta</strong>";
$lng['serversettings']['letsencryptstate']['title'] = "Let's Encrypt state";
$lng['serversettings']['letsencryptstate']['description'] = "State used to generate Let's Encrypt certificates.<br><strong class=\"red\">ATTENTION:</strong>Let's Encrypt is still in beta</strong>";
$lng['domains']['ssl_redirect_temporarilydisabled'] = "<br>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';

View File

@@ -1596,6 +1596,7 @@ $lng['serversettings']['letsencryptcountrycode']['title'] = "Let's Encrypt L&aum
$lng['serversettings']['letsencryptcountrycode']['description'] = "2 - stelliger L&auml;ndercode, welcher benutzt wird um Let's Encrypt - Zertifikate zu bestellen.<br><strong class=\"red\">ATTENTION:</strong>Let's Encrypt befindet sich noch im Test</strong>";
$lng['serversettings']['letsencryptstate']['title'] = "Let's Encrypt Bundesland";
$lng['serversettings']['letsencryptstate']['description'] = "Bundesland, welches benutzt wird um Let's Encrypt - Zertifikate zu bestellen.<br><strong class=\"red\">ATTENTION:</strong>Let's Encrypt befindet sich noch im Test</strong>";
$lng['domains']['ssl_redirect_temporarilydisabled'] = "<br>Die SSL-Umleitung ist, w&auml;hrend ein neues Let's Encrypt - Zertifikat erstellt wird, tempor&auml;r deaktiviert. Die Umleitung wird nach der Zertifikatserstellung wieder aktiviert.";
// Added for Termination-date
$lng['domains']['termination_date'] = 'K&uuml;ndigungsdatum';

View File

@@ -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.<domain> 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'],
@@ -86,16 +91,24 @@ while ($certrow = $certificates_stmt->fetch(PDO::FETCH_ASSOC)) {
)
);
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']);
$changedetected = 1;
} 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");
}
}

View File

@@ -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);
}
/**