Allow selecting new keysize, fixes #1594

Prepare database and cron for HSTS, refs #1593
Added option to re-use key and CSR for Let's Encrypt

Signed-off-by: Florian Aders <eleras@froxlor.org>
This commit is contained in:
Florian Aders
2016-02-19 17:35:44 +01:00
parent e3a594f3e7
commit e621e02f92
18 changed files with 163 additions and 48 deletions

View File

@@ -108,6 +108,32 @@ return array(
'default' => 'Germany',
'save_method' => 'storeSettingField',
),
'system_letsencryptchallengepath' => array(
'label' => $lng['serversettings']['letsencryptchallengepath'],
'settinggroup' => 'system',
'varname' => 'letsencryptchallengepath',
'type' => 'string',
'string_emptyallowed' => false,
'default' => FROXLOR_INSTALL_DIR,
'save_method' => 'storeSettingField',
),
'system_letsencryptkeysize' => array(
'label' => $lng['serversettings']['letsencryptkeysize'],
'settinggroup' => 'system',
'varname' => 'letsencryptkeysize',
'type' => 'int',
'int_min' => 2048,
'default' => 4096,
'save_method' => 'storeSettingField',
),
'system_letsencryptreuseold' => array(
'label' => $lng['serversettings']['letsencryptreuseold'],
'settinggroup' => 'system',
'varname' => 'letsencryptreuseold',
'type' => 'bool',
'default' => false,
'save_method' => 'storeSettingField',
),
)
)
)

View File

@@ -251,6 +251,9 @@ CREATE TABLE `panel_domains` (
`mod_fcgid_maxrequests` int(4) default '-1',
`ismainbutsubto` int(11) unsigned NOT NULL default '0',
`letsencrypt` tinyint(1) NOT NULL default '0',
`hsts` varchar(10) NOT NULL default '0',
`hsts_sub` tinyint(1) NOT NULL default '0',
`hsts_preload` tinyint(1) NOT NULL default '1',
PRIMARY KEY (`id`),
KEY `customerid` (`customerid`),
KEY `parentdomain` (`parentdomainid`),
@@ -518,6 +521,9 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES
('system', 'letsencryptca', 'testing'),
('system', 'letsencryptcountrycode', 'DE'),
('system', 'letsencryptstate', 'Germany'),
('system', 'letsencryptchallengepath', '/var/www/froxlor'),
('system', 'letsencryptkeysize', '4096'),
('system', 'letsencryptreuseold', 0),
('panel', 'decimal_places', '4'),
('panel', 'adminmail', 'admin@SERVERNAME'),
('panel', 'phpmyadmin_url', ''),
@@ -548,7 +554,7 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES
('panel', 'password_numeric', '0'),
('panel', 'password_special_char_required', '0'),
('panel', 'password_special_char', '!?<>§$%+#=@'),
('panel', 'version', '0.9.35-dev4');
('panel', 'version', '0.9.35-dev5');
DROP TABLE IF EXISTS `panel_tasks`;
@@ -832,6 +838,7 @@ CREATE TABLE IF NOT EXISTS `domain_ssl_settings` (
`ssl_key_file` mediumtext NOT NULL,
`ssl_ca_file` mediumtext,
`ssl_cert_chainfile` mediumtext,
`ssl_csr_file` mediumtext,
`expirationdate` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci;

View File

@@ -472,6 +472,8 @@ class FroxlorInstall {
$this->_updateSetting($upd_stmt, '/etc/nginx/nginx.pem', 'system', 'ssl_cert_file');
$this->_updateSetting($upd_stmt, '/var/run/nginx/', 'phpfpm', 'fastcgi_ipcdir');
}
$this->_updateSetting($upd_stmt, dirname(dirname(dirname(__FILE__))), 'system', 'letsencryptchallengepath');
// insert the lastcronrun to be the installation date
$this->_updateSetting($upd_stmt, time(), 'system', 'lastcronrun');

View File

@@ -3079,3 +3079,19 @@ if (isFroxlorVersion('0.9.35-dev3')) {
updateToVersion('0.9.35-dev4');
}
if (isFroxlorVersion('0.9.35-dev4')) {
showUpdateStep("Adding more Let's Encrypt settings");
Settings::AddNew("system.letsencryptchallengepath", FROXLOR_INSTALL_DIR);
Settings::AddNew("system.letsencryptkeysize", '4096');
Settings::AddNew("system.letsencryptreuseold", 0);
Database::query("ALTER TABLE `".TABLE_PANEL_DOMAIN_SSL_SETTINGS."` ADD `ssl_csr_file` MEDIUMTEXT AFTER `ssl_cert_chainfile`;");
Database::query("ALTER TABLE `".TABLE_PANEL_DOMAINS."` ADD `hsts` VARCHAR(10) NOT NULL DEFAULT '0' AFTER `letsencrypt`");
Database::query("ALTER TABLE `".TABLE_PANEL_DOMAINS."` ADD `hsts_sub` TINYINT(1) NOT NULL DEFAULT '0' AFTER `hsts`");
Database::query("ALTER TABLE `".TABLE_PANEL_DOMAINS."` ADD `hsts_preload` TINYINT(1) NOT NULL DEFAULT '1' AFTER `hsts_sub`");
lastStepStatus(0);
updateToVersion('0.9.35-dev5');
}

View File

@@ -75,7 +75,7 @@ class lescript
}
}
public function signDomains(array $domains, $domainkey = null)
public function signDomains(array $domains, $domainkey = null, $csr = null)
{
if (!$this->accountKey) {
@@ -117,7 +117,7 @@ class lescript
// 2. saving authentication token for web verification
// ---------------------------------------------------
$directory = FROXLOR_INSTALL_DIR.'/.well-known/acme-challenge';
$directory = Settings::Get('system.letsencryptchallengepath').'/.well-known/acme-challenge';
$tokenPath = $directory.'/'.$challenge['token'];
if(!file_exists($directory) && !@mkdir($directory, 0755, true)) {
@@ -190,7 +190,7 @@ class lescript
// ----------------------
// generate private key for domain if not exist
if(empty($domainkey)) {
if(empty($domainkey) || Settings::Get('system.letsencryptreuseold') == 0) {
$keys = $this->generateKey();
$domainkey = $keys['private'];
}
@@ -199,11 +199,15 @@ class lescript
$privateDomainKey = openssl_pkey_get_private($domainkey);
$this->client->getLastLinks();
if (empty($csrfile) || Settings::Get('system.letsencryptreuseold') == 0) {
$csr = $this->generateCSR($privateDomainKey, $domains);
}
// request certificates creation
$result = $this->signedRequest(
"/acme/new-cert",
array('resource' => 'new-cert', 'csr' => $this->generateCSR($privateDomainKey, $domains))
array('resource' => 'new-cert', 'csr' => $csr)
);
if ($this->client->getLastCode() !== 201) {
throw new \RuntimeException("Invalid response code: ".$this->client->getLastCode().", ".json_encode($result));
@@ -249,7 +253,7 @@ class lescript
$chain = implode("\n", $certificates);
$this->log("Done, returning new certificates and key");
return array('fullchain' => $fullchain, 'crt' => $crt, 'chain' => $chain, 'key' => $domainkey);
return array('fullchain' => $fullchain, 'crt' => $crt, 'chain' => $chain, 'key' => $domainkey, 'csr' => $csr);
}
private function parsePemFromBody($body)
@@ -281,7 +285,7 @@ class lescript
'HOME = .
RANDFILE = $ENV::HOME/.rnd
[ req ]
default_bits = 4096
default_bits = ' . Settings::Get('system.letsencryptkeysize') . '
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
req_extensions = v3_req
@@ -320,7 +324,7 @@ keyUsage = nonRepudiation, digitalSignature, keyEncipherment');
{
$res = openssl_pkey_new(array(
"private_key_type" => OPENSSL_KEYTYPE_RSA,
"private_key_bits" => 4096,
"private_key_bits" => Settings::Get('system.letsencryptkeysize'),
));
if(!openssl_pkey_export($res, $privateKey)) {

View File

@@ -66,8 +66,8 @@
</file>
<file name="/etc/apache2/modules.d/80_acme.conf">
<content><![CDATA[
Alias "/.well-known/acme-challenge" "{{const.FROXLOR_INSTALL_DIR}}/.well-known/acme-challenge"
<Directory "/var/www/.well-known/acme-challenge">
Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge"
<Directory "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge">
Order allow,deny
Allow from all
</Directory>
@@ -96,8 +96,8 @@ Alias "/.well-known/acme-challenge" "{{const.FROXLOR_INSTALL_DIR}}/.well-known/a
</file>
<file name="/etc/apache2/modules.d/80_acme.conf">
<content><![CDATA[
Alias "/.well-known/acme-challenge" "{{const.FROXLOR_INSTALL_DIR}}/.well-known/acme-challenge"
<Directory "/var/www/.well-known/acme-challenge">
Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge"
<Directory "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge">
Require all granted
</Directory>
]]>
@@ -126,6 +126,7 @@ server.modules = (
"mod_auth",
"mod_fastcgi",
"mod_cgi",
"mod_setenv",
"mod_accesslog"
)
@@ -168,7 +169,7 @@ fastcgi.server = (
)
)
alias.url += ("/.well-known/acme-challenge/" => "{{const.FROXLOR_INSTALL_DIR}}/.well-known/acme-challenge/")
alias.url += ("/.well-known/acme-challenge/" => "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge/")
]]>
</content>
@@ -265,7 +266,7 @@ fastcgi_param REDIRECT_STATUS 200;
<file name="/etc/nginx/conf.d/acme.conf">
<content><![CDATA[
location /.well-known/acme-challenge {
alias {{const.FROXLOR_INSTALL_DIR}};
alias {{settings.system.letsencryptchallengepath}};
location ~ /.well-known/acme-challenge/(.*) {
default_type text/plain;

View File

@@ -41,6 +41,7 @@
<content><![CDATA[mkdir -p {{settings.system.deactivateddocroot}}]]></content>
</command>
<command><![CDATA[a2dismod userdir]]></command>
<command><![CDATA[a2enmod headers]]></command>
</commands>
</general>
<!-- HTTP Apache -->
@@ -69,8 +70,8 @@
</file>
<file name="/etc/apache2/conf-enabled/acme.conf">
<content><![CDATA[
Alias "/.well-known/acme-challenge" "{{const.FROXLOR_INSTALL_DIR}}/.well-known/acme-challenge"
<Directory "/var/www/.well-known/acme-challenge">
Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge"
<Directory "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge">
Require all granted
</Directory>
]]>
@@ -89,6 +90,7 @@ server.modules = (
"mod_compress",
"mod_redirect",
"mod_rewrite",
"mod_setenv",
)
server.document-root = "/var/www"
@@ -107,7 +109,7 @@ static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
compress.cache-dir = "/var/cache/lighttpd/compress/"
compress.filetype = ( "application/javascript", "text/css", "text/html", "text/plain" )
alias.url += ("/.well-known/acme-challenge/" => "{{const.FROXLOR_INSTALL_DIR}}/.well-known/acme-challenge/")
alias.url += ("/.well-known/acme-challenge/" => "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge/")
# default listening port for IPv6 falls back to the IPv4 port
include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
@@ -286,7 +288,7 @@ fastcgi_param REDIRECT_STATUS 200;
<file name="/etc/nginx/conf.d/acme.conf">
<content><![CDATA[
location /.well-known/acme-challenge {
alias {{const.FROXLOR_INSTALL_DIR}};
alias {{settings.system.letsencryptchallengepath}};
location ~ /.well-known/acme-challenge/(.*) {
default_type text/plain;

View File

@@ -41,6 +41,7 @@
<content><![CDATA[mkdir -p {{settings.system.deactivateddocroot}}]]></content>
</command>
<command><![CDATA[a2dismod userdir]]></command>
<command><![CDATA[a2enmod headers]]></command>
</commands>
</general>
<!-- HTTP Apache -->
@@ -67,8 +68,8 @@
</file>
<file name="/etc/apache2/conf-enabled/acme.conf">
<content><![CDATA[
Alias "/.well-known/acme-challenge" "{{const.FROXLOR_INSTALL_DIR}}/.well-known/acme-challenge"
<Directory "/var/www/.well-known/acme-challenge">
Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge"
<Directory "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge">
Order allow,deny
Allow from all
</Directory>
@@ -97,6 +98,7 @@ server.modules = (
"mod_auth",
"mod_fastcgi",
"mod_cgi",
"mod_setenv",
"mod_accesslog"
)
@@ -136,7 +138,7 @@ fastcgi.server = (
)
)
alias.url += ("/.well-known/acme-challenge/" => "{{const.FROXLOR_INSTALL_DIR}}/.well-known/acme-challenge/")
alias.url += ("/.well-known/acme-challenge/" => "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge/")
#### external configuration files
## mimetype mapping
@@ -245,7 +247,7 @@ fastcgi_param REDIRECT_STATUS 200;
<file name="/etc/nginx/conf.d/acme.conf">
<content><![CDATA[
location /.well-known/acme-challenge {
alias {{const.FROXLOR_INSTALL_DIR}};
alias {{settings.system.letsencryptchallengepath}};
location ~ /.well-known/acme-challenge/(.*) {
default_type text/plain;

View File

@@ -41,6 +41,7 @@
<content><![CDATA[mkdir -p {{settings.system.deactivateddocroot}}]]></content>
</command>
<command><![CDATA[a2dismod userdir]]></command>
<command><![CDATA[a2enmod headers]]></command>
</commands>
</general>
<!-- HTTP Apache -->
@@ -49,8 +50,8 @@
<include>//service[@type='http']/general/commands</include>
<file name="/etc/httpd/conf.d/acme.conf">
<content><![CDATA[
Alias "/.well-known/acme-challenge" "{{const.FROXLOR_INSTALL_DIR}}/.well-known/acme-challenge"
<Directory "/var/www/.well-known/acme-challenge">
Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge"
<Directory "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge">
Require all granted
</Directory>
]]>

View File

@@ -41,6 +41,7 @@
<content><![CDATA[mkdir -p {{settings.system.deactivateddocroot}}]]></content>
</command>
<command><![CDATA[a2dismod userdir]]></command>
<command><![CDATA[a2enmod headers]]></command>
</commands>
</general>
<!-- HTTP Apache -->
@@ -67,8 +68,8 @@
</file>
<file name="/etc/apache2/conf-enabled/acme.conf">
<content><![CDATA[
Alias "/.well-known/acme-challenge" "{{const.FROXLOR_INSTALL_DIR}}/.well-known/acme-challenge"
<Directory "/var/www/.well-known/acme-challenge">
Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge"
<Directory "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge">
Order Deny,Allow
Deny from All
</Directory>
@@ -97,8 +98,8 @@ Alias "/.well-known/acme-challenge" "{{const.FROXLOR_INSTALL_DIR}}/.well-known/a
</file>
<file name="/etc/apache2/conf-enabled/acme.conf">
<content><![CDATA[
Alias "/.well-known/acme-challenge" "{{const.FROXLOR_INSTALL_DIR}}/.well-known/acme-challenge"
<Directory "/var/www/.well-known/acme-challenge">
Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge"
<Directory "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge">
Require all granted
</Directory>
]]>
@@ -126,6 +127,7 @@ server.modules = (
"mod_auth",
"mod_fastcgi",
"mod_cgi",
"mod_setenv",
"mod_accesslog"
)
@@ -165,7 +167,7 @@ fastcgi.server = (
)
)
alias.url += ("/.well-known/acme-challenge/" => "{{const.FROXLOR_INSTALL_DIR}}/.well-known/acme-challenge/")
alias.url += ("/.well-known/acme-challenge/" => "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge/")
#### external configuration files
## mimetype mapping
@@ -274,7 +276,7 @@ fastcgi_param REDIRECT_STATUS 200;
<file name="/etc/nginx/conf.d/acme.conf">
<content><![CDATA[
location /.well-known/acme-challenge {
alias {{const.FROXLOR_INSTALL_DIR}};
alias {{settings.system.letsencryptchallengepath}};
location ~ /.well-known/acme-challenge/(.*) {
default_type text/plain;

View File

@@ -41,6 +41,7 @@
<content><![CDATA[mkdir -p {{settings.system.deactivateddocroot}}]]></content>
</command>
<command><![CDATA[a2dismod userdir]]></command>
<command><![CDATA[a2enmod headers]]></command>
</commands>
</general>
<!-- HTTP Apache -->
@@ -67,8 +68,8 @@
</file>
<file name="/etc/apache2/conf-enabled/acme.conf">
<content><![CDATA[
Alias "/.well-known/acme-challenge" "{{const.FROXLOR_INSTALL_DIR}}/.well-known/acme-challenge"
<Directory "/var/www/.well-known/acme-challenge">
Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge"
<Directory "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge">
Order Deny,Allow
Deny from All
</Directory>
@@ -97,8 +98,8 @@ Alias "/.well-known/acme-challenge" "{{const.FROXLOR_INSTALL_DIR}}/.well-known/a
</file>
<file name="/etc/apache2/conf-enabled/acme.conf">
<content><![CDATA[
Alias "/.well-known/acme-challenge" "{{const.FROXLOR_INSTALL_DIR}}/.well-known/acme-challenge"
<Directory "/var/www/.well-known/acme-challenge">
Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge"
<Directory "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge">
Require all granted
</Directory>
]]>
@@ -116,6 +117,7 @@ server.modules = (
"mod_alias",
"mod_compress",
"mod_redirect",
"mod_setenv",
"mod_rewrite",
)
@@ -135,7 +137,7 @@ static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
compress.cache-dir = "/var/cache/lighttpd/compress/"
compress.filetype = ( "application/javascript", "text/css", "text/html", "text/plain" )
alias.url += ("/.well-known/acme-challenge/" => "{{const.FROXLOR_INSTALL_DIR}}/.well-known/acme-challenge/")
alias.url += ("/.well-known/acme-challenge/" => "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge/")
# default listening port for IPv6 falls back to the IPv4 port
include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
@@ -314,7 +316,7 @@ fastcgi_param REDIRECT_STATUS 200;
<file name="/etc/nginx/conf.d/acme.conf">
<content><![CDATA[
location /.well-known/acme-challenge {
alias {{const.FROXLOR_INSTALL_DIR}};
alias {{settings.system.letsencryptchallengepath}};
location ~ /.well-known/acme-challenge/(.*) {
default_type text/plain;

View File

@@ -16,7 +16,7 @@
*/
// Main version variable
$version = '0.9.35-dev4';
$version = '0.9.35-dev5';
// Database version (unused, old stuff from SysCP)
$dbversion = '2';

View File

@@ -1942,6 +1942,12 @@ $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['serversettings']['letsencryptchallengepath']['title'] = "Path for Let's Encrypt challenges";
$lng['serversettings']['letsencryptchallengepath']['description'] = "Directory where the Let's Encrypt challenges should be offered from via a global alias.<br><strong class=\"red\">ATTENTION:</strong>Let's Encrypt is still in beta</strong>";
$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.<br><strong class=\"red\">ATTENTION:</strong>Let's Encrypt is still in beta</strong>";
$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.<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

View File

@@ -1584,20 +1584,26 @@ $lng['admin']['mod_fcgid_umask']['title'] = 'Umask (Standard: 022)';
// Added for let's encrypt
$lng['admin']['letsencrypt']['title'] = 'Benutze Let\'s Encrypt';
$lng['admin']['letsencrypt']['description'] = 'Holt ein kostenloses Zertifikat von <a href="https://letsencrypt.org">Let\'s Encrypt</a>. Das Zertifikat wird automatisch erstellt und verl&auml;nger.<br><strong class="red">ACHTUNG:</strong>Wenn Wildcards aktiviert sind, wird diese Option automatisch deaktiviert. Dieses Feature befindet sich noch im Test.';
$lng['admin']['letsencrypt']['description'] = 'Holt ein kostenloses Zertifikat von <a href="https://letsencrypt.org">Let\'s Encrypt</a>. Das Zertifikat wird automatisch erstellt und verlängert.<br><strong class="red">ACHTUNG:</strong>Wenn Wildcards aktiviert sind, wird diese Option automatisch deaktiviert. Dieses Feature befindet sich noch im Test.';
$lng['customer']['letsencrypt']['title'] = 'Benutze Let\'s Encrypt';
$lng['customer']['letsencrypt']['description'] = 'Holt ein kostenloses Zertifikat von <a href="https://letsencrypt.org">Let\'s Encrypt</a>. Das Zertifikat wird automatisch erstellt und verl&auml;ngert.<br><string class="red">ACHTUNG:</strong>Dieses Feature befindet sich noch im Test.';
$lng['error']['sslredirectonlypossiblewithsslipport'] = 'Die Nutzung von Let\'s Encrypt ist nur m&ouml;glich, wenn die Domain mindestens eine IP/Port - Kombination mit aktiviertem SSL zugewiesen hat.';
$lng['customer']['letsencrypt']['description'] = 'Holt ein kostenloses Zertifikat von <a href="https://letsencrypt.org">Let\'s Encrypt</a>. Das Zertifikat wird automatisch erstellt und verlängert.<br><string class="red">ACHTUNG:</strong>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['panel']['letsencrypt'] = 'Benutzt Let\'s encrypt';
$lng['crondesc']['cron_letsencrypt'] = 'aktualisiert Let\'s Encrypt Zertifikate';
$lng['serversettings']['letsencryptca']['title'] = "Let's Encrypt Umgebung";
$lng['serversettings']['letsencryptca']['description'] = "Let's Encrypt - Umgebung, welche genutzt wird um Zertifikate zu bestellen.<br><strong class=\"red\">ATTENTION:</strong>Let's Encrypt befindet sich noch im Test</strong>";
$lng['serversettings']['letsencryptcountrycode']['title'] = "Let's Encrypt L&auml;ndercode";
$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']['letsencryptca']['description'] = "Let's Encrypt - Umgebung, welche genutzt wird um Zertifikate zu bestellen.<br><strong class=\"red\">ACHTUNG:</strong>Let's Encrypt befindet sich noch im Test";
$lng['serversettings']['letsencryptcountrycode']['title'] = "Let's Encrypt Ländercode";
$lng['serversettings']['letsencryptcountrycode']['description'] = "2 - stelliger Ländercode, welcher benutzt wird um Let's Encrypt - Zertifikate zu bestellen.<br><strong class=\"red\">ACHTUNG:</strong>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.<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.";
$lng['serversettings']['letsencryptstate']['description'] = "Bundesland, welches benutzt wird um Let's Encrypt - Zertifikate zu bestellen.<br><strong class=\"red\">ACHTUNG:</strong>Let's Encrypt befindet sich noch im Test";
$lng['serversettings']['letsencryptchallengepath']['title'] = "Verzeichnis für Let's Encrypt challenges";
$lng['serversettings']['letsencryptchallengepath']['description'] = "Let's Encrypt challenges werden aus diesem Verzeichnis über einen globalen Alias ausgeliefert.<br><strong class=\"red\">ACHTUNG:</strong>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.<br><strong class=\"red\">ACHTUNG:</strong>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 aktiviet ist, werden der alte Schlüssel und CSR bei jeder Verlängerung verwendet, andernfalls wird ein neues Paar generiert.<br><strong class=\"red\">ACHTUNG:</strong>Let's Encrypt befindet sich noch im Test";
$lng['domains']['ssl_redirect_temporarilydisabled'] = "<br>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&uuml;ndigungsdatum';

View File

@@ -21,14 +21,14 @@
$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`,
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
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)
");
$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
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, `ssl_csr_file` = :csr, expirationdate = :expirationdate
");
$upddom_stmt = Database::prepare("
@@ -71,7 +71,7 @@ while ($certrow = $certificates_stmt->fetch(PDO::FETCH_ASSOC)) {
$le->initAccount($certrow);
// Request the new certificate (old key may be used)
$return = $le->signDomains($domains, $certrow['ssl_key_file']);
$return = $le->signDomains($domains, $certrow['ssl_key_file'], $certrow['ssl_csr_file']);
// We are interessted in the expirationdate
$newcert = openssl_x509_parse($return['crt']);
@@ -84,6 +84,7 @@ while ($certrow = $certificates_stmt->fetch(PDO::FETCH_ASSOC)) {
'key' => $return['key'],
'ca' => $return['chain'],
'fullchain' => $return['fullchain'],
'csr' => $return['csr'],
'expirationdate' => date('Y-m-d H:i:s', $newcert['validTo_time_t'])
)
);

View File

@@ -811,6 +811,19 @@ class apache extends HttpConfigBase {
if ($domain['ssl_cert_chainfile'] != '') {
$vhost_content .= ' SSLCertificateChainFile ' . makeCorrectFile($domain['ssl_cert_chainfile']) . "\n";
}
if ($domain['hsts'] > 0) {
$vhost_content .= ' <IfModule mod_headers.c>' . "\n";
$vhost_content .= ' Header always set Strict-Transport-Security "max-age=' . $domain['hsts'];
if ($domain['hsts_sub'] == 1) {
$vhost_content .= '; includeSubdomains';
}
if ($domain['hsts_preload'] == 1) {
$vhost_content .= '; preload';
}
$vhost_content .= '"' . "\n";
$vhost_content .= ' </IfModule>' . "\n";
}
}
else
{

View File

@@ -518,6 +518,18 @@ class lighttpd extends HttpConfigBase {
if ($domain['ssl_ca_file'] != '') {
$ssl_settings.= 'ssl.ca-file = "' . makeCorrectFile($domain['ssl_ca_file']) . '"' . "\n";
}
if ($domain['hsts'] > 0) {
$vhost_content .= '$HTTP["scheme"] == "https" { setenv.add-response-header = ( "Strict-Transport-Security" => "max-age=' . $domain['hsts'];
if ($domain['hsts_sub'] == 1) {
$vhost_content .= '; includeSubdomains';
}
if ($domain['hsts_preload'] == 1) {
$vhost_content .= '; preload';
}
$vhost_content .= '") }' . "\n";
}
}
}
return $ssl_settings;

View File

@@ -591,6 +591,18 @@ class nginx extends HttpConfigBase {
$sslsettings.= "\t" . 'ssl_client_certificate ' . makeCorrectFile($domain_or_ip['ssl_ca_file']) . ';' . "\n";
}
}
if ($domain['hsts'] > 0) {
$vhost_content .= 'add_header Strict-Transport-Security "max-age=' . $domain['hsts'];
if ($domain['hsts_sub'] == 1) {
$vhost_content .= '; includeSubdomains';
}
if ($domain['hsts_preload'] == 1) {
$vhost_content .= '; preload';
}
$vhost_content .= '";' . "\n";
}
}
}