From e1ceb050e19c7574bca146a8da7047ee4ff456b5 Mon Sep 17 00:00:00 2001
From: Marius Burkard <m.burkard@pixcept.de>
Date: Sun, 10 Jul 2016 05:02:35 -0400
Subject: [PATCH] Merge branch 'stable-3.1'
---
server/plugins-available/nginx_plugin.inc.php | 414 +++++++++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 346 insertions(+), 68 deletions(-)
diff --git a/server/plugins-available/nginx_plugin.inc.php b/server/plugins-available/nginx_plugin.inc.php
index 9ce9de8..9933aae 100644
--- a/server/plugins-available/nginx_plugin.inc.php
+++ b/server/plugins-available/nginx_plugin.inc.php
@@ -36,6 +36,7 @@
// private variables
var $action = '';
var $ssl_certificate_changed = false;
+ var $update_letsencrypt = false;
//* This function is called during ispconfig installation to determine
// if a symlink shall be created for this plugin.
@@ -156,10 +157,10 @@
[ req_distinguished_name ]
C = ".trim($data['new']['ssl_country'])."
- ST = ".trim($data['new']['ssl_state'])."
- L = ".trim($data['new']['ssl_locality'])."
- O = ".trim($data['new']['ssl_organisation'])."
- OU = ".trim($data['new']['ssl_organisation_unit'])."
+ " . (trim($data['new']['ssl_state']) == '' ? '' : "ST = ".trim($data['new']['ssl_state'])) . "
+ " . (trim($data['new']['ssl_locality']) == '' ? '' : "L = ".trim($data['new']['ssl_locality']))."
+ " . (trim($data['new']['ssl_organisation']) == '' ? '' : "O = ".trim($data['new']['ssl_organisation']))."
+ " . (trim($data['new']['ssl_organisation_unit']) == '' ? '' : "OU = ".trim($data['new']['ssl_organisation_unit']))."
CN = $domain
emailAddress = webmaster@".$data['new']['domain']."
@@ -219,6 +220,22 @@
$app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
}
+ //* Check that the SSL key is not password protected
+ if($data["new"]["ssl_action"] == 'save') {
+ if(stristr($data["new"]["ssl_key"],'Proc-Type: 4,ENCRYPTED')) {
+ $data["new"]["ssl_action"] = '';
+
+ $app->log('SSL Certificate not saved. The SSL key is encrypted.', LOGLEVEL_WARN);
+ $app->dbmaster->datalogError('SSL Certificate not saved. The SSL key is encrypted.');
+
+ /* Update the DB of the (local) Server */
+ $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
+
+ /* Update also the master-DB of the Server-Farm */
+ $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
+ }
+ }
+
//* Save a SSL certificate to disk
if($data["new"]["ssl_action"] == 'save') {
$this->ssl_certificate_changed = true;
@@ -338,6 +355,7 @@
$data['new'] = $tmp;
$data['old'] = $tmp;
$this->action = 'update';
+ $this->update_letsencrypt = true;
}
// load the server configuration options
@@ -372,6 +390,19 @@
$log_folder = 'log';
$old_web_folder = 'web';
$old_log_folder = 'log';
+ if($data['new']['type'] == 'vhost'){
+ if($data['new']['web_folder'] != ''){
+ if(substr($data['new']['web_folder'],0,1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],1);
+ if(substr($data['new']['web_folder'],-1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],0,-1);
+ }
+ $web_folder .= '/'.$data['new']['web_folder'];
+
+ if($data['old']['web_folder'] != ''){
+ if(substr($data['old']['web_folder'],0,1) == '/') $data['old']['web_folder'] = substr($data['old']['web_folder'],1);
+ if(substr($data['old']['web_folder'],-1) == '/') $data['old']['web_folder'] = substr($data['old']['web_folder'],0,-1);
+ }
+ $old_web_folder .= '/'.$data['old']['web_folder'];
+ }
if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') {
// new one
$tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['new']['parent_domain_id']);
@@ -557,6 +588,7 @@
$app->system->removeLine('/etc/fstab', $fstab_line);
//* Unmount log directory
+ //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder));
exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder));
}
@@ -570,7 +602,8 @@
$app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755);
exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder));
//* add mountpoint to fstab
- $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nobootwait,_netdev 0 0';
+ $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nobootwait';
+ $fstab_line .= @($web_config['network_filesystem'] == 'y')?',_netdev 0 0':' 0 0';
$app->system->replaceLine('/etc/fstab', $fstab_line, $fstab_line, 1, 1);
}
@@ -700,15 +733,33 @@
} // end copy error docs
// Set the quota for the user, but only for vhosts, not vhostsubdomains or vhostalias
- if($username != '' && $app->system->is_user($username) && $data['new']['type'] == 'vhost') {
+ if($username != '' && $app->system->is_user($username) && $data['new']['type'] == 'vhost') {
if($data['new']['hd_quota'] > 0) {
$blocks_soft = $data['new']['hd_quota'] * 1024;
$blocks_hard = $blocks_soft + 1024;
+ $mb_hard = $mb_soft + 1;
} else {
- $blocks_soft = $blocks_hard = 0;
+ $mb_soft = $mb_hard = $blocks_soft = $blocks_hard = 0;
}
- exec("setquota -u $username $blocks_soft $blocks_hard 0 0 -a &> /dev/null");
- exec('setquota -T -u '.$username.' 604800 604800 -a &> /dev/null');
+
+ // get the primitive folder for document_root and the filesystem, will need it later.
+ $df_output=explode(" ", exec("df -T $document_root|awk 'END{print \$2,\$NF}'"));
+ $file_system = $df_output[0];
+ $primitive_root = $df_output[1];
+
+ if ( in_array($file_system , array('ext2','ext3','ext4'), true) ) {
+ exec('setquota -u '. $username . ' ' . $blocks_soft . ' ' . $blocks_hard . ' 0 0 -a &> /dev/null');
+ exec('setquota -T -u '.$username.' 604800 604800 -a &> /dev/null');
+ } elseif ($file_system == 'xfs') {
+
+ exec("xfs_quota -x -c 'limit -g bsoft=$mb_soft" . 'm'. " bhard=$mb_hard" . 'm'. " $username' $primitive_root");
+
+ // xfs only supports timers globally, not per user.
+ exec("xfs_quota -x -c 'timer -bir -i 604800'");
+
+ unset($project_uid, $username_position, $xfs_projects);
+ unset($primitive_root, $df_output, $mb_hard, $mb_soft);
+ }
}
if($this->action == 'insert' || $data["new"]["system_user"] != $data["old"]["system_user"]) {
@@ -726,7 +777,7 @@
if($data['new']['type'] == 'vhost' && $web_config['security_level'] == 20) $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['nginx_user']));
//* If the security level is set to high
- if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost')) {
+ if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost') or ($web_folder != $old_web_folder && $data['new']['type'] == 'vhost')) {
$app->system->web_folder_protection($data['new']['document_root'], false);
@@ -740,6 +791,7 @@
//$app->system->chmod($data['new']['document_root'].'/webdav',0710);
$app->system->chmod($data['new']['document_root'].'/private', 0710);
$app->system->chmod($data['new']['document_root'].'/ssl', 0755);
+ if($web_folder != 'web') $app->system->chmod($data['new']['document_root'].'/'.$web_folder, 0751);
// make tmp directory writable for nginx and the website users
$app->system->chmod($data['new']['document_root'].'/tmp', 0770);
@@ -791,6 +843,11 @@
//$app->system->chgrp($data['new']['document_root'].'/webdav',$groupname);
$app->system->chown($data['new']['document_root'].'/private', $username);
$app->system->chgrp($data['new']['document_root'].'/private', $groupname);
+
+ if($web_folder != 'web'){
+ $app->system->chown($data['new']['document_root'].'/'.$web_folder, $username);
+ $app->system->chgrp($data['new']['document_root'].'/'.$web_folder, $groupname);
+ }
// If the security Level is set to medium
} else {
@@ -800,6 +857,7 @@
//$app->system->chmod($data['new']['document_root'].'/webdav',0755);
$app->system->chmod($data['new']['document_root'].'/ssl', 0755);
$app->system->chmod($data['new']['document_root'].'/cgi-bin', 0755);
+ if($web_folder != 'web') $app->system->chmod($data['new']['document_root'].'/'.$web_folder, 0755);
// make temp directory writable for nginx and the website users
$app->system->chmod($data['new']['document_root'].'/tmp', 0770);
@@ -830,6 +888,11 @@
$app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname);
//$app->system->chown($data['new']['document_root'].'/webdav',$username);
//$app->system->chgrp($data['new']['document_root'].'/webdav',$groupname);
+
+ if($web_folder != 'web'){
+ $app->system->chown($data['new']['document_root'].'/'.$web_folder, $username);
+ $app->system->chgrp($data['new']['document_root'].'/'.$web_folder, $groupname);
+ }
}
} elseif((($data['new']['type'] == 'vhostsubdomain') || ($data['new']['type'] == 'vhostalias')) &&
(($this->action == 'insert') || ($web_config['set_folder_permissions_on_update'] == 'y'))) {
@@ -862,42 +925,7 @@
$app->system->chown('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root');
$app->system->chgrp('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root');
}
-
- // Change the ownership of the error log to the owner of the website
- /*
- if(!@is_file($data['new']['document_root'].'/log/error.log')) exec('touch '.escapeshellcmd($data['new']['document_root']).'/log/error.log');
- $app->system->chown($data['new']['document_root'].'/log/error.log',$username);
- $app->system->chgrp($data['new']['document_root'].'/log/error.log',$groupname);
- */
-
-
- /*
- //* Write the custom php.ini file, if custom_php_ini filed is not empty
- $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$data['new']['system_user'];
- if(!is_dir($web_config['website_basedir'].'/conf')) mkdir($web_config['website_basedir'].'/conf');
- if(trim($data['new']['custom_php_ini']) != '') {
- $has_custom_php_ini = true;
- if(!is_dir($custom_php_ini_dir)) $app->system->mkdirpath($custom_php_ini_dir);
- $php_ini_content = '';
- if($data['new']['php'] == 'mod') {
- $master_php_ini_path = $web_config['php_ini_path_apache'];
- } else {
- if($data["new"]['php'] == 'fast-cgi' && file_exists($fastcgi_config["fastcgi_phpini_path"])) {
- $master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"];
- } else {
- $master_php_ini_path = $web_config['php_ini_path_cgi'];
- }
- }
- if($master_php_ini_path != '' && substr($master_php_ini_path,-7) == 'php.ini' && is_file($master_php_ini_path)) {
- $php_ini_content .= $app->system->file_get_contents($master_php_ini_path)."\n";
- }
- $php_ini_content .= str_replace("\r",'',trim($data['new']['custom_php_ini']));
- $app->system->file_put_contents($custom_php_ini_dir.'/php.ini',$php_ini_content);
- } else {
- $has_custom_php_ini = false;
- if(is_file($custom_php_ini_dir.'/php.ini')) $app->system->unlink($custom_php_ini_dir.'/php.ini');
- }
- */
+
//* Create the vhost config file
$app->load('tpl');
@@ -906,6 +934,7 @@
$tpl->newTemplate('nginx_vhost.conf.master');
// IPv4
+ if($data['new']['ip_address'] == '') $data['new']['ip_address'] = '*';
//* use ip-mapping for web-mirror
if($data['new']['ip_address'] != '*' && $conf['mirror_server_id'] > 0) {
@@ -950,7 +979,7 @@
$default_php_fpm = true;
}
*/
- if($data['new']['php'] != 'no'){
+ if($data['new']['php'] == 'php-fpm' || $data['new']['php'] == 'hhvm'){
if(trim($data['new']['fastcgi_php_version']) != ''){
$default_php_fpm = false;
list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version']));
@@ -1125,12 +1154,70 @@
$nginx_directives = $data['new']['nginx_directives'];
$vhost_data['enable_pagespeed'] = false;
}
+
+ // folder_directive_snippets
+ if(trim($data['new']['folder_directive_snippets']) != ''){
+ $data['new']['folder_directive_snippets'] = trim($data['new']['folder_directive_snippets']);
+ $data['new']['folder_directive_snippets'] = str_replace("\r\n", "\n", $data['new']['folder_directive_snippets']);
+ $data['new']['folder_directive_snippets'] = str_replace("\r", "\n", $data['new']['folder_directive_snippets']);
+ $folder_directive_snippets_lines = explode("\n", $data['new']['folder_directive_snippets']);
+
+ if(is_array($folder_directive_snippets_lines) && !empty($folder_directive_snippets_lines)){
+ foreach($folder_directive_snippets_lines as $folder_directive_snippets_line){
+ list($folder_directive_snippets_folder, $folder_directive_snippets_snippets_id) = explode(':', $folder_directive_snippets_line);
+
+ $folder_directive_snippets_folder = trim($folder_directive_snippets_folder);
+ $folder_directive_snippets_snippets_id = trim($folder_directive_snippets_snippets_id);
+
+ if($folder_directive_snippets_folder != '' && intval($folder_directive_snippets_snippets_id) > 0 && preg_match('@^((?!(.*\.\.)|(.*\./)|(.*//))[^/][\w/_\.\-]{1,100})?$@', $folder_directive_snippets_folder)){
+ if(substr($folder_directive_snippets_folder, -1) != '/') $folder_directive_snippets_folder .= '/';
+ if(substr($folder_directive_snippets_folder, 0, 1) == '/') $folder_directive_snippets_folder = substr($folder_directive_snippets_folder, 1);
+
+ $master_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", intval($folder_directive_snippets_snippets_id));
+ if(isset($master_snippet['snippet'])){
+ $folder_directive_snippets_trans = array('{FOLDER}' => $folder_directive_snippets_folder, '{FOLDERMD5}' => md5($folder_directive_snippets_folder));
+ $master_snippet['snippet'] = strtr($master_snippet['snippet'], $folder_directive_snippets_trans);
+ $nginx_directives .= "\n\n".$master_snippet['snippet'];
+
+ // create folder it it does not exist
+ if(!is_dir($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder)){
+ $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder);
+ $app->system->chown($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder, $username);
+ $app->system->chgrp($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder, $groupname);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // use vLib for template logic
+ if(trim($nginx_directives) != '') {
+ $nginx_directives_new = '';
+ $ngx_conf_tpl = new tpl();
+ $ngx_conf_tpl_tmp_file = tempnam($conf['temppath'], "ngx");
+ file_put_contents($ngx_conf_tpl_tmp_file, $nginx_directives);
+ $ngx_conf_tpl->newTemplate($ngx_conf_tpl_tmp_file);
+ $ngx_conf_tpl->setVar('use_tcp', $use_tcp);
+ $ngx_conf_tpl->setVar('use_socket', $use_socket);
+ $ngx_conf_tpl->setVar('fpm_socket', $fpm_socket);
+ $ngx_conf_tpl->setVar($vhost_data);
+ $nginx_directives_new = $ngx_conf_tpl->grab();
+ if(is_file($ngx_conf_tpl_tmp_file)) unlink($ngx_conf_tpl_tmp_file);
+ if($nginx_directives_new != '') $nginx_directives = $nginx_directives_new;
+ unset($nginx_directives_new);
+ }
+
// Make sure we only have Unix linebreaks
$nginx_directives = str_replace("\r\n", "\n", $nginx_directives);
$nginx_directives = str_replace("\r", "\n", $nginx_directives);
$nginx_directive_lines = explode("\n", $nginx_directives);
if(is_array($nginx_directive_lines) && !empty($nginx_directive_lines)){
- $trans = array('{DOCROOT}' => $vhost_data['web_document_root_www'], '{FASTCGIPASS}' => 'fastcgi_pass '.($data['new']['php_fpm_use_socket'] == 'y'? 'unix:'.$fpm_socket : '127.0.0.1:'.$vhost_data['fpm_port']).';');
+ $trans = array(
+ '{DOCROOT}' => $vhost_data['web_document_root_www'],
+ '{DOCROOT_CLIENT}' => $vhost_data['web_document_root'],
+ '{FASTCGIPASS}' => 'fastcgi_pass '.($data['new']['php_fpm_use_socket'] == 'y'? 'unix:'.$fpm_socket : '127.0.0.1:'.$vhost_data['fpm_port']).';'
+ );
foreach($nginx_directive_lines as $nginx_directive_line){
$final_nginx_directives[] = array('nginx_directive' => strtr($nginx_directive_line, $trans));
}
@@ -1139,9 +1226,149 @@
// Check if a SSL cert exists
$ssl_dir = $data['new']['document_root'].'/ssl';
+ if(!isset($data['new']['ssl_domain']) OR empty($data['new']['ssl_domain'])) { $data['new']['ssl_domain'] = $data['new']['domain']; }
$domain = $data['new']['ssl_domain'];
+ if(!$domain) $domain = $data['new']['domain'];
+ $tpl->setVar('ssl_domain', $domain);
$key_file = $ssl_dir.'/'.$domain.'.key';
$crt_file = $ssl_dir.'/'.$domain.'.crt';
+
+
+ $tpl->setVar('ssl_letsencrypt', "n");
+
+ if($data['new']['ssl'] == 'y' && $data['new']['ssl_letsencrypt'] == 'y') {
+ //* be sure to have good domain
+ if(substr($domain, 0, 2) === '*.') {
+ // wildcard domain not yet supported by letsencrypt!
+ $app->log('Wildcard domains not yet supported by letsencrypt, so changing ' . $domain . ' to ' . substr($domain, 2), LOGLEVEL_WARN);
+ $domain = substr($domain, 2);
+ }
+
+ $data['new']['ssl_domain'] = $domain;
+ $vhost_data['ssl_domain'] = $domain;
+ }
+
+ //* Generate Let's Encrypt SSL certificat
+ if($data['new']['ssl'] == 'y' && $data['new']['ssl_letsencrypt'] == 'y' && ( // ssl and let's encrypt is active
+ ($data['old']['ssl'] == 'n' || $data['old']['ssl_letsencrypt'] == 'n') // we have new let's encrypt configuration
+ || ($data['old']['domain'] != $data['new']['domain']) // we have domain update
+ || ($data['old']['subdomain'] != $data['new']['subdomain']) // we have new or update on "auto" subdomain
+ || $this->update_letsencrypt == true
+ )) {
+ // default values
+ $temp_domains = array();
+ $lddomain = $domain;
+ $subdomains = null;
+ $aliasdomains = null;
+ $sub_prefixes = array();
+
+ //* be sure to have good domain
+ if($data['new']['subdomain'] == "www" OR $data['new']['subdomain'] == "*") {
+ $temp_domains[] = "www." . $domain;
+ }
+
+ //* then, add subdomain if we have
+ $subdomains = $app->db->queryAllRecords('SELECT domain FROM web_domain WHERE parent_domain_id = '.intval($data['new']['domain_id'])." AND active = 'y' AND type = 'subdomain'");
+ if(is_array($subdomains)) {
+ foreach($subdomains as $subdomain) {
+ $temp_domains[] = $subdomain['domain'];
+ $sub_prefixes[] = str_replace($domain, "", $subdomain['domain']);
+ }
+ }
+
+ //* then, add alias domain if we have
+ $aliasdomains = $app->db->queryAllRecords('SELECT domain,subdomain FROM web_domain WHERE parent_domain_id = '.intval($data['new']['domain_id'])." AND active = 'y' AND type = 'alias'");
+ if(is_array($aliasdomains)) {
+ foreach($aliasdomains as $aliasdomain) {
+ $temp_domains[] = $aliasdomain['domain'];
+ if(isset($aliasdomain['subdomain']) && ($aliasdomain['subdomain'] != "none")) {
+ $temp_domains[] = "www." . $aliasdomain['domain'];
+ }
+
+ foreach($sub_prefixes as $s) {
+ $temp_domains[] = $s . $aliasdomain['domain'];
+ }
+ }
+ }
+
+ // prevent duplicate
+ $temp_domains = array_unique($temp_domains);
+
+ // generate cli format
+ foreach($temp_domains as $temp_domain) {
+ $lddomain .= (string) " --domains " . $temp_domain;
+ }
+
+ // useless data
+ unset($subdomains);
+ unset($temp_domains);
+
+ $tpl->setVar('ssl_letsencrypt', "y");
+ //* TODO: check dns entry is correct
+ $crt_tmp_file = "/etc/letsencrypt/live/".$domain."/fullchain.pem";
+ $key_tmp_file = "/etc/letsencrypt/live/".$domain."/privkey.pem";
+ $webroot = $data['new']['document_root']."/web";
+
+ //* check if we have already a Let's Encrypt cert
+ //if(!file_exists($crt_tmp_file) && !file_exists($key_tmp_file)) {
+ // we must not skip if cert exists, otherwise changed domains (alias or sub) won't make it to the cert
+ $app->log("Create Let's Encrypt SSL Cert for: $domain", LOGLEVEL_DEBUG);
+
+ $success = false;
+ $letsencrypt = explode("\n", shell_exec('which letsencrypt certbot /root/.local/share/letsencrypt/bin/letsencrypt'));
+ $letsencrypt = reset($letsencrypt);
+ if(is_executable($letsencrypt)) {
+ $success = $this->_exec($letsencrypt . " certonly -n --text --agree-tos --expand --authenticator webroot --server https://acme-v01.api.letsencrypt.org/directory --rsa-key-size 4096 --email postmaster@$domain --domains $lddomain --webroot-path /usr/local/ispconfig/interface/acme");
+ }
+ if(!$success) {
+ // error issuing cert
+ $app->log('Let\'s Encrypt SSL Cert for: ' . $domain . ' could not be issued.', LOGLEVEL_WARN);
+ $data['new']['ssl_letsencrypt'] = 'n';
+ if($data['old']['ssl'] == 'n') $data['new']['ssl'] = 'n';
+ /* Update the DB of the (local) Server */
+ $app->db->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ?", $data['new']['ssl'], 'n', $data['new']['domain']);
+ /* Update also the master-DB of the Server-Farm */
+ $app->dbmaster->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ?", $data['new']['ssl'], 'n', $data['new']['domain']);
+ }
+ //}
+
+ //* check is been correctly created
+ if(file_exists($crt_tmp_file) OR file_exists($key_tmp_file)) {
+ $date = date("YmdHis");
+ //* TODO: check if is a symlink, if target same keep it, either remove it
+ if(is_file($key_file)) {
+ $app->system->copy($key_file, $key_file.'.old.'.$date);
+ $app->system->chmod($key_file.'.old.'.$date, 0400);
+ $app->system->unlink($key_file);
+ }
+
+ if ($web_config["website_symlinks_rel"] == 'y') {
+ $this->create_relative_link(escapeshellcmd($key_tmp_file), escapeshellcmd($key_file));
+ } else {
+ exec("ln -s ".escapeshellcmd($key_tmp_file)." ".escapeshellcmd($key_file));
+ }
+
+ if(is_file($crt_file)) {
+ $app->system->copy($crt_file, $crt_file.'.old.'.$date);
+ $app->system->chmod($crt_file.'.old.'.$date, 0400);
+ $app->system->unlink($crt_file);
+ }
+
+ if($web_config["website_symlinks_rel"] == 'y') {
+ $this->create_relative_link(escapeshellcmd($crt_tmp_file), escapeshellcmd($crt_file));
+ } else {
+ exec("ln -s ".escapeshellcmd($crt_tmp_file)." ".escapeshellcmd($crt_file));
+ }
+
+ /* we don't need to store it.
+ /* Update the DB of the (local) Server */
+ $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']);
+ $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
+ /* Update also the master-DB of the Server-Farm */
+ $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']);
+ $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
+ }
+ };
if($domain!='' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0) && (@filesize($key_file)>0)) {
$vhost_data['ssl_enabled'] = 1;
@@ -1352,6 +1579,18 @@
'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true),
'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false));
}
+ }
+
+ // http2 or spdy?
+ $vhost_data['enable_http2'] = 'n';
+ if($vhost_data['enable_spdy'] == 'y'){
+ // check if nginx support http_v2; if so, use that instead of spdy
+ exec("2>&1 nginx -V | tr -- - '\n' | grep http_v2_module", $tmp_output, $tmp_retval);
+ if($tmp_retval == 0){
+ $vhost_data['enable_http2'] = 'y';
+ $vhost_data['enable_spdy'] = 'n';
+ }
+ unset($tmp_output, $tmp_retval);
}
$tpl->setVar($vhost_data);
@@ -1880,12 +2119,26 @@
if(is_array($log_folders) && !empty($log_folders)){
foreach($log_folders as $log_folder){
//if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder));
+ //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
}
} else {
//if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder));
+ //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
}
+
+ // remove letsencrypt if it exists (renew will always fail otherwise)
+ $domain = $data['old']['ssl_domain'];
+ if(!$domain) $domain = $data['old']['domain'];
+ if(substr($domain, 0, 2) === '*.') {
+ // wildcard domain not yet supported by letsencrypt!
+ $domain = substr($domain, 2);
+ }
+ //$crt_tmp_file = "/etc/letsencrypt/live/".$domain."/cert.pem";
+ //$key_tmp_file = "/etc/letsencrypt/live/".$domain."/privkey.pem";
+ $le_conf_file = '/etc/letsencrypt/renewal/' . $domain . '.conf';
+ @rename('/etc/letsencrypt/renewal/' . $domain . '.conf', '/etc/letsencrypt/renewal/' . $domain . '.conf~backup');
}
//* remove mountpoint from fstab
@@ -1907,6 +2160,7 @@
$data['new'] = $tmp;
$data['old'] = $tmp;
$this->action = 'update';
+ $this->update_letsencrypt = true;
// just run the update function
$this->update($event_name, $data);
@@ -2017,6 +2271,7 @@
$this->php_fpm_pool_delete($data, $web_config);
} elseif($data['old']['php'] == 'hhvm') {
$this->hhvm_update($data, $web_config);
+ $this->php_fpm_pool_delete($data, $web_config);
}
//remove the php cgi starter script if available
@@ -2387,7 +2642,7 @@
$monit_content = file_get_contents($conf['rootpath'] . '/conf/hhvm_monit.master');
}
- if($data['new']['php'] == 'hhvm' && $data['old']['php'] != 'hhvm' || $data['new']['custom_php_ini'] != $data['old']['custom_php_ini']) {
+ if($data['new']['php'] == 'hhvm' && $data['old']['php'] != 'hhvm' || (isset($data['old']['custom_php_ini']) && isset($data['new']['custom_php_ini']) && $data['new']['custom_php_ini'] != $data['old']['custom_php_ini'])) {
// Custom php.ini settings
$custom_php_ini_settings = trim($data['new']['custom_php_ini']);
@@ -2399,7 +2654,7 @@
foreach($required_php_snippets as $required_php_snippet){
$required_php_snippet = intval($required_php_snippet);
if($required_php_snippet > 0){
- $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet);
+ $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE ".($snippet['master_directive_snippets_id'] > 0 ? 'master_' : '')."directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet);
$php_snippet['snippet'] = trim($php_snippet['snippet']);
if($php_snippet['snippet'] != ''){
$custom_php_ini_settings .= "\n".$php_snippet['snippet'];
@@ -2409,13 +2664,14 @@
}
}
}
+
if($custom_php_ini_settings != ''){
// Make sure we only have Unix linebreaks
$custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings);
$custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings);
file_put_contents('/etc/hhvm/'.$data['new']['system_user'].'.ini', $custom_php_ini_settings);
} else {
- if(is_file('/etc/hhvm/'.$data['old']['system_user'].'.ini')) unlink('/etc/hhvm/'.$data['old']['system_user'].'.ini');
+ if($data['old']['system_user'] != '' && is_file('/etc/hhvm/'.$data['old']['system_user'].'.ini')) unlink('/etc/hhvm/'.$data['old']['system_user'].'.ini');
}
$content = str_replace('{SYSTEM_USER}', $data['new']['system_user'], $content);
@@ -2424,18 +2680,28 @@
exec('/usr/sbin/update-rc.d hhvm_' . $data['new']['system_user'] . ' defaults >/dev/null 2>&1');
exec('/etc/init.d/hhvm_' . $data['new']['system_user'] . ' restart >/dev/null 2>&1');
- $monit_content = str_replace('{SYSTEM_USER}', $data['new']['system_user'], $monit_content);
- file_put_contents('/etc/monit/conf.d/hhvm_' . $data['new']['system_user'], $monit_content);
- exec('/etc/init.d/monit restart >/dev/null 2>&1');
+ if(is_dir('/etc/monit/conf.d')){
+ $monit_content = str_replace('{SYSTEM_USER}', $data['new']['system_user'], $monit_content);
+ file_put_contents('/etc/monit/conf.d/00-hhvm_' . $data['new']['system_user'], $monit_content);
+ if(is_file('/etc/monit/conf.d/hhvm_' . $data['new']['system_user'])) unlink('/etc/monit/conf.d/hhvm_' . $data['new']['system_user']);
+ exec('/etc/init.d/monit restart >/dev/null 2>&1');
+ }
} elseif($data['new']['php'] != 'hhvm' && $data['old']['php'] == 'hhvm') {
- exec('/etc/init.d/hhvm_' . $data['old']['system_user'] . ' stop >/dev/null 2>&1');
- exec('/usr/sbin/update-rc.d hhvm_' . $data['old']['system_user'] . ' remove >/dev/null 2>&1');
- unlink('/etc/init.d/hhvm_' . $data['old']['system_user']);
- if(is_file('/etc/hhvm/'.$data['old']['system_user'].'.ini')) unlink('/etc/hhvm/'.$data['old']['system_user'].'.ini');
+ if($data['old']['system_user'] != ''){
+ exec('/etc/init.d/hhvm_' . $data['old']['system_user'] . ' stop >/dev/null 2>&1');
+ exec('/usr/sbin/update-rc.d hhvm_' . $data['old']['system_user'] . ' remove >/dev/null 2>&1');
+ unlink('/etc/init.d/hhvm_' . $data['old']['system_user']);
+ if(is_file('/etc/hhvm/'.$data['old']['system_user'].'.ini')) unlink('/etc/hhvm/'.$data['old']['system_user'].'.ini');
+ }
- if(is_file('/etc/monit/conf.d/hhvm_' . $data['new']['system_user'])){
- unlink('/etc/monit/conf.d/hhvm_' . $data['new']['system_user']);
+ if(is_file('/etc/monit/conf.d/hhvm_' . $data['old']['system_user']) || is_file('/etc/monit/conf.d/00-hhvm_' . $data['old']['system_user'])){
+ if(is_file('/etc/monit/conf.d/hhvm_' . $data['old']['system_user'])){
+ unlink('/etc/monit/conf.d/hhvm_' . $data['old']['system_user']);
+ }
+ if(is_file('/etc/monit/conf.d/00-hhvm_' . $data['old']['system_user'])){
+ unlink('/etc/monit/conf.d/00-hhvm_' . $data['old']['system_user']);
+ }
exec('/etc/init.d/monit restart >/dev/null 2>&1');
}
}
@@ -2454,7 +2720,8 @@
$default_php_fpm = true;
}
*/
- if($data['new']['php'] != 'no'){
+ // HHVM => PHP-FPM-Fallback
+ if($data['new']['php'] == 'php-fpm' || $data['new']['php'] == 'hhvm'){
if(trim($data['new']['fastcgi_php_version']) != ''){
$default_php_fpm = false;
list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version']));
@@ -2475,7 +2742,8 @@
$app->uses("getconf");
$web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
- if($data['new']['php'] == 'no'){
+ // HHVM => PHP-FPM-Fallback
+ if($data['new']['php'] != 'php-fpm' && $data['new']['php'] != 'hhvm'){
if(@is_file($pool_dir.$pool_name.'.conf')){
$app->system->unlink($pool_dir.$pool_name.'.conf');
//$reload = true;
@@ -2512,7 +2780,7 @@
$tpl->setVar('fpm_pool', $pool_name);
$tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1);
$tpl->setVar('fpm_user', $data['new']['system_user']);
- $tpl->setVar('fpm_group', $data['new']['system_group']);
+ $tpl->setVar('fpm_group', $web_config['group']);
$tpl->setVar('pm', $data['new']['pm']);
$tpl->setVar('pm_max_children', $data['new']['pm_max_children']);
$tpl->setVar('pm_start_servers', $data['new']['pm_start_servers']);
@@ -2543,7 +2811,7 @@
foreach($required_php_snippets as $required_php_snippet){
$required_php_snippet = intval($required_php_snippet);
if($required_php_snippet > 0){
- $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet);
+ $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE ".($snippet['master_directive_snippets_id'] > 0 ? 'master_' : '')."directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet);
$php_snippet['snippet'] = trim($php_snippet['snippet']);
if($php_snippet['snippet'] != ''){
$custom_php_ini_settings .= "\n".$php_snippet['snippet'];
@@ -2554,6 +2822,7 @@
}
}
+ $custom_session_save_path = false;
if($custom_php_ini_settings != ''){
// Make sure we only have Unix linebreaks
$custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings);
@@ -2569,6 +2838,7 @@
$value = trim($value);
if($value != ''){
$key = trim($key);
+ if($key == 'session.save_path') $custom_session_save_path = true;
switch (strtolower($value)) {
case '0':
// PHP-FPM might complain about invalid boolean value if you use 0
@@ -2589,6 +2859,8 @@
}
}
}
+
+ $tpl->setVar('custom_session_save_path', ($custom_session_save_path ? 'y' : 'n'));
$tpl->setLoop('custom_php_ini_settings', $final_php_ini_settings);
@@ -2785,13 +3057,15 @@
} else {
if($islocation){
- if(strpos($l, '{') !== false){
+ $openingbracketpos = strrpos($l, '{');
+ if($openingbracketpos !== false){
$level += 1;
}
- if(strpos($l, '}') !== false && $level > 0){
+ $closingbracketpos = strrpos($l, '}');
+ if($closingbracketpos !== false && $level > 0 && $closingbracketpos >= intval($openingbracketpos)){
$level -= 1;
$locations[$location]['location'] .= $lines[$i]."\n";
- } elseif(strpos($l, '}') !== false && $level == 0){
+ } elseif($closingbracketpos !== false && $level == 0 && $closingbracketpos >= intval($openingbracketpos)){
$islocation = false;
} else {
$locations[$location]['location'] .= $lines[$i]."\n";
@@ -2858,8 +3132,12 @@
//* Wrapper for exec function for easier debugging
private function _exec($command) {
global $app;
+ $out = array();
+ $ret = 0;
$app->log('exec: '.$command, LOGLEVEL_DEBUG);
- exec($command);
+ exec($command, $out, $ret);
+ if($ret != 0) return false;
+ else return true;
}
private function _checkTcp ($host, $port) {
--
Gitblit v1.9.1