added let's encrypt for froxlor vhost - untested for now, testers are welcome

Signed-off-by: Michael Kaufmann (d00p) <d00p@froxlor.org>
This commit is contained in:
Michael Kaufmann (d00p)
2016-09-05 17:01:10 +02:00
parent 290d06e2c4
commit e4887362ec
13 changed files with 524 additions and 351 deletions

View File

@@ -89,6 +89,22 @@ return array(
'cronmodule' => 'froxlor/letsencrypt',
'save_method' => 'storeSettingField'
),
'system_le_froxlor_enabled' => array(
'label' => $lng['serversettings']['le_froxlor_enabled'],
'settinggroup' => 'system',
'varname' => 'le_froxlor_enabled',
'type' => 'bool',
'default' => false,
'save_method' => 'storeSettingField'
),
'system_le_froxlor_redirect' => array(
'label' => $lng['serversettings']['le_froxlor_redirect'],
'settinggroup' => 'system',
'varname' => 'le_froxlor_redirect',
'type' => 'bool',
'default' => false,
'save_method' => 'storeSettingField'
),
'system_letsencryptca' => array(
'label' => $lng['serversettings']['letsencryptca'],
'settinggroup' => 'system',

View File

@@ -102,7 +102,7 @@ return array(
'settinggroup' => 'system',
'varname' => 'mod_fcgid_ownvhost',
'type' => 'bool',
'default' => false,
'default' => true,
'save_method' => 'storeSettingField',
'websrv_avail' => array('apache2')
),

View File

@@ -35,7 +35,7 @@ return array(
'settinggroup' => 'phpfpm',
'varname' => 'enabled_ownvhost',
'type' => 'bool',
'default' => false,
'default' => true,
'save_method' => 'storeSettingField'
),
'system_phpfpm_httpuser' => array(

View File

@@ -521,7 +521,7 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES
('system', 'lepublickey', 'unset'),
('system', 'letsencryptca', 'production'),
('system', 'letsencryptcountrycode', 'DE'),
('system', 'letsencryptstate', 'Germany'),
('system', 'letsencryptstate', 'Hessen'),
('system', 'letsencryptchallengepath', '/var/www/froxlor'),
('system', 'letsencryptkeysize', '4096'),
('system', 'letsencryptreuseold', 0),
@@ -532,6 +532,8 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES
('system', 'apacheglobaldiropt', ''),
('system', 'allow_customer_shell', '0'),
('system', 'available_shells', ''),
('system', 'le_froxlor_enabled', '0'),
('system', 'le_froxlor_redirect', '0'),
('panel', 'decimal_places', '4'),
('panel', 'adminmail', 'admin@SERVERNAME'),
('panel', 'phpmyadmin_url', ''),
@@ -563,7 +565,7 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES
('panel', 'password_special_char_required', '0'),
('panel', 'password_special_char', '!?<>§$%+#=@'),
('panel', 'version', '0.9.37'),
('panel', 'db_version', '201608260');
('panel', 'db_version', '201609050');
DROP TABLE IF EXISTS `panel_tasks`;

View File

@@ -3425,3 +3425,13 @@ if (isDatabaseVersion('201607210')) {
updateToDbVersion('201608260');
}
if (isDatabaseVersion('201608260')) {
showUpdateStep("Adding new settings to use Let's Encrypt for froxlor");
Settings::AddNew("system.le_froxlor_enabled", "0");
Settings::AddNew("system.le_froxlor_redirect", "0");
lastStepStatus(0);
updateToDbVersion('201609050');
}

View File

@@ -53,7 +53,7 @@ class lescript
$this->log("Using '$ca' to generate certificate");
}
public function initAccount($certrow)
public function initAccount($certrow, $isFroxlorVhost = false)
{
// Let's see if we have the private accountkey
$this->accountKey = $certrow['leprivatekey'];
@@ -66,6 +66,10 @@ class lescript
$keys = $this->generateKey();
// Only store the accountkey in production, in staging always generate a new key
if (Settings::Get('system.letsencryptca') == 'production') {
if ($isFroxlorVhost) {
Settings::Set('system.lepublickey', $keys['public']);
Settings::Set('system.leprivatekey', $keys['private']);
} else {
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `lepublickey` = :public, `leprivatekey` = :private " . "WHERE `customerid` = :customerid;");
Database::pexecute($upd_stmt, array(
'public' => $keys['public'],
@@ -73,6 +77,7 @@ class lescript
'customerid' => $certrow['customerid']
));
}
}
$this->accountKey = $keys['private'];
$response = $this->postNewReg();

View File

@@ -19,7 +19,7 @@
$version = '0.9.37';
// Database version (YYYYMMDDC where C is a daily counter)
$dbversion = '201608260';
$dbversion = '201609050';
// Distribution branding-tag (used for Debian etc.)
$branding = '';

View File

@@ -2032,3 +2032,7 @@ $lng['serversettings']['allow_allow_customer_shell']['description'] = '<strong c
$lng['serversettings']['available_shells']['title'] = 'List of available shells';
$lng['serversettings']['available_shells']['description'] = 'Comma seperated list of shells that are available for the customer to chose from for their ftp-users.<br><br>Note that the default shell <strong>/bin/false</strong> will always be a choice (if enabled), even if this setting is empty. It is the default value for ftp-users in any case';
$lng['panel']['shell'] = 'Shell';
$lng['serversettings']['le_froxlor_enabled']['title'] = "Enable Let's Encrypt for the froxlor vhost";
$lng['serversettings']['le_froxlor_enabled']['description'] = "If activated, the froxlor vhost will automatically be secured using a Let's Encrypt certificate.";
$lng['serversettings']['le_froxlor_redirect']['title'] = "Enable SSL-redirect for the froxlor vhost";
$lng['serversettings']['le_froxlor_redirect']['description'] = "If activated, all http requests to your froxlor will be redirected to the corresponding SSL site.";

View File

@@ -1684,3 +1684,7 @@ $lng['serversettings']['allow_allow_customer_shell']['title'] = 'Erlaube Kunden
$lng['serversettings']['allow_allow_customer_shell']['description'] = '<strong class="red">Bitte beachten: Shell Zugriff gestattet dem Benutzer verschiedene Programme auf Ihrem System auszuführen. Mit großer Vorsicht verwenden. Bitte aktiviere dies nur wenn WIRKLICH bekannt ist, was das bedeutet!!!</strong>';
$lng['serversettings']['available_shells']['title'] = 'Liste der verfügbaren Shells';
$lng['serversettings']['available_shells']['description'] = 'Komme-getrennte Liste von Shells die der Kunde für seine FTP-Konten wählen kann.<br><br>Hinweis: Die Standard-Shell <strong>/bin/false</strong> wird immer eine Auswahlmöglichkeit sein (wenn aktiviert), auch wenn diese Einstellung leer ist. Sie ist in jedem Fall der Standardwert für alle FTP-Konten';
$lng['serversettings']['le_froxlor_enabled']['title'] = "Let's Encrypt für den froxlor Vhost verwenden";
$lng['serversettings']['le_froxlor_enabled']['description'] = "Wenn dies aktiviert ist, erstellt froxlor für seinen vhost automatisch ein Let's Encrypt Zertifikat.";
$lng['serversettings']['le_froxlor_redirect']['title'] = "SSL-Weiterleitung für den froxlor Vhost aktivieren";
$lng['serversettings']['le_froxlor_redirect']['description'] = "Wenn dies aktiviert ist, werden alle HTTP Anfragen an die entsprechende SSL Seite weitergeleitet.";

View File

@@ -93,7 +93,99 @@ $updcert_stmt = Database::prepare(
$upddom_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `ssl_redirect` = '1' WHERE `id` = :domainid");
// flag for re-generation of vhost files
$changedetected = 0;
// first - generate LE for system-vhost if enabled
if (Settings::Get('system.le_froxlor_enabled') == '1') {
$certrow = array(
'loginname' => 'froxlor.panel',
'domain' => Settings::Get('system.hostname'),
'domainid' => 0,
'documentroot' => FROXLOR_INSTALL_DIR,
'leprivatekey' => Settings::Get('system.leprivatekey'),
'lepublickey' => Settings::Get('system.lepublickey'),
'ssl_redirect' => Settings::Get('system.le_froxlor_redirect'),
'expirationdate' => null,
'ssl_cert_file' => null,
'ssl_key_file' => null,
'ssl_ca_file' => null,
'ssl_csr_file' => null
);
$froxlor_ssl_settings_stmt = Database::prepare("
SELECT * FROM `".TABLE_PANEL_DOMAIN_SSL_SETTINGS."`
WHERE `domainid` = '0' AND
(`expirationdate` < DATE_ADD(NOW(), INTERVAL 30 DAY) OR `expirationdate` IS NULL)
");
$froxlor_ssl = Database::pexecute_first($froxlor_ssl_settings_stmt);
if ($froxlor_ssl) {
$certrow['id'] = $froxlor_ssl['id'];
$certrow['expirationdate'] = $froxlor_ssl['expirationdate'];
$certrow['ssl_cert_file'] = $froxlor_ssl['ssl_cert_file'];
$certrow['ssl_key_file'] = $froxlor_ssl['ssl_key_file'];
$certrow['ssl_ca_file'] = $froxlor_ssl['ssl_ca_file'];
$certrow['ssl_csr_file'] = $froxlor_ssl['ssl_csr_file'];
}
$domains = array(
$certrow['domain'],
'www.'.$certrow['domain']
);
// Only renew let's encrypt certificate if no broken ssl_redirect is enabled
if ($certrow['ssl_redirect'] != 2) {
$cronlog->logAction(CRON_ACTION, LOG_DEBUG, "Updating " . $certrow['domain']);
$cronlog = FroxlorLogger::getInstanceOf(array(
'loginname' => $certrow['loginname']
));
try {
// Initialize Lescript with documentroot
$le = new lescript($cronlog, $version);
// Initialize Lescript
$le->initAccount($certrow, true);
// Request the new certificate (old key may be used)
$return = $le->signDomains($domains, $certrow['ssl_key_file'], $certrow['ssl_csr_file']);
// We are interessted in the expirationdate
$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'])
));
if ($certrow['ssl_redirect'] == 3) {
Settings::Set('system.le_froxlor_redirect', '1');
}
$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());
}
} else {
$cronlog->logAction(CRON_ACTION, LOG_WARNING,
"Skipping Let's Encrypt generation for " . $certrow['domain'] . " due to an enabled ssl_redirect");
}
}
// customer domains
$certrows = $certificates_stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($certrows as $certrow) {

View File

@@ -363,12 +363,32 @@ class apache extends HttpConfigBase {
$row_ipsandports['ssl_cert_chainfile'] = Settings::Get('system.ssl_cert_chainfile');
}
if ($row_ipsandports['ssl_cert_file'] != '') {
$domain = array(
'id' => 0,
'domain' => Settings::Get('system.hostname'),
'adminid' => 1, /* first admin-user (superadmin) */
'loginname' => 'froxlor.panel',
'documentroot' => $mypath,
);
// override corresponding array values
$domain['ssl_cert_file'] = $row_ipsandports['ssl_cert_file'];
$domain['ssl_key_file'] = $row_ipsandports['ssl_key_file'];
$domain['ssl_ca_file'] = $row_ipsandports['ssl_ca_file'];
$domain['ssl_cert_chainfile'] = $row_ipsandports['ssl_cert_chainfile'];
// SSL STUFF
$dssl = new DomainSSL();
// this sets the ssl-related array-indices in the $domain array
// if the domain has customer-defined ssl-certificates
$dssl->setDomainSSLFilesArray($domain);
if ($domain['ssl_cert_file'] != '') {
// check for existence, #1485
if (!file_exists($row_ipsandports['ssl_cert_file'])) {
$this->logger->logAction(CRON_ACTION, LOG_ERR, $ipport . ' :: certificate file "'.$row_ipsandports['ssl_cert_file'].'" does not exist! Cannot create ssl-directives');
echo $ipport . ' :: certificate file "'.$row_ipsandports['ssl_cert_file'].'" does not exist! Cannot create SSL-directives'."\n";
if (!file_exists($domain['ssl_cert_file'])) {
$this->logger->logAction(CRON_ACTION, LOG_ERR, $ipport . ' :: certificate file "'.$domain['ssl_cert_file'].'" does not exist! Cannot create ssl-directives');
echo $ipport . ' :: certificate file "'.$domain['ssl_cert_file'].'" does not exist! Cannot create SSL-directives'."\n";
} else {
$this->virtualhosts_data[$vhosts_filename] .= ' SSLEngine On' . "\n";
@@ -377,36 +397,36 @@ class apache extends HttpConfigBase {
$this->virtualhosts_data[$vhosts_filename] .= ' SSLHonorCipherOrder On' . "\n";
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCipherSuite ' . Settings::Get('system.ssl_cipher_list') . "\n";
$this->virtualhosts_data[$vhosts_filename] .= ' SSLVerifyDepth 10' . "\n";
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCertificateFile ' . makeCorrectFile($row_ipsandports['ssl_cert_file']) . "\n";
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCertificateFile ' . makeCorrectFile($domain['ssl_cert_file']) . "\n";
if ($row_ipsandports['ssl_key_file'] != '') {
if ($domain['ssl_key_file'] != '') {
// check for existence, #1485
if (!file_exists($row_ipsandports['ssl_key_file'])) {
$this->logger->logAction(CRON_ACTION, LOG_ERR, $ipport . ' :: certificate key file "'.$row_ipsandports['ssl_key_file'].'" does not exist! Cannot create ssl-directives');
echo $ipport . ' :: certificate key file "'.$row_ipsandports['ssl_key_file'].'" does not exist! SSL-directives might not be working'."\n";
if (!file_exists($domain['ssl_key_file'])) {
$this->logger->logAction(CRON_ACTION, LOG_ERR, $ipport . ' :: certificate key file "'.$domain['ssl_key_file'].'" does not exist! Cannot create ssl-directives');
echo $ipport . ' :: certificate key file "'.$domain['ssl_key_file'].'" does not exist! SSL-directives might not be working'."\n";
} else {
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCertificateKeyFile ' . makeCorrectFile($row_ipsandports['ssl_key_file']) . "\n";
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCertificateKeyFile ' . makeCorrectFile($domain['ssl_key_file']) . "\n";
}
}
if ($row_ipsandports['ssl_ca_file'] != '') {
if ($domain['ssl_ca_file'] != '') {
// check for existence, #1485
if (!file_exists($row_ipsandports['ssl_ca_file'])) {
$this->logger->logAction(CRON_ACTION, LOG_ERR, $ipport . ' :: certificate CA file "'.$row_ipsandports['ssl_ca_file'].'" does not exist! Cannot create ssl-directives');
echo $ipport . ' :: certificate CA file "'.$row_ipsandports['ssl_ca_file'].'" does not exist! SSL-directives might not be working'."\n";
if (!file_exists($domain['ssl_ca_file'])) {
$this->logger->logAction(CRON_ACTION, LOG_ERR, $ipport . ' :: certificate CA file "'.$domain['ssl_ca_file'].'" does not exist! Cannot create ssl-directives');
echo $ipport . ' :: certificate CA file "'.$domain['ssl_ca_file'].'" does not exist! SSL-directives might not be working'."\n";
} else {
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCACertificateFile ' . makeCorrectFile($row_ipsandports['ssl_ca_file']) . "\n";
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCACertificateFile ' . makeCorrectFile($domain['ssl_ca_file']) . "\n";
}
}
// #418
if ($row_ipsandports['ssl_cert_chainfile'] != '') {
if ($domain['ssl_cert_chainfile'] != '') {
// check for existence, #1485
if (!file_exists($row_ipsandports['ssl_cert_chainfile'])) {
$this->logger->logAction(CRON_ACTION, LOG_ERR, $ipport . ' :: certificate chain file "'.$row_ipsandports['ssl_cert_chainfile'].'" does not exist! Cannot create ssl-directives');
echo $ipport . ' :: certificate chain file "'.$row_ipsandports['ssl_cert_chainfile'].'" does not exist! SSL-directives might not be working'."\n";
if (!file_exists($domain['ssl_cert_chainfile'])) {
$this->logger->logAction(CRON_ACTION, LOG_ERR, $ipport . ' :: certificate chain file "'.$domain['ssl_cert_chainfile'].'" does not exist! Cannot create ssl-directives');
echo $ipport . ' :: certificate chain file "'.$domain['ssl_cert_chainfile'].'" does not exist! SSL-directives might not be working'."\n";
} else {
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCertificateChainFile ' . makeCorrectFile($row_ipsandports['ssl_cert_chainfile']) . "\n";
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCertificateChainFile ' . makeCorrectFile($domain['ssl_cert_chainfile']) . "\n";
}
}
}
@@ -845,6 +865,9 @@ class apache extends HttpConfigBase {
}
}
// avoid using any whitespaces
$domain['documentroot'] = trim($domain['documentroot']);
if (preg_match('/^https?\:\/\//', $domain['documentroot'])) {
$corrected_docroot = $this->idnaConvert->encode($domain['documentroot']);

View File

@@ -1,4 +1,7 @@
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
<?php
if (! defined('MASTER_CRONJOB'))
die('You cannot access this file directly!');
/**
* This file is part of the Froxlor project.
@@ -15,20 +18,27 @@
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package Cron
*
* @TODO ssl-redirect to non-standard port
* @todo ssl-redirect to non-standard port
*/
require_once (dirname(__FILE__) . '/../classes/class.HttpConfigBase.php');
class lighttpd extends HttpConfigBase {
class lighttpd extends HttpConfigBase
{
private $logger = false;
private $idnaConvert = false;
// protected
protected $lighttpd_data = array();
protected $needed_htpasswds = array();
protected $auth_backend_loaded = false;
protected $htpasswd_files = array();
protected $mod_accesslog_loaded = "0";
/**
@@ -39,13 +49,14 @@ class lighttpd extends HttpConfigBase {
*/
private $_deactivated = false;
public function __construct($logger, $idnaConvert) {
public function __construct($logger, $idnaConvert)
{
$this->logger = $logger;
$this->idnaConvert = $idnaConvert;
}
public function reload() {
public function reload()
{
if ((int) Settings::Get('phpfpm.enabled') == 1) {
$this->logger->logAction(CRON_ACTION, LOG_INFO, 'lighttpd::reload: reloading php-fpm');
safe_exec(escapeshellcmd(Settings::Get('phpfpm.reload')));
@@ -54,8 +65,8 @@ class lighttpd extends HttpConfigBase {
safe_exec(escapeshellcmd(Settings::Get('system.apachereload_command')));
}
public function createIpPort() {
public function createIpPort()
{
$result_ipsandports_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` ORDER BY `ip` ASC, `port` ASC");
while ($row_ipsandports = $result_ipsandports_stmt->fetch(PDO::FETCH_ASSOC)) {
@@ -104,11 +115,12 @@ class lighttpd extends HttpConfigBase {
/**
* dirprotection, see #72
* @TODO use better regex for this, deferred until 0.9.5
*
$this->lighttpd_data[$vhost_filename].= ' $HTTP["url"] =~ "^/(.+)\/(.+)\.php" {' . "\n";
$this->lighttpd_data[$vhost_filename].= ' url.access-deny = ("")' . "\n";
$this->lighttpd_data[$vhost_filename].= ' }' . "\n";
* @todo use better regex for this, deferred until 0.9.5
*
* $this->lighttpd_data[$vhost_filename].= ' $HTTP["url"] =~ "^/(.+)\/(.+)\.php" {' . "\n";
* $this->lighttpd_data[$vhost_filename].= ' url.access-deny = ("")' . "\n";
* $this->lighttpd_data[$vhost_filename].= ' }' . "\n";
*/
/**
@@ -142,13 +154,7 @@ class lighttpd extends HttpConfigBase {
}
if ($row_ipsandports['specialsettings'] != '') {
$this->lighttpd_data[$vhost_filename].= $this->processSpecialConfigTemplate(
$row_ipsandports['specialsettings'],
$domain,
$row_ipsandports['ip'],
$row_ipsandports['port'],
$row_ipsandports['ssl'] == '1'
). "\n";
$this->lighttpd_data[$vhost_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['specialsettings'], $domain, $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n";
}
$this->lighttpd_data[$vhost_filename] .= '}' . "\n";
@@ -163,26 +169,46 @@ class lighttpd extends HttpConfigBase {
$row_ipsandports['ssl_ca_file'] = Settings::Get('system.ssl_ca_file');
}
if ($row_ipsandports['ssl_cert_file'] != '') {
$domain = array(
'id' => 0,
'domain' => Settings::Get('system.hostname'),
'adminid' => 1, /* first admin-user (superadmin) */
'loginname' => 'froxlor.panel',
'documentroot' => $mypath
);
// override corresponding array values
$domain['ssl_cert_file'] = $row_ipsandports['ssl_cert_file'];
$domain['ssl_key_file'] = $row_ipsandports['ssl_key_file'];
$domain['ssl_ca_file'] = $row_ipsandports['ssl_ca_file'];
$domain['ssl_cert_chainfile'] = $row_ipsandports['ssl_cert_chainfile'];
// SSL STUFF
$dssl = new DomainSSL();
// this sets the ssl-related array-indices in the $domain array
// if the domain has customer-defined ssl-certificates
$dssl->setDomainSSLFilesArray($domain);
if ($domain['ssl_cert_file'] != '') {
// check for existence, #1485
if (!file_exists($row_ipsandports['ssl_cert_file'])) {
$this->logger->logAction(CRON_ACTION, LOG_ERR, $ip.':'.$port . ' :: certificate file "'.$row_ipsandports['ssl_cert_file'].'" does not exist! Cannot create ssl-directives');
echo $ip.':'.$port . ' :: certificate file "'.$row_ipsandports['ssl_cert_file'].'" does not exist! Cannot create SSL-directives'."\n";
if (! file_exists($domain['ssl_cert_file'])) {
$this->logger->logAction(CRON_ACTION, LOG_ERR, $ip . ':' . $port . ' :: certificate file "' . $domain['ssl_cert_file'] . '" does not exist! Cannot create ssl-directives');
echo $ip . ':' . $port . ' :: certificate file "' . $domain['ssl_cert_file'] . '" does not exist! Cannot create SSL-directives' . "\n";
} else {
$this->lighttpd_data[$vhost_filename] .= 'ssl.engine = "enable"' . "\n";
$this->lighttpd_data[$vhost_filename] .= 'ssl.use-sslv2 = "disable"' . "\n";
$this->lighttpd_data[$vhost_filename] .= 'ssl.cipher-list = "' . Settings::Get('system.ssl_cipher_list') . '"' . "\n";
$this->lighttpd_data[$vhost_filename] .= 'ssl.honor-cipher-order = "enable"' . "\n";
$this->lighttpd_data[$vhost_filename].= 'ssl.pemfile = "' . makeCorrectFile($row_ipsandports['ssl_cert_file']) . '"' . "\n";
$this->lighttpd_data[$vhost_filename] .= 'ssl.pemfile = "' . makeCorrectFile($domain['ssl_cert_file']) . '"' . "\n";
if ($row_ipsandports['ssl_ca_file'] != '') {
if ($domain['ssl_ca_file'] != '') {
// check for existence, #1485
if (!file_exists($row_ipsandports['ssl_ca_file'])) {
$this->logger->logAction(CRON_ACTION, LOG_ERR, $ip.':'.$port . ' :: certificate CA file "'.$row_ipsandports['ssl_ca_file'].'" does not exist! Cannot create ssl-directives');
echo $ip.':'.port . ' :: certificate CA file "'.$row_ipsandports['ssl_ca_file'].'" does not exist! SSL-directives might not be working'."\n";
if (! file_exists($domain['ssl_ca_file'])) {
$this->logger->logAction(CRON_ACTION, LOG_ERR, $ip . ':' . $port . ' :: certificate CA file "' . $domain['ssl_ca_file'] . '" does not exist! Cannot create ssl-directives');
echo $ip . ':' . port . ' :: certificate CA file "' . $domain['ssl_ca_file'] . '" does not exist! SSL-directives might not be working' . "\n";
} else {
$this->lighttpd_data[$vhost_filename].= 'ssl.ca-file = "' . makeCorrectFile($row_ipsandports['ssl_ca_file']) . '"' . "\n";
$this->lighttpd_data[$vhost_filename] .= 'ssl.ca-file = "' . makeCorrectFile($domain['ssl_ca_file']) . '"' . "\n";
}
}
}
@@ -213,14 +239,12 @@ class lighttpd extends HttpConfigBase {
$this->_createStandardErrorHandler();
}
/**
* define a default server.error-handler-404-statement, bug #unknown-yet
*/
private function _createStandardErrorHandler() {
if (Settings::Get('defaultwebsrverrhandler.enabled') == '1'
&& Settings::Get('defaultwebsrverrhandler.err404') != ''
) {
private function _createStandardErrorHandler()
{
if (Settings::Get('defaultwebsrverrhandler.enabled') == '1' && Settings::Get('defaultwebsrverrhandler.err404') != '') {
$vhost_filename = makeCorrectFile(Settings::Get('system.apacheconf_vhost') . '/05_froxlor_default_errorhandler.conf');
if (! isset($this->lighttpd_data[$vhost_filename])) {
@@ -235,14 +259,16 @@ class lighttpd extends HttpConfigBase {
}
}
protected function create_htaccess($domain) {
protected function create_htaccess($domain)
{
$needed_htpasswds = array();
$result_htpasswds_stmt = Database::prepare("
SELECT * FROM " . TABLE_PANEL_HTPASSWDS . "
WHERE `path` LIKE :docroot
");
Database::pexecute($result_htpasswds_stmt, array('docroot' => $domain['documentroot'] . '%'));
Database::pexecute($result_htpasswds_stmt, array(
'docroot' => $domain['documentroot'] . '%'
));
$htaccess_text = '';
while ($row_htpasswds = $result_htpasswds_stmt->fetch(PDO::FETCH_ASSOC)) {
@@ -283,25 +309,20 @@ class lighttpd extends HttpConfigBase {
return $htaccess_text;
}
public function createVirtualHosts()
{}
public function createVirtualHosts() {
}
public function createFileDirOptions()
{}
protected function composePhpOptions($domain)
{}
public function createFileDirOptions() {
}
protected function composePhpOptions($domain) {
}
public function createOwnVhostStarter() {
}
protected function createLighttpdHosts($ipid, $ssl, $vhost_filename) {
public function createOwnVhostStarter()
{}
protected function createLighttpdHosts($ipid, $ssl, $vhost_filename)
{
$domains = WebserverBase::getVhostsToCreate();
foreach ($domains as $domain) {
@@ -316,21 +337,12 @@ class lighttpd extends HttpConfigBase {
$_inc_path = substr($_tmp_path, $_pos + 1);
// maindomain
if ((int)$domain['parentdomainid'] == 0
&& isCustomerStdSubdomain((int)$domain['id']) == false
&& ((int)$domain['ismainbutsubto'] == 0
|| domainMainToSubExists($domain['ismainbutsubto']) == false)
) {
if ((int) $domain['parentdomainid'] == 0 && isCustomerStdSubdomain((int) $domain['id']) == false && ((int) $domain['ismainbutsubto'] == 0 || domainMainToSubExists($domain['ismainbutsubto']) == false)) {
$vhost_no = '50';
}
// sub-but-main-domain
elseif ((int)$domain['parentdomainid'] == 0
&& isCustomerStdSubdomain((int)$domain['id']) == false
&& (int)$domain['ismainbutsubto'] > 0
) {
} // sub-but-main-domain
elseif ((int) $domain['parentdomainid'] == 0 && isCustomerStdSubdomain((int) $domain['id']) == false && (int) $domain['ismainbutsubto'] > 0) {
$vhost_no = '51';
}
// subdomains
} // subdomains
else {
// number of dots in a domain specifies it's position (and depth of subdomain) starting at 89 going downwards on higher depth
$vhost_no = (string) (90 - substr_count($domain['domain'], ".") + 1);
@@ -348,10 +360,7 @@ class lighttpd extends HttpConfigBase {
$this->lighttpd_data[$vhost_filename] = '';
}
if ((!empty($this->lighttpd_data[$vhost_filename])
&& !is_dir(Settings::Get('system.apacheconf_vhost')))
|| is_dir(Settings::Get('system.apacheconf_vhost'))
) {
if ((! empty($this->lighttpd_data[$vhost_filename]) && ! is_dir(Settings::Get('system.apacheconf_vhost'))) || is_dir(Settings::Get('system.apacheconf_vhost'))) {
if ($ssl == '1') {
$ssl_vhost = true;
$ips_and_ports_index = 'ssl_ipandport';
@@ -370,12 +379,9 @@ class lighttpd extends HttpConfigBase {
return $included_vhosts;
}
protected function getVhostContent($domain, $ssl_vhost = false, $ipid) {
if ($ssl_vhost === true
&& $domain['ssl'] != '1'
&& $domain['ssl_redirect'] != '1'
) {
protected function getVhostContent($domain, $ssl_vhost = false, $ipid)
{
if ($ssl_vhost === true && $domain['ssl'] != '1' && $domain['ssl_redirect'] != '1') {
return '';
}
@@ -383,24 +389,21 @@ class lighttpd extends HttpConfigBase {
$vhost_content .= $this->getServerNames($domain) . " {\n";
// respect ssl_redirect settings, #542
if ($ssl_vhost == false
&& $domain['ssl'] == '1'
&& $domain['ssl_redirect'] == '1'
) {
if ($ssl_vhost == false && $domain['ssl'] == '1' && $domain['ssl_redirect'] == '1') {
// We must not check if our port differs from port 443,
// but if there is a destination-port != 443
$_sslport = '';
// This returns the first port that is != 443 with ssl enabled, if any
// ordered by ssl-certificate (if any) so that the ip/port combo
// with certificate is used
$ssldestport_stmt = Database::prepare(
"SELECT `ip`.`port` FROM ".TABLE_PANEL_IPSANDPORTS." `ip`
$ssldestport_stmt = Database::prepare("SELECT `ip`.`port` FROM " . TABLE_PANEL_IPSANDPORTS . " `ip`
LEFT JOIN `" . TABLE_DOMAINTOIP . "` `dip` ON (`ip`.`id` = `dip`.`id_ipandports`)
WHERE `dip`.`id_domain` = :domainid
AND `ip`.`ssl` = '1' AND `ip`.`port` != 443
ORDER BY `ip`.`ssl_cert_file` DESC, `ip`.`port` LIMIT 1;"
);
$ssldestport = Database::pexecute_first($ssldestport_stmt, array('domainid' => $domain['id']));
ORDER BY `ip`.`ssl_cert_file` DESC, `ip`.`port` LIMIT 1;");
$ssldestport = Database::pexecute_first($ssldestport_stmt, array(
'domainid' => $domain['id']
));
if ($ssldestport['port'] != '') {
$_sslport = ":" . $ssldestport['port'];
@@ -409,19 +412,19 @@ class lighttpd extends HttpConfigBase {
$domain['documentroot'] = 'https://' . $domain['domain'] . $_sslport . '/';
}
// avoid using any whitespaces
$domain['documentroot'] = trim($domain['documentroot']);
if (preg_match('/^https?\:\/\//', $domain['documentroot'])) {
$vhost_content .= ' url.redirect = (' . "\n";
$vhost_content .= ' "^/(.*)$" => "' . $this->idnaConvert->encode($domain['documentroot']) . '$1"' . "\n";
$vhost_content .= ' )' . "\n";
} else {
mkDirWithCorrectOwnership($domain['customerroot'], $domain['documentroot'], $domain['guid'], $domain['guid'], true, true);
$only_webroot = false;
if ($ssl_vhost === false
&& $domain['ssl_redirect'] == '1'
) {
if ($ssl_vhost === false && $domain['ssl_redirect'] == '1') {
$only_webroot = true;
}
@@ -437,7 +440,9 @@ class lighttpd extends HttpConfigBase {
SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "`
WHERE `id` = :id
");
$ipandport = Database::pexecute_first($ipandport_stmt, array('id' => $ipid));
$ipandport = Database::pexecute_first($ipandport_stmt, array(
'id' => $ipid
));
$domain['ip'] = $ipandport['ip'];
$domain['port'] = $ipandport['port'];
@@ -456,30 +461,15 @@ class lighttpd extends HttpConfigBase {
$vhost_content .= $this->getSslSettings($domain, $ssl_vhost);
if ($domain['specialsettings'] != "") {
$vhost_content.= $this->processSpecialConfigTemplate(
$domain['specialsettings'],
$domain,
$domain['ip'],
$domain['port'],
$ssl_vhost). "\n";
$vhost_content .= $this->processSpecialConfigTemplate($domain['specialsettings'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
if ($ipandport['default_vhostconf_domain'] != '') {
$vhost_content.= $this->processSpecialConfigTemplate(
$ipandport['default_vhostconf_domain'],
$domain,
$domain['ip'],
$domain['port'],
$ssl_vhost) . "\n";
$vhost_content .= $this->processSpecialConfigTemplate($ipandport['default_vhostconf_domain'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
if (Settings::Get('system.default_vhostconf') != '') {
$vhost_content.= $this->processSpecialConfigTemplate(
Settings::Get('system.default_vhostconf'),
$domain,
$domain['ip'],
$domain['port'],
$ssl_vhost). "\n";
$vhost_content .= $this->processSpecialConfigTemplate(Settings::Get('system.default_vhostconf'), $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
}
$vhost_content .= $this->getLogFiles($domain);
@@ -491,14 +481,11 @@ class lighttpd extends HttpConfigBase {
return $vhost_content;
}
protected function getSslSettings($domain, $ssl_vhost) {
protected function getSslSettings($domain, $ssl_vhost)
{
$ssl_settings = '';
if ($ssl_vhost === true
&& $domain['ssl'] == '1'
&& (int)Settings::Get('system.use_ssl') == 1
) {
if ($ssl_vhost === true && $domain['ssl'] == '1' && (int) Settings::Get('system.use_ssl') == 1) {
if ($domain['ssl_cert_file'] == '') {
$domain['ssl_cert_file'] = Settings::Get('system.ssl_cert_file');
}
@@ -535,9 +522,8 @@ class lighttpd extends HttpConfigBase {
return $ssl_settings;
}
protected function getLogFiles($domain) {
protected function getLogFiles($domain)
{
$logfiles_text = '';
$speciallogfile = '';
@@ -570,7 +556,9 @@ class lighttpd extends HttpConfigBase {
FROM `" . TABLE_PANEL_DOMAINS . "`
WHERE `aliasdomain` = :domainid OR `parentdomainid` = :domainid
");
Database::pexecute($alias_domains_stmt, array('domainid' => $domain['id']));
Database::pexecute($alias_domains_stmt, array(
'domainid' => $domain['id']
));
while (($alias_domain = $alias_domains_stmt->fetch(PDO::FETCH_ASSOC)) !== false) {
@@ -608,13 +596,15 @@ class lighttpd extends HttpConfigBase {
return $logfiles_text;
}
protected function create_pathOptions($domain) {
protected function create_pathOptions($domain)
{
$result_stmt = Database::prepare("
SELECT * FROM " . TABLE_PANEL_HTACCESS . "
WHERE `path` LIKE :docroot
");
Database::pexecute($result_stmt, array('docroot' => $domain['documentroot'] . '%'));
Database::pexecute($result_stmt, array(
'docroot' => $domain['documentroot'] . '%'
));
$path_options = '';
$error_string = '';
@@ -650,9 +640,7 @@ class lighttpd extends HttpConfigBase {
$path_options = $error_string;
}
if (customerHasPerlEnabled($domain['customerid'])
&& $row['options_cgi'] != '0'
) {
if (customerHasPerlEnabled($domain['customerid']) && $row['options_cgi'] != '0') {
$path = makeCorrectDir(substr($row['path'], strlen($domain['documentroot']) - 1));
mkDirWithCorrectOwnership($domain['documentroot'], $row['path'], $domain['guid'], $domain['guid']);
@@ -672,18 +660,18 @@ class lighttpd extends HttpConfigBase {
return $path_options;
}
protected function getDirOptions($domain) {
protected function getDirOptions($domain)
{
$result_stmt = Database::prepare("
SELECT * FROM " . TABLE_PANEL_HTPASSWDS . "
WHERE `customerid` = :customerid
");
Database::pexecute($result_stmt, array('customerid' => $domain['customerid']));
Database::pexecute($result_stmt, array(
'customerid' => $domain['customerid']
));
while ($row_htpasswds = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
if ($auth_backend_loaded[$domain['ipandport']] != 'yes'
&& $auth_backend_loaded[$domain['ssl_ipandport']] != 'yes'
) {
if ($auth_backend_loaded[$domain['ipandport']] != 'yes' && $auth_backend_loaded[$domain['ssl_ipandport']] != 'yes') {
$filename = $domain['customerid'] . '.htpasswd';
if ($this->auth_backend_loaded[$domain['ipandport']] != 'yes') {
@@ -722,8 +710,8 @@ class lighttpd extends HttpConfigBase {
return ' auth.backend.htpasswd.userfile = "' . makeCorrectFile(Settings::Get('system.apacheconf_htpasswddir') . '/' . $filename) . '"' . "\n";
}
protected function getServerNames($domain) {
protected function getServerNames($domain)
{
$server_string = array();
$domain_name = str_replace('.', '\.', $domain['domain']);
@@ -742,7 +730,9 @@ class lighttpd extends HttpConfigBase {
FROM `" . TABLE_PANEL_DOMAINS . "`
WHERE `aliasdomain` = :domainid
");
Database::pexecute($alias_domains_stmt, array('domainid' => $domain['id']));
Database::pexecute($alias_domains_stmt, array(
'domainid' => $domain['id']
));
while (($alias_domain = $alias_domains_stmt->fetch(PDO::FETCH_ASSOC)) !== false) {
$alias_domain_name = str_replace('.', '\.', $alias_domain['domain']);
@@ -785,20 +775,16 @@ class lighttpd extends HttpConfigBase {
return $servernames_text;
}
protected function getWebroot($domain, $ssl) {
protected function getWebroot($domain, $ssl)
{
$webroot_text = '';
if ($domain['deactivated'] == '1'
&& Settings::Get('system.deactivateddocroot') != ''
) {
if ($domain['deactivated'] == '1' && Settings::Get('system.deactivateddocroot') != '') {
$webroot_text .= ' # Using docroot for deactivated users...' . "\n";
$webroot_text .= ' server.document-root = "' . makeCorrectDir(Settings::Get('system.deactivateddocroot')) . "\"\n";
$this->_deactivated = true;
} else {
if ($ssl === false
&& $domain['ssl_redirect'] == '1'
) {
if ($ssl === false && $domain['ssl_redirect'] == '1') {
$redirect_domain = $this->idnaConvert->encode('https://' . $domain['domain']);
$webroot_text .= ' url.redirect = (' . "\n";
$webroot_text .= "\t" . '"^/(.*)" => "' . $redirect_domain . '/$1",' . "\n";
@@ -821,11 +807,11 @@ class lighttpd extends HttpConfigBase {
return $webroot_text;
}
/**
* Lets set the text part for the stats software
*/
protected function getStats($domain) {
protected function getStats($domain)
{
$stats_text = '';
if ($domain['speciallogfile'] == '1') {
@@ -852,8 +838,7 @@ class lighttpd extends HttpConfigBase {
} else {
$stats_text .= ' alias.url = ( "/webalizer/" => "' . makeCorrectFile($domain['customerroot'] . '/webalizer/') . '" )' . "\n";
}
}
// if the docroots are equal, we still have to set an alias for awstats
} // if the docroots are equal, we still have to set an alias for awstats
// because the stats are in /awstats/[domain], not just /awstats/
// also, the awstats-icons are someplace else too!
// -> webalizer does not need this!
@@ -866,8 +851,8 @@ class lighttpd extends HttpConfigBase {
return $stats_text;
}
public function writeConfigs() {
public function writeConfigs()
{
$this->logger->logAction(CRON_ACTION, LOG_INFO, "lighttpd::writeConfigs: rebuilding " . Settings::Get('system.apacheconf_vhost'));
$vhostDir = new frxDirectory(Settings::Get('system.apacheconf_vhost'));

View File

@@ -150,6 +150,35 @@ class nginx extends HttpConfigBase {
if ($row_ipsandports['ssl_cert_file'] != '' && file_exists($row_ipsandports['ssl_cert_file'])) {
$ssl_vhost = true;
}
$domain = array(
'id' => 0,
'domain' => Settings::Get('system.hostname'),
'adminid' => 1, /* first admin-user (superadmin) */
'loginname' => 'froxlor.panel',
'documentroot' => $mypath
);
// override corresponding array values
$domain['ssl_cert_file'] = $row_ipsandports['ssl_cert_file'];
$domain['ssl_key_file'] = $row_ipsandports['ssl_key_file'];
$domain['ssl_ca_file'] = $row_ipsandports['ssl_ca_file'];
$domain['ssl_cert_chainfile'] = $row_ipsandports['ssl_cert_chainfile'];
// SSL STUFF
$dssl = new DomainSSL();
// this sets the ssl-related array-indices in the $domain array
// if the domain has customer-defined ssl-certificates
$dssl->setDomainSSLFilesArray($domain);
if ($domain['ssl_cert_file'] != '' && file_exists($domain['ssl_cert_file'])) {
// override corresponding array values
$row_ipsandports['ssl_cert_file'] = $domain['ssl_cert_file'];
$row_ipsandports['ssl_key_file'] = $domain['ssl_key_file'];
$row_ipsandports['ssl_ca_file'] = $domain['ssl_ca_file'];
$row_ipsandports['ssl_cert_chainfile'] = $domain['ssl_cert_chainfile'];
$ssl_vhost = true;
}
}
/**
@@ -415,6 +444,9 @@ class nginx extends HttpConfigBase {
$domain['documentroot'] = 'https://' . $domain['domain'] . $_sslport . '/';
}
// avoid using any whitespaces
$domain['documentroot'] = trim($domain['documentroot']);
// create ssl settings first since they are required for normal and redirect vhosts
if ($ssl_vhost === true
&& $domain['ssl'] == '1'