From b81daafdcd18f4b8a3d0beebc8202160274156da Mon Sep 17 00:00:00 2001 From: dachris1 Date: Tue, 15 Nov 2022 20:01:29 +0100 Subject: [PATCH 1/4] added gentoo specific code to keep symlinks in _getinitcommand server/lib/classes/system.inc.php added gentoo specific code to keep symlinks as init script. gentoo uses symlinks to start different php-fpm versions, but "realpath" kills these symlinks. --- server/lib/classes/system.inc.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/server/lib/classes/system.inc.php b/server/lib/classes/system.inc.php index 7e4e7ae447..f122448839 100644 --- a/server/lib/classes/system.inc.php +++ b/server/lib/classes/system.inc.php @@ -2132,6 +2132,26 @@ class system{ } $full_init_script_path = realpath($init_script_directory.'/'.$servicename); + + //** Gentoo, keep symlink as init script, but do some checks + if(file_exists('/etc/gentoo-release')) { + //* check if init script is symlink + if(is_link($init_script_directory.'/'.$servicename)) { + //* Check init script owner (realpath, symlink is checked later) + if(fileowner($full_init_script_path) !== 0) { + $app->log('Init script '.$full_init_script_path.' not owned by root user',LOGLEVEL_WARN); + return false; + } + + //* full path is symlink + $full_init_script_path_symlink = $init_script_directory.'/'.$servicename; + + //* check if realpath matches symlink + if(strpos($full_init_script_path_symlink,$full_init_script_path) == 0) { + $full_init_script_path = $full_init_script_path_symlink; + } + } + } if($full_init_script_path == '') { $app->log('No init script, we quit here.',LOGLEVEL_WARN); -- GitLab From 98f84fedc3d8711a9722c34926c8a6ff973cfb12 Mon Sep 17 00:00:00 2001 From: dachris1 Date: Tue, 15 Nov 2022 20:05:37 +0100 Subject: [PATCH 2/4] updated/added functions install/dist/lib/gentoo.lib.php updated functions: configure_postfix configure_dovecot install_ispconfig added configuration for pureftpd versions greater than 1.0.50 added function get_host_ips() because gentoo does not provide IPs with "hostname --all-ip-addresses" --- install/dist/lib/gentoo.lib.php | 695 +++++++++++++++++++++++--------- 1 file changed, 500 insertions(+), 195 deletions(-) diff --git a/install/dist/lib/gentoo.lib.php b/install/dist/lib/gentoo.lib.php index c98788e33c..8c942f2491 100644 --- a/install/dist/lib/gentoo.lib.php +++ b/install/dist/lib/gentoo.lib.php @@ -47,8 +47,7 @@ class installer extends installer_base caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); } - public function configure_postfix($options = '') - { + public function configure_postfix($options = '') { global $conf,$autoinstall; $cf = $conf['postfix']; @@ -57,6 +56,11 @@ class installer extends installer_base if(!is_dir($config_dir)){ $this->error("The postfix configuration directory '$config_dir' does not exist."); } + + //* Get postfix version + exec('postconf -d mail_version 2>&1', $out); + $postfix_version = preg_replace('/.*=\s*/', '', $out[0]); + unset($out); //* Install virtual mappings foreach (glob('tpl/mysql-virtual_*.master') as $filename) { @@ -65,30 +69,48 @@ class installer extends installer_base //* mysql-verify_recipients.cf $this->process_postfix_config('mysql-verify_recipients.cf'); + + // test if lmtp if available + $configure_lmtp = $this->get_postfix_service('lmtp','unix'); + //* postfix-dkim + $filename='tag_as_originating.re'; + $full_file_name=$config_dir.'/'.$filename; + if(is_file($full_file_name)) copy($full_file_name, $full_file_name.'~'); + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/postfix-'.$filename.'.master', 'tpl/postfix-'.$filename.'.master'); + if($configure_lmtp) { + $content = preg_replace('/amavis:/', 'lmtp:', $content); + } + wf($full_file_name, $content); + + $filename='tag_as_foreign.re'; + $full_file_name=$config_dir.'/'.$filename; + if(is_file($full_file_name)) copy($full_file_name, $full_file_name.'~'); + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/postfix-'.$filename.'.master', 'tpl/postfix-'.$filename.'.master'); + if($configure_lmtp) { + $content = preg_replace('/amavis:/', 'lmtp:', $content); + } + wf($full_file_name, $content); + //* Changing mode and group of the new created config files. - caselog('chmod o= '.$config_dir.'/mysql-virtual_*.cf* &> /dev/null', + /*caselog('chmod o= '.$config_dir.'/mysql-virtual_*.cf* &> /dev/null', __FILE__, __LINE__, 'chmod on mysql-virtual_*.cf*', 'chmod on mysql-virtual_*.cf* failed'); caselog('chgrp '.$cf['group'].' '.$config_dir.'/mysql-virtual_*.cf* &> /dev/null', - __FILE__, __LINE__, 'chgrp on mysql-virtual_*.cf*', 'chgrp on mysql-virtual_*.cf* failed'); + __FILE__, __LINE__, 'chgrp on mysql-virtual_*.cf*', 'chgrp on mysql-virtual_*.cf* failed');*/ //* Creating virtual mail user and group $command = 'groupadd -g '.$cf['vmail_groupid'].' '.$cf['vmail_groupname']; - if (!is_group($cf['vmail_groupname'])) { - caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); - } + if(!is_group($cf['vmail_groupname'])) caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); $command = 'useradd -g '.$cf['vmail_groupname'].' -u '.$cf['vmail_userid'].' '.$cf['vmail_username'].' -d '.$cf['vmail_mailbox_base'].' -m'; - if (!is_user($cf['vmail_username'])) { - caselog("$command &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); - } + if(!is_user($cf['vmail_username'])) caselog("$command &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); //* These postconf commands will be executed on installation and update $server_ini_rec = $this->db->queryOneRecord("SELECT config FROM ?? WHERE server_id = ?", $conf["mysql"]["database"].'.server', $conf['server_id']); $server_ini_array = ini_to_array(stripslashes($server_ini_rec['config'])); unset($server_ini_rec); - //* If there are RBL's defined, format the list and add them to smtp_recipient_restrictions to prevent removeal after an update + //* If there are RBL's defined, format the list and add them to smtp_recipient_restrictions to prevent removal after an update $rbl_list = ''; if (@isset($server_ini_array['mail']['realtime_blackhole_list']) && $server_ini_array['mail']['realtime_blackhole_list'] != '') { $rbl_hosts = explode(",", str_replace(" ", "", $server_ini_array['mail']['realtime_blackhole_list'])); @@ -107,7 +129,7 @@ class installer extends installer_base $reject_sender_login_mismatch = ''; $reject_authenticated_sender_login_mismatch = ''; if(isset($server_ini_array['mail']['reject_sender_login_mismatch']) && ($server_ini_array['mail']['reject_sender_login_mismatch'] == 'y')) { - $reject_sender_login_mismatch = ', reject_sender_login_mismatch'; + $reject_sender_login_mismatch = ',reject_sender_login_mismatch,'; $reject_authenticated_sender_login_mismatch = 'reject_authenticated_sender_login_mismatch, '; } @@ -145,7 +167,42 @@ class installer extends installer_base $postconf_tpl = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/gentoo_postfix.conf.master', 'tpl/gentoo_postfix.conf.master'); $postconf_tpl = strtr($postconf_tpl, $postconf_placeholders); $postconf_commands = array_filter(explode("\n", $postconf_tpl)); // read and remove empty lines - + + //* Merge version-specific postfix config + if(version_compare($postfix_version , '2.5', '>=')) { + $configfile = 'postfix_2-5.conf'; + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master'); + $content = strtr($content, $postconf_placeholders); + $postconf_commands = array_merge($postconf_commands, array_filter(explode("\n", $content))); + } + if(version_compare($postfix_version , '2.10', '>=')) { + $configfile = 'postfix_2-10.conf'; + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master'); + $content = strtr($content, $postconf_placeholders); + $postconf_commands = array_merge($postconf_commands, array_filter(explode("\n", $content))); + } + if(version_compare($postfix_version , '3.0', '>=')) { + $configfile = 'postfix_3-0.conf'; + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master'); + $content = strtr($content, $postconf_placeholders); + $postconf_commands = array_merge($postconf_commands, array_filter(explode("\n", $content))); + } + if(version_compare($postfix_version , '3.3', '>=')) { + $configfile = 'postfix_3-3.conf'; + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master'); + $content = strtr($content, $postconf_placeholders); + $postconf_commands = array_merge($postconf_commands, array_filter(explode("\n", $content))); + } + $configfile = 'postfix_custom.conf'; + if(file_exists($conf['ispconfig_install_dir'].'/server/conf-custom/install/' . $configfile . '.master')) { + $content = file_get_contents($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master'); + $content = strtr($content, $postconf_placeholders); + $postconf_commands = array_merge($postconf_commands, array_filter(explode("\n", $content))); + } + + // Remove comment lines, these would give fatal errors when passed to postconf. + $postconf_commands = array_filter($postconf_commands, function($line) { return preg_match('/^[^#]/', $line); }); + //* These postconf commands will be executed on installation only if($this->is_update == false) { $postconf_commands = array_merge($postconf_commands, array( @@ -161,6 +218,15 @@ class installer extends installer_base touch($config_dir.'/nested_header_checks'); touch($config_dir.'/body_checks'); touch($config_dir.'/sasl_passwd'); + + //* Create the mailman files + if(!is_dir('/var/lib/mailman/data')) exec('mkdir -p /var/lib/mailman/data'); + if(!is_file('/var/lib/mailman/data/aliases')) touch('/var/lib/mailman/data/aliases'); + exec('postalias /var/lib/mailman/data/aliases'); + if(!is_file('/var/lib/mailman/data/virtual-mailman')) touch('/var/lib/mailman/data/virtual-mailman'); + exec('postmap /var/lib/mailman/data/virtual-mailman'); + if(!is_file('/var/lib/mailman/data/transport-mailman')) touch('/var/lib/mailman/data/transport-mailman'); + exec('/usr/sbin/postmap /var/lib/mailman/data/transport-mailman'); //* Create auxillary postfix conf files $configfile = 'helo_access'; @@ -189,13 +255,13 @@ class installer extends installer_base //* Executing the postconf commands foreach($postconf_commands as $cmd) { $command = "postconf -e '$cmd'"; - caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command); + swriteln($command); + caselog($command." &> /dev/null", __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command); } - - //* Create the SSL certificate - if (!stristr($options, 'dont-create-certs')) - { - if(AUTOINSTALL){ + + if (!stristr($options, 'dont-create-certs')){ + //* Create the SSL certificate + if(AUTOINSTALL){ $command = 'cd '.$config_dir.'; ' ."openssl req -new -subj '/C=".escapeshellcmd($autoinstall['ssl_cert_country'])."/ST=".escapeshellcmd($autoinstall['ssl_cert_state'])."/L=".escapeshellcmd($autoinstall['ssl_cert_locality'])."/O=".escapeshellcmd($autoinstall['ssl_cert_organisation'])."/OU=".escapeshellcmd($autoinstall['ssl_cert_organisation_unit'])."/CN=".escapeshellcmd($autoinstall['ssl_cert_common_name'])."' -outform PEM -out smtpd.cert -newkey rsa:4096 -nodes -keyout smtpd.key -keyform PEM -days 3650 -x509"; } else { @@ -208,58 +274,59 @@ class installer extends installer_base caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command); } - //* We have to change the permissions of the courier authdaemon directory to make it accessible for maildrop. - $command = 'chmod 755 /var/lib/courier/authdaemon/'; - if (is_dir('/var/lib/courier/authdaemon')) { - caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command); - } + //** We have to change the permissions of the courier authdaemon directory to make it accessible for maildrop. + $command = 'chmod 755 /var/run/courier/authdaemon/'; + if(is_file('/var/run/courier/authdaemon/')) caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command); - //* Changing maildrop lines in posfix master.cf + //* Check maildrop service in posfix master.cf + $quoted_regex = '^maildrop unix.*pipe flags=DRhu user=vmail '.preg_quote('argv=/usr/bin/maildrop -d '.$cf['vmail_username'].' ${extension} ${recipient} ${user} ${nexthop} ${sender}', '/'); $configfile = $config_dir.'/master.cf'; - $content = rf($configfile); - - $content = preg_replace('/^#?maildrop/m', 'maildrop', $content); - $content = preg_replace('/^#?(\s+)flags=DRhu user=vmail argv=\/usr\/bin\/maildrop -d/m', - '$1flags=DRhu user=vmail argv=/usr/bin/maildrop -d vmail \${extension} \${recipient} \${user} \${nexthop} \${sender}', - $content); - - $this->write_config_file($configfile, $content); - - //* Writing the Maildrop mailfilter file - $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/mailfilter.master', 'tpl/mailfilter.master'); + if($this->get_postfix_service('maildrop', 'unix')) { + exec ("postconf -M maildrop.unix 2> /dev/null", $out, $ret); + $change_maildrop_flags = @(preg_match("/$quoted_regex/", $out[0]) && $out[0] !='')?false:true; + } else { + $change_maildrop_flags = @(preg_match("/$quoted_regex/", $configfile))?false:true; + } + if ($change_maildrop_flags) { + //* Change maildrop service in posfix master.cf + if(is_file($config_dir.'/master.cf')) { + copy($config_dir.'/master.cf', $config_dir.'/master.cf~'); + } + if(is_file($config_dir.'/master.cf~')) { + chmod($config_dir.'/master.cf~', 0400); + } + $configfile = $config_dir.'/master.cf'; + $content = rf($configfile); + $content = str_replace('flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}', + 'flags=DRhu user='.$cf['vmail_username'].' argv=/usr/bin/maildrop -d '.$cf['vmail_username'].' ${extension} ${recipient} ${user} ${nexthop} ${sender}', + $content); + wf($configfile, $content); + } + + //* Writing the Maildrop mailfilter file + $configfile = 'mailfilter'; + if(is_file($cf['vmail_mailbox_base'].'/.'.$configfile)) { + copy($cf['vmail_mailbox_base'].'/.'.$configfile, $cf['vmail_mailbox_base'].'/.'.$configfile.'~'); + } + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master'); $content = str_replace('{dist_postfix_vmail_mailbox_base}', $cf['vmail_mailbox_base'], $content); - - $this->write_config_file($cf['vmail_mailbox_base'].'/.mailfilter', $content); + wf($cf['vmail_mailbox_base'].'/.'.$configfile, $content); //* Create the directory for the custom mailfilters - if (!is_dir($cf['vmail_mailbox_base'].'/mailfilters')) - { + if(!is_dir($cf['vmail_mailbox_base'].'/mailfilters')) { $command = 'mkdir '.$cf['vmail_mailbox_base'].'/mailfilters'; - caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); - } - - //* postfix-dkim - $filename='tag_as_originating.re'; - $full_file_name=$config_dir.'/'.$filename; - if(is_file($full_file_name)) copy($full_file_name, $full_file_name.'~'); - $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/postfix-'.$filename.'.master', 'tpl/postfix-'.$filename.'.master'); - wf($full_file_name, $content); - - $filename='tag_as_foreign.re'; - $full_file_name=$config_dir.'/'.$filename; - if(is_file($full_file_name)) copy($full_file_name, $full_file_name.'~'); - $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/postfix-'.$filename.'.master', 'tpl/postfix-'.$filename.'.master'); - wf($full_file_name, $content); + caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); + } //* Chmod and chown the .mailfilter file - $command = 'chown -R '.$cf['vmail_username'].':'.$cf['vmail_groupname'].' '.$cf['vmail_mailbox_base'].'/.mailfilter'; + $command = 'chown '.$cf['vmail_username'].':'.$cf['vmail_groupname'].' '.$cf['vmail_mailbox_base'].'/.mailfilter'; caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); - $command = 'chmod -R 600 '.$cf['vmail_mailbox_base'].'/.mailfilter'; + $command = 'chmod 600 '.$cf['vmail_mailbox_base'].'/.mailfilter'; caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); } - + public function configure_saslauthd() { global $conf; @@ -297,17 +364,21 @@ class installer extends installer_base caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); } - public function configure_dovecot() - { + public function configure_dovecot() { global $conf; $virtual_transport = 'dovecot'; $configure_lmtp = false; + // use lmtp if installed + if($configure_lmtp = (is_file('/usr/lib/dovecot/lmtp') || is_file('/usr/libexec/dovecot/lmtp'))) { + $virtual_transport = 'lmtp:unix:private/dovecot-lmtp'; + } + // check if virtual_transport must be changed if ($this->is_update) { - $tmp = $this->db->queryOneRecord("SELECT * FROM ?? WHERE server_id = ?", $conf["mysql"]["database"].".server", $conf['server_id']); + $tmp = $this->db->queryOneRecord("SELECT * FROM ?? WHERE server_id = ?", $conf["mysql"]["database"] . ".server", $conf['server_id']); $ini_array = ini_to_array(stripslashes($tmp['config'])); // ini_array needs not to be checked, because already done in update.php -> updateDbAndIni() @@ -318,10 +389,13 @@ class installer extends installer_base } $config_dir = $conf['postfix']['config_dir']; + $quoted_config_dir = preg_quote($config_dir, '|'); + $postfix_version = `postconf -d mail_version 2>/dev/null`; + $postfix_version = preg_replace( '/mail_version\s*=\s*(.*)\s*/', '$1', $postfix_version ); //* Configure master.cf and add a line for deliver if(!$this->get_postfix_service('dovecot', 'unix')) { - //* backup + //* backup if(is_file($config_dir.'/master.cf')){ copy($config_dir.'/master.cf', $config_dir.'/master.cf~2'); } @@ -329,14 +403,15 @@ class installer extends installer_base chmod($config_dir.'/master.cf~2', 0400); } //* Configure master.cf and add a line for deliver - $content = rf($conf["postfix"]["config_dir"].'/master.cf'); - $deliver_content = 'dovecot unix - n n - - pipe'."\n".' flags=DROhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}'."\n"; + $content = rf($config_dir.'/master.cf'); + $deliver_content = 'dovecot unix - n n - - pipe'."\n".' flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${user}@${nexthop}'."\n"; af($config_dir.'/master.cf', $deliver_content); unset($content); unset($deliver_content); } //* Reconfigure postfix to use dovecot authentication + // Adding the amavisd commands to the postfix configuration $postconf_commands = array ( 'dovecot_destination_recipient_limit = 1', 'virtual_transport = '.$virtual_transport, @@ -344,25 +419,44 @@ class installer extends installer_base 'smtpd_sasl_path = private/auth' ); - //* Make a backup copy of the main.cf file - copy($conf['postfix']['config_dir'].'/main.cf', $conf['postfix']['config_dir'].'/main.cf~3'); + // Make a backup copy of the main.cf file + copy($config_dir.'/main.cf', $config_dir.'/main.cf~3'); - //* Executing the postconf commands - foreach($postconf_commands as $cmd) - { + $options = preg_split("/,\s*/", exec("postconf -h smtpd_recipient_restrictions")); + $new_options = array(); + foreach ($options as $value) { + $value = trim($value); + if ($value == '') continue; + if (preg_match("|check_recipient_access\s+proxy:mysql:${quoted_config_dir}/mysql-verify_recipients.cf|", $value)) { + continue; + } + $new_options[] = $value; + } + if ($configure_lmtp && $conf['mail']['content_filter'] === 'amavisd') { + for ($i = 0; isset($new_options[$i]); $i++) { + if ($new_options[$i] == 'reject_unlisted_recipient') { + array_splice($new_options, $i+1, 0, array("check_recipient_access proxy:mysql:${config_dir}/mysql-verify_recipients.cf")); + break; + } + } + # postfix < 3.3 needs this when using reject_unverified_recipient: + if(version_compare($postfix_version, 3.3, '<')) { + $postconf_commands[] = "enable_original_recipient = yes"; + } + } + $postconf_commands[] = "smtpd_recipient_restrictions = ".implode(", ", $new_options); + + // Executing the postconf commands + foreach($postconf_commands as $cmd) { $command = "postconf -e '$cmd'"; - caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); + caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); } + //* backup dovecot.conf $config_dir = $conf['dovecot']['config_dir']; - //* copy dovecot.conf - $configfile = $config_dir.'/dovecot.conf'; - $content = $this->get_template_file('dovecot.conf', true); - $this->write_config_file($configfile, $content); - - //* dovecot-lmtpd - if($configure_lmtp) { - replaceLine($config_dir.'/'.$configfile, 'protocols = imap pop3', 'protocols = imap pop3 lmtp', 1, 0); + $configfile = 'dovecot.conf'; + if(is_file($config_dir.'/'.$configfile)) { + copy($config_dir.'/'.$configfile, $config_dir.'/'.$configfile.'~'); } //* Get the dovecot version @@ -370,15 +464,112 @@ class installer extends installer_base $dovecot_version = $tmp[0]; unset($tmp); + //* Copy dovecot configuration file + if(version_compare($dovecot_version,1, '<=')) { //* Dovecot 1.x + if(is_file($conf['ispconfig_install_dir'].'/server/conf-custom/install/gentoo_dovecot.conf.master')) { + copy($conf['ispconfig_install_dir'].'/server/conf-custom/install/gentoo_dovecot.conf.master', $config_dir.'/'.$configfile); + } else { + copy('dist/tpl/gentoo/dovecot.conf.master', $config_dir.'/'.$configfile); + } + } else { //* Dovecot 2.x + if(is_file($conf['ispconfig_install_dir'].'/server/conf-custom/install/gentoo_dovecot2.conf.master')) { + copy($conf['ispconfig_install_dir'].'/server/conf-custom/install/gentoo_dovecot2.conf.master', $config_dir.'/'.$configfile); + } else { + copy('dist/tpl/gentoo/dovecot2.conf.master', $config_dir.'/'.$configfile); + } + // Copy custom config file + if(is_file($conf['ispconfig_install_dir'].'/server/conf-custom/install/dovecot_custom.conf.master')) { + if(!@is_dir($config_dir . '/conf.d')) { + mkdir($config_dir . '/conf.d'); + } + copy($conf['ispconfig_install_dir'].'/server/conf-custom/install/dovecot_custom.conf.master', $config_dir.'/conf.d/99-ispconfig-custom-config.conf'); + } + replaceLine($config_dir.'/'.$configfile, 'postmaster_address = postmaster@example.com', 'postmaster_address = postmaster@'.$conf['hostname'], 1, 0); + replaceLine($config_dir.'/'.$configfile, 'postmaster_address = webmaster@localhost', 'postmaster_address = postmaster@'.$conf['hostname'], 1, 0); + if(version_compare($dovecot_version, 2.1, '<')) { + removeLine($config_dir.'/'.$configfile, 'ssl_protocols ='); + } + if(version_compare($dovecot_version,2.2) >= 0) { + // Dovecot > 2.2 does not recognize !SSLv2 anymore on Debian 9 + $content = file_get_contents($config_dir.'/'.$configfile); + $content = str_replace('!SSLv2','',$content); + file_put_contents($config_dir.'/'.$configfile,$content); + unset($content); + } + if(version_compare($dovecot_version,2.3) >= 0) { + // Remove deprecated setting(s) + removeLine($config_dir.'/'.$configfile, 'ssl_protocols ='); + + // Check if we have a dhparams file and if not, create it + if(!file_exists('/etc/dovecot/dh.pem')) { + swriteln('Creating new DHParams file, this takes several minutes. Do not interrupt the script.'); + if(file_exists('/var/lib/dovecot/ssl-parameters.dat')) { + // convert existing ssl parameters file + $command = 'dd if=/var/lib/dovecot/ssl-parameters.dat bs=1 skip=88 | openssl dhparam -inform der > /etc/dovecot/dh.pem'; + caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); + } else { + /* + Create a new dhparams file. We use 2048 bit only as it simply takes too long + on smaller systems to generate a 4096 bit dh file (> 30 minutes). If you need + a 4096 bit file, create it manually before you install ISPConfig + */ + $command = 'openssl dhparam -out /etc/dovecot/dh.pem 2048'; + caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); + } + } + //remove #2.3+ comment + $content = file_get_contents($config_dir.'/'.$configfile); + $content = str_replace('#2.3+ ','',$content); + file_put_contents($config_dir.'/'.$configfile,$content); + unset($content); + + } else { + // remove settings which are not supported in Dovecot < 2.3 + removeLine($config_dir.'/'.$configfile, 'ssl_min_protocol ='); + removeLine($config_dir.'/'.$configfile, 'ssl_dh ='); + } + } + + $dovecot_protocols = 'imap pop3'; + + //* dovecot-lmtpd + if($configure_lmtp) { + $dovecot_protocols .= ' lmtp'; + } + + //* dovecot-managesieved + if(is_file('/usr/lib/dovecot/managesieve') || is_file('/usr/libexec/dovecot/managesieve')) { + $dovecot_protocols .= ' sieve'; + } + + replaceLine($config_dir.'/'.$configfile, 'protocols = imap pop3', "protocols = $dovecot_protocols", 1, 0); + //* dovecot-sql.conf - $configfile = $config_dir.'/dovecot-sql.conf'; - $content = $this->get_template_file('debian_dovecot-sql.conf', true, true); + $configfile = 'dovecot-sql.conf'; + if(is_file($config_dir.'/'.$configfile)) { + copy($config_dir.'/'.$configfile, $config_dir.'/'.$configfile.'~'); + } + if(is_file($config_dir.'/'.$configfile.'~')) chmod($config_dir.'/'.$configfile.'~', 0400); + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/debian_dovecot-sql.conf.master', 'tpl/debian_dovecot-sql.conf.master'); + $content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content); + $content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content); + $content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content); + $content = str_replace('{mysql_server_host}', $conf['mysql']['host'], $content); + $content = str_replace('{mysql_server_port}', $conf['mysql']['port'], $content); + $content = str_replace('{server_id}', $conf['server_id'], $content); # enable iterate_query for dovecot2 if(version_compare($dovecot_version,2, '>=')) { $content = str_replace('# iterate_query', 'iterate_query', $content); } - $content = str_replace('{server_id}', $conf['server_id'], $content); - $this->write_config_file($configfile, $content); + wf($config_dir.'/'.$configfile, $content); + + chmod($config_dir.'/'.$configfile, 0600); + chown($config_dir.'/'.$configfile, 'root'); + chgrp($config_dir.'/'.$configfile, 'root'); + + // Dovecot shall ignore mounts in website directory + if(is_installed('doveadm')) exec("doveadm mount add '/var/www/*' ignore > /dev/null 2> /dev/null"); + } public function configure_spamassassin() @@ -515,6 +706,36 @@ class installer extends installer_base $content = preg_replace('/MISC_OTHER="[^"]+"/', 'MISC_OTHER="-b -A -E -Z -D -H -O clf:'.$logdir.'/transfer.log'.$enable_tls.'"', $content); $this->write_config_file($conf['pureftpd']['config_file'], $content); + + //* Since version 1.0.50: Configuration through /etc/conf.d/pure-ftpd is now deprecated! + exec("/usr/sbin/pure-ftpd --help | head -1",$out); + if(preg_match("#v([0-9\.]+)\s#",$out[0],$matches)){ + $pureftpd_version = $matches[1]; + + if(version_compare($pureftpd_version, '1.0.50', '>=')) { + $configfile = $conf['pureftpd']['main_config_file']; + if(is_file($configfile)) { + copy($configfile, $configfile.'~'); + } + + $content = rf($configfile); + $content = preg_replace('/BrokenClientsCompatibility\s+(yes|no)/', 'BrokenClientsCompatibility yes', $content); + $content = preg_replace('/ChrootEveryone\s+(yes|no)/', 'ChrootEveryone yes', $content); + $content = preg_replace('/NoAnonymous\s+(yes|no)/', 'NoAnonymous yes', $content); + $content = preg_replace('/#? AltLog\s+clf.*\s/', 'AltLog clf:/var/log/pureftpd.log', $content); + $content = preg_replace('/CustomerProof\s+(yes|no)/', 'CustomerProof yes', $content); + $content = preg_replace('/DisplayDotFiles\s+(yes|no)/', 'DisplayDotFiles yes', $content); + $content = preg_replace('/DontResolve\s+(yes|no)/', 'DontResolve yes', $content); + $content = preg_replace('/#? MySQLConfigFile\s+\/.*\s/', 'MySQLConfigFile ' . $conf['pureftpd']['mysql_config_file'], $content); + + if(file_exists('/etc/ssl/private/pure-ftpd.pem')) { + $content = preg_replace('/(#?) TLS\s+(0|1)/', 'TLS 1', $content); + } + + wf($configfile, $content); + } + } + } public function configure_powerdns() @@ -845,39 +1066,46 @@ class installer extends installer_base } } + + public function get_host_ips() { + $out = array(); + exec("ip addr show | awk '/global/ { print $2 }' | cut -d '/' -f 1", $ret, $val); + if($val == 0) { + if(is_array($ret) && !empty($ret)){ + foreach($ret as $ip) { + $ip = trim($ip); + $out[] = $ip; + } + } + } - public function install_ispconfig() - { + return $out; + } + + public function install_ispconfig() { global $conf; $install_dir = $conf['ispconfig_install_dir']; //* Create the ISPConfig installation directory - if(!is_dir($install_dir)) - { + if(!@is_dir($install_dir)) { $command = "mkdir $install_dir"; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); } //* Create a ISPConfig user and group - if (!is_group('ispconfig')) - { - $command = 'groupadd ispconfig'; - caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); - } + $command = 'groupadd ispconfig'; + if(!is_group('ispconfig')) caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); - if (!is_user('ispconfig')) - { - $command = "useradd -g ispconfig -d $install_dir ispconfig"; - caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); - } + $command = 'useradd -g ispconfig -d '.$install_dir.' ispconfig'; + if(!is_user('ispconfig')) caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); //* copy the ISPConfig interface part - $command = "cp -rf ../interface $install_dir"; + $command = 'cp -rf ../interface '.$install_dir; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); //* copy the ISPConfig server part - $command = "cp -rf ../server $install_dir"; + $command = 'cp -rf ../server '.$install_dir; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); //* Make a backup of the security settings @@ -887,28 +1115,29 @@ class installer extends installer_base $command = 'cp -rf ../security '.$install_dir; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); - //* Apply changed security_settings.ini values to new security_settings.ini file - if(is_file('/usr/local/ispconfig/security/security_settings.ini~')) { - $security_settings_old = ini_to_array(file_get_contents('/usr/local/ispconfig/security/security_settings.ini~')); - $security_settings_new = ini_to_array(file_get_contents('/usr/local/ispconfig/security/security_settings.ini')); - if(is_array($security_settings_new) && is_array($security_settings_old)) { - foreach($security_settings_new as $section => $sval) { - if(is_array($sval)) { - foreach($sval as $key => $val) { - if(isset($security_settings_old[$section]) && isset($security_settings_old[$section][$key])) { - $security_settings_new[$section][$key] = $security_settings_old[$section][$key]; - } - } - } - } - file_put_contents('/usr/local/ispconfig/security/security_settings.ini',array_to_ini($security_settings_new)); - } + $configfile = 'security_settings.ini'; + if(is_file($install_dir.'/security/'.$configfile)) { + copy($install_dir.'/security/'.$configfile, $install_dir.'/security/'.$configfile.'~'); } + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master'); + wf($install_dir.'/security/'.$configfile, $content); + //* Create a symlink, so ISPConfig is accessible via web + // Replaced by a separate vhost definition for port 8080 + // $command = "ln -s $install_dir/interface/web/ /var/www/ispconfig"; + // caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); //* Create the config file for ISPConfig interface $configfile = 'config.inc.php'; - $content = $this->get_template_file($configfile, true, true); //* get contents & insert db cred + if(is_file($install_dir.'/interface/lib/'.$configfile)) { + copy($install_dir.'/interface/lib/'.$configfile, $install_dir.'/interface/lib/'.$configfile.'~'); + } + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master'); + $content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content); + $content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content); + $content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content); + $content = str_replace('{mysql_server_host}', $conf['mysql']['host'], $content); + $content = str_replace('{mysql_server_port}', $conf['mysql']['port'], $content); $content = str_replace('{mysql_master_server_ispconfig_user}', $conf['mysql']['master_ispconfig_user'], $content); $content = str_replace('{mysql_master_server_ispconfig_password}', $conf['mysql']['master_ispconfig_password'], $content); @@ -923,10 +1152,34 @@ class installer extends installer_base $content = str_replace('{theme}', $conf['theme'], $content); $content = str_replace('{language_file_import_enabled}', ($conf['language_file_import_enabled'] == true)?'true':'false', $content); - $this->write_config_file("$install_dir/interface/lib/$configfile", $content); + wf($install_dir.'/interface/lib/'.$configfile, $content); //* Create the config file for ISPConfig server - $this->write_config_file("$install_dir/server/lib/$configfile", $content); + $configfile = 'config.inc.php'; + if(is_file($install_dir.'/server/lib/'.$configfile)) { + copy($install_dir.'/server/lib/'.$configfile, $install_dir.'/interface/lib/'.$configfile.'~'); + } + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master'); + $content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content); + $content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content); + $content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content); + $content = str_replace('{mysql_server_host}', $conf['mysql']['host'], $content); + $content = str_replace('{mysql_server_port}', $conf['mysql']['port'], $content); + + $content = str_replace('{mysql_master_server_ispconfig_user}', $conf['mysql']['master_ispconfig_user'], $content); + $content = str_replace('{mysql_master_server_ispconfig_password}', $conf['mysql']['master_ispconfig_password'], $content); + $content = str_replace('{mysql_master_server_database}', $conf['mysql']['master_database'], $content); + $content = str_replace('{mysql_master_server_host}', $conf['mysql']['master_host'], $content); + $content = str_replace('{mysql_master_server_port}', $conf['mysql']['master_port'], $content); + + $content = str_replace('{server_id}', $conf['server_id'], $content); + $content = str_replace('{ispconfig_log_priority}', $conf['ispconfig_log_priority'], $content); + $content = str_replace('{language}', $conf['language'], $content); + $content = str_replace('{timezone}', $conf['timezone'], $content); + $content = str_replace('{theme}', $conf['theme'], $content); + $content = str_replace('{language_file_import_enabled}', ($conf['language_file_import_enabled'] == true)?'true':'false', $content); + + wf($install_dir.'/server/lib/'.$configfile, $content); //* Create the config file for remote-actions (but only, if it does not exist, because // the value is a autoinc-value and so changed by the remoteaction_core_module @@ -935,7 +1188,7 @@ class installer extends installer_base wf($install_dir.'/server/lib/remote_action.inc.php', $content); } - // Enable the server modules and plugins. + //* Enable the server modules and plugins. // TODO: Implement a selector which modules and plugins shall be enabled. $dir = $install_dir.'/server/mods-available/'; if (is_dir($dir)) { @@ -977,10 +1230,12 @@ class installer extends installer_base if(method_exists($tmp, 'onInstall') && $tmp->onInstall()) { if(!@is_link($install_dir.'/server/plugins-enabled/'.$file)) { @symlink($install_dir.'/server/plugins-available/'.$file, $install_dir.'/server/plugins-enabled/'.$file); + //@symlink($install_dir.'/server/plugins-available/'.$file, '../plugins-enabled/'.$file); } if (strpos($file, '_core_plugin') !== false) { if(!@is_link($install_dir.'/server/plugins-core/'.$file)) { @symlink($install_dir.'/server/plugins-available/'.$file, $install_dir.'/server/plugins-core/'.$file); + //@symlink($install_dir.'/server/plugins-available/'.$file, '../plugins-core/'.$file); } } } @@ -991,21 +1246,25 @@ class installer extends installer_base } } - //* Update the server config + // Update the server config $mail_server_enabled = ($conf['services']['mail'])?1:0; $web_server_enabled = ($conf['services']['web'])?1:0; $dns_server_enabled = ($conf['services']['dns'])?1:0; $file_server_enabled = ($conf['services']['file'])?1:0; $db_server_enabled = ($conf['services']['db'])?1:0; - $vserver_server_enabled = ($conf['services']['vserver'])?1:0; + $vserver_server_enabled = ($conf['openvz']['installed'])?1:0; + $proxy_server_enabled = ($conf['services']['proxy'])?1:0; + $firewall_server_enabled = ($conf['services']['firewall'])?1:0; + $xmpp_server_enabled = ($conf['services']['xmpp'])?1:0; - $sql = "UPDATE `server` SET mail_server = ?, web_server = ?, dns_server = ?, file_server = ?, db_server = ?, vserver_server = ? WHERE server_id = ?"; + $sql = "UPDATE `server` SET mail_server = '$mail_server_enabled', web_server = '$web_server_enabled', dns_server = '$dns_server_enabled', file_server = '$file_server_enabled', db_server = '$db_server_enabled', vserver_server = '$vserver_server_enabled', proxy_server = '$proxy_server_enabled', firewall_server = '$firewall_server_enabled', xmpp_server = '$xmpp_server_enabled' WHERE server_id = ?"; - $this->db->query($sql, $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $vserver_server_enabled, $conf['server_id']); + $this->db->query($sql, $conf['server_id']); if($conf['mysql']['master_slave_setup'] == 'y') { - $this->dbmaster->query($sql, $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $vserver_server_enabled, $conf['server_id']); + $this->dbmaster->query($sql, $conf['server_id']); } + // chown install dir to root and chmod 755 $command = 'chown root:root '.$install_dir; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); @@ -1020,6 +1279,10 @@ class installer extends installer_base $command = 'chown -R ispconfig:ispconfig '.$install_dir.'/interface'; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); + //* Chmod the files and directories in the acme dir + $command = 'chmod -R 755 '.$install_dir.'/interface/acme'; + caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); + //* chown the server files to the root user and group $command = 'chown -R root:root '.$install_dir.'/server'; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); @@ -1046,9 +1309,7 @@ class installer extends installer_base exec("chmod -R 770 $install_dir/interface/lib/lang"); //* Make the temp directory for language file exports writable - if(is_dir($install_dir.'/interface/web/temp')) { - exec("chmod -R 770 $install_dir/interface/web/temp"); - } + if(is_dir($install_dir.'/interface/web/temp')) exec("chmod -R 770 $install_dir/interface/web/temp"); //* Make all interface language file directories group writable $handle = @opendir($install_dir.'/interface/web'); @@ -1101,18 +1362,18 @@ class installer extends installer_base // and must be fixed as this will allow the apache user to read the ispconfig files. // Later this must run as own apache server or via suexec! if($conf['apache']['installed'] == true){ - $command = 'usermod -a -G ispconfig '.$conf['apache']['user']; + $command = 'adduser '.$conf['apache']['user'].' ispconfig'; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); if(is_group('ispapps')){ - $command = 'usermod -a -G ispapps '.$conf['apache']['user']; + $command = 'adduser '.$conf['apache']['user'].' ispapps'; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); } } if($conf['nginx']['installed'] == true){ - $command = 'usermod -a -G ispconfig '.$conf['nginx']['user']; + $command = 'adduser '.$conf['nginx']['user'].' ispconfig'; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); if(is_group('ispapps')){ - $command = 'usermod -a -G ispapps '.$conf['nginx']['user']; + $command = 'adduser '.$conf['nginx']['user'].' ispapps'; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); } } @@ -1128,43 +1389,62 @@ class installer extends installer_base if($conf['apache']['installed'] == true && $this->install_ispconfig_interface == true){ //* Copy the ISPConfig vhost for the controlpanel - $content = $this->get_template_file("apache_ispconfig.vhost", true); - $content = str_replace('{vhost_port}', $conf['apache']['vhost_port'], $content); + $vhost_conf_dir = $conf['apache']['vhost_conf_dir']; + //$vhost_conf_enabled_dir = $conf['apache']['vhost_conf_enabled_dir']; - //* comment out the listen directive if port is 80 or 443 - if ($conf['apache']['vhost_port'] == 80 or $conf['apache']['vhost_port'] == 443) { - $content = str_replace('{vhost_port_listen}', '#', $content); + // Dont just copy over the virtualhost template but add some custom settings + $tpl = new tpl(); + if (file_exists($conf['ispconfig_install_dir']."/server/conf-custom/install/apache_ispconfig.vhost.master")) { + $tpl->newTemplate($conf['ispconfig_install_dir']."/server/conf-custom/install/apache_ispconfig.vhost.master"); + } else { + $tpl->newTemplate("dist/tpl/gentoo/apache_ispconfig.vhost.master"); + } + $tpl->setVar('vhost_port',$conf['apache']['vhost_port']); + + // comment out the listen directive if port is 80 or 443 + if($conf['apache']['vhost_port'] == 80 or $conf['apache']['vhost_port'] == 443) { + $tpl->setVar('vhost_port_listen','#'); } else { - $content = str_replace('{vhost_port_listen}', '', $content); + $tpl->setVar('vhost_port_listen',''); } if(is_file($install_dir.'/interface/ssl/ispserver.crt') && is_file($install_dir.'/interface/ssl/ispserver.key')) { - $content = str_replace('{ssl_comment}', '', $content); + $tpl->setVar('ssl_comment',''); } else { - $content = str_replace('{ssl_comment}', '#', $content); + $tpl->setVar('ssl_comment','#'); } if(is_file($install_dir.'/interface/ssl/ispserver.crt') && is_file($install_dir.'/interface/ssl/ispserver.key') && is_file($install_dir.'/interface/ssl/ispserver.bundle')) { - $content = str_replace('{ssl_bundle_comment}', '', $content); + $tpl->setVar('ssl_bundle_comment',''); } else { - $content = str_replace('{ssl_bundle_comment}', '#', $content); + $tpl->setVar('ssl_bundle_comment','#'); } - $vhost_path = $conf['apache']['vhost_conf_dir'].'/ispconfig.vhost'; - $this->write_config_file($vhost_path, $content); - - if(!is_file('/var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter')) { - $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/apache_ispconfig_fcgi_starter.master', 'tpl/apache_ispconfig_fcgi_starter.master'); - $content = str_replace('{fastcgi_bin}', $conf['fastcgi']['fastcgi_bin'], $content); - $content = str_replace('{fastcgi_phpini_path}', $conf['fastcgi']['fastcgi_phpini_path'], $content); - @mkdir('/var/www/php-fcgi-scripts/ispconfig', 0755, true); - $this->set_immutable('/var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter', false); - wf('/var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter', $content); - exec('chmod +x /var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter'); - chmod('/var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter', 0755); - @symlink($install_dir.'/interface/web', '/var/www/ispconfig'); - exec('chown -R ispconfig:ispconfig /var/www/php-fcgi-scripts/ispconfig'); - $this->set_immutable('/var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter', true); - } + $tpl->setVar('apache_version',getapacheversion()); + + wf($vhost_conf_dir.'/ispconfig.vhost', $tpl->grab()); + + //* and create the symlink + /*if($this->is_update == false) { + if(@is_link($vhost_conf_enabled_dir.'/ispconfig.vhost')) unlink($vhost_conf_enabled_dir.'/ispconfig.vhost'); + if(!@is_link($vhost_conf_enabled_dir.'/000-ispconfig.vhost')) { + symlink($vhost_conf_dir.'/ispconfig.vhost', $vhost_conf_enabled_dir.'/000-ispconfig.vhost'); + } + }*/ + //if(!is_file('/var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter')) { + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/apache_ispconfig_fcgi_starter.master', 'tpl/apache_ispconfig_fcgi_starter.master'); + $content = str_replace('{fastcgi_bin}', $conf['fastcgi']['fastcgi_bin'], $content); + $content = str_replace('{fastcgi_phpini_path}', $conf['fastcgi']['fastcgi_phpini_path'], $content); + @mkdir('/var/www/php-fcgi-scripts/ispconfig', 0755, true); + $this->set_immutable('/var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter', false); + wf('/var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter', $content); + exec('chmod +x /var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter'); + @symlink($install_dir.'/interface/web', '/var/www/ispconfig'); + exec('chown -R ispconfig:ispconfig /var/www/php-fcgi-scripts/ispconfig'); + $this->set_immutable('/var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter', true); + //} + + // unlink acme vhost symlink + if(is_link($vhost_conf_dir . '/999-acme.conf') && file_exists($vhost_conf_dir . '/acme.conf')) unlink($vhost_conf_dir . '/999-acme.conf'); } if($conf['nginx']['installed'] == true && $this->install_ispconfig_interface == true){ @@ -1177,7 +1457,7 @@ class installer extends installer_base $content = str_replace('{vhost_port}', $conf['nginx']['vhost_port'], $content); if(is_file($install_dir.'/interface/ssl/ispserver.crt') && is_file($install_dir.'/interface/ssl/ispserver.key')) { - $content = str_replace('{ssl_on}', 'ssl', $content); + $content = str_replace('{ssl_on}', 'ssl http2', $content); $content = str_replace('{ssl_comment}', '', $content); $content = str_replace('{fastcgi_ssl}', 'on', $content); } else { @@ -1219,44 +1499,41 @@ class installer extends installer_base } //* Install the update script - if (is_file('/usr/local/bin/ispconfig_update_from_dev.sh')) { - unlink('/usr/local/bin/ispconfig_update_from_dev.sh'); - } - + if(is_file('/usr/local/bin/ispconfig_update_from_dev.sh')) unlink('/usr/local/bin/ispconfig_update_from_dev.sh'); chown($install_dir.'/server/scripts/update_from_dev.sh', 'root'); chmod($install_dir.'/server/scripts/update_from_dev.sh', 0700); - chown($install_dir.'/server/scripts/update_from_tgz.sh', 'root'); - chmod($install_dir.'/server/scripts/update_from_tgz.sh', 0700); +// chown($install_dir.'/server/scripts/update_from_tgz.sh', 'root'); +// chmod($install_dir.'/server/scripts/update_from_tgz.sh', 0700); chown($install_dir.'/server/scripts/ispconfig_update.sh', 'root'); chmod($install_dir.'/server/scripts/ispconfig_update.sh', 0700); - - if (!is_link('/usr/local/bin/ispconfig_update_from_dev.sh')) { - symlink($install_dir.'/server/scripts/ispconfig_update.sh', '/usr/local/bin/ispconfig_update_from_dev.sh'); - } - - if (!is_link('/usr/local/bin/ispconfig_update.sh')) { - symlink($install_dir.'/server/scripts/ispconfig_update.sh', '/usr/local/bin/ispconfig_update.sh'); - } + if(!is_link('/usr/local/bin/ispconfig_update_from_dev.sh')) symlink($install_dir.'/server/scripts/ispconfig_update.sh', '/usr/local/bin/ispconfig_update_from_dev.sh'); + if(!is_link('/usr/local/bin/ispconfig_update.sh')) symlink($install_dir.'/server/scripts/ispconfig_update.sh', '/usr/local/bin/ispconfig_update.sh'); + + // Make executable then unlink and symlink letsencrypt pre, post and renew hook scripts + chown($install_dir.'/server/scripts/letsencrypt_pre_hook.sh', 'root'); + chown($install_dir.'/server/scripts/letsencrypt_post_hook.sh', 'root'); + chown($install_dir.'/server/scripts/letsencrypt_renew_hook.sh', 'root'); + chmod($install_dir.'/server/scripts/letsencrypt_pre_hook.sh', 0700); + chmod($install_dir.'/server/scripts/letsencrypt_post_hook.sh', 0700); + chmod($install_dir.'/server/scripts/letsencrypt_renew_hook.sh', 0700); + if(is_link('/usr/local/bin/letsencrypt_pre_hook.sh')) unlink('/usr/local/bin/letsencrypt_pre_hook.sh'); + if(is_link('/usr/local/bin/letsencrypt_post_hook.sh')) unlink('/usr/local/bin/letsencrypt_post_hook.sh'); + if(is_link('/usr/local/bin/letsencrypt_renew_hook.sh')) unlink('/usr/local/bin/letsencrypt_renew_hook.sh'); + symlink($install_dir.'/server/scripts/letsencrypt_pre_hook.sh', '/usr/local/bin/letsencrypt_pre_hook.sh'); + symlink($install_dir.'/server/scripts/letsencrypt_post_hook.sh', '/usr/local/bin/letsencrypt_post_hook.sh'); + symlink($install_dir.'/server/scripts/letsencrypt_renew_hook.sh', '/usr/local/bin/letsencrypt_renew_hook.sh'); //* Make the logs readable for the ispconfig user - if (is_file('/var/log/maillog')) { - exec('chmod +r /var/log/maillog'); - } - if (is_file('/var/log/messages')) { - exec('chmod +r /var/log/messages'); - } - if (is_file('/var/log/clamav/clamav.log')) { - exec('chmod +r /var/log/clamav/clamav.log'); - } - if (is_file('/var/log/clamav/freshclam.log')) { - exec('chmod +r /var/log/clamav/freshclam.log'); - } - - //* Create the ispconfig log directory - if (!is_dir($conf['ispconfig_log_dir'])) { - mkdir($conf['ispconfig_log_dir']); - } - if (!is_file($conf['ispconfig_log_dir'].'/ispconfig.log')) { + if(@is_file('/var/log/mail.log')) exec('chmod +r /var/log/mail.log'); + if(@is_file('/var/log/mail.warn')) exec('chmod +r /var/log/mail.warn'); + if(@is_file('/var/log/mail.err')) exec('chmod +r /var/log/mail.err'); + if(@is_file('/var/log/messages')) exec('chmod +r /var/log/messages'); + if(@is_file('/var/log/clamav/clamav.log')) exec('chmod +r /var/log/clamav/clamav.log'); + if(@is_file('/var/log/clamav/freshclam.log')) exec('chmod +r /var/log/clamav/freshclam.log'); + + //* Create the ispconfig log file and directory + if(!is_file($conf['ispconfig_log_dir'].'/ispconfig.log')) { + if(!is_dir($conf['ispconfig_log_dir'])) mkdir($conf['ispconfig_log_dir'], 0755); touch($conf['ispconfig_log_dir'].'/ispconfig.log'); } chmod($conf['ispconfig_log_dir'].'/ispconfig.log', 0600); @@ -1268,16 +1545,45 @@ class installer extends installer_base exec('chown ispconfig:ispconfig '. $conf['ispconfig_log_dir'].'/auth.log'); exec('chmod 660 '. $conf['ispconfig_log_dir'].'/auth.log'); - rename($install_dir.'/server/scripts/run-getmail.sh', '/usr/local/bin/run-getmail.sh'); - - if (is_user('getmail')) { - chown('/usr/local/bin/run-getmail.sh', 'getmail'); + if(is_user('getmail')) { + rename($install_dir.'/server/scripts/run-getmail.sh', '/usr/local/bin/run-getmail.sh'); + if(is_user('getmail')) chown('/usr/local/bin/run-getmail.sh', 'getmail'); + chmod('/usr/local/bin/run-getmail.sh', 0744); + } + + //* Add Log-Rotation + if (is_dir('/etc/logrotate.d')) { + @unlink('/etc/logrotate.d/logispc3'); // ignore, if the file is not there + /* We rotate these logs in cron_daily.php + $fh = fopen('/etc/logrotate.d/logispc3', 'w'); + fwrite($fh, + "$conf['ispconfig_log_dir']/ispconfig.log { \n" . + " weekly \n" . + " missingok \n" . + " rotate 4 \n" . + " compress \n" . + " delaycompress \n" . + "} \n" . + "$conf['ispconfig_log_dir']/cron.log { \n" . + " weekly \n" . + " missingok \n" . + " rotate 4 \n" . + " compress \n" . + " delaycompress \n" . + "}"); + fclose($fh); + */ } - chmod('/usr/local/bin/run-getmail.sh', 0744); //* Remove Domain module as its functions are available in the client module now if(@is_dir('/usr/local/ispconfig/interface/web/domain')) exec('rm -rf /usr/local/ispconfig/interface/web/domain'); + //* Disable rkhunter run and update in debian cronjob as ispconfig is running and updating rkhunter + if(is_file('/etc/default/rkhunter')) { + replaceLine('/etc/default/rkhunter', 'CRON_DAILY_RUN="yes"', 'CRON_DAILY_RUN="no"', 1, 0); + replaceLine('/etc/default/rkhunter', 'CRON_DB_UPDATE="yes"', 'CRON_DB_UPDATE="no"', 1, 0); + } + // Add symlink for patch tool if(!is_link('/usr/local/bin/ispconfig_patch')) exec('ln -s /usr/local/ispconfig/server/scripts/ispconfig_patch /usr/local/bin/ispconfig_patch'); @@ -1286,7 +1592,6 @@ class installer extends installer_base if(is_file($conf['amavis']['config_dir'].'/50-user~')) chmod($conf['amavis']['config_dir'].'/50-user~', 0400); if(is_file($conf['amavis']['config_dir'].'/amavisd.conf')) chmod($conf['amavis']['config_dir'].'/amavisd.conf', 0640); if(is_file($conf['amavis']['config_dir'].'/amavisd.conf~')) chmod($conf['amavis']['config_dir'].'/amavisd.conf~', 0400); - } } -- GitLab From f58ff87aad89fa72b3807d66b75058840bdd4fb0 Mon Sep 17 00:00:00 2001 From: dachris1 Date: Tue, 15 Nov 2022 20:11:18 +0100 Subject: [PATCH 3/4] new config based on debian config added because gentoo has no mod version installed by default added --- .../tpl/gentoo/apache_ispconfig.vhost.master | 121 ++++++++++++++---- 1 file changed, 98 insertions(+), 23 deletions(-) diff --git a/install/dist/tpl/gentoo/apache_ispconfig.vhost.master b/install/dist/tpl/gentoo/apache_ispconfig.vhost.master index 01b3b383d5..39d25ac906 100644 --- a/install/dist/tpl/gentoo/apache_ispconfig.vhost.master +++ b/install/dist/tpl/gentoo/apache_ispconfig.vhost.master @@ -4,41 +4,83 @@ # for the ISPConfig controlpanel ###################################################### -{vhost_port_listen} Listen {vhost_port} - - NameVirtualHost *:{vhost_port} - + Listen +NameVirtualHost *: - +> ServerAdmin webmaster@localhost Alias /mail /var/www/ispconfig/mail + + + SetHandler None + + + + + SetHandler None + + + DocumentRoot /var/www/ispconfig/ SuexecUserGroup ispconfig ispconfig - Options +Indexes +FollowSymLinks +MultiViews +ExecCGI + Options -Indexes +FollowSymLinks +MultiViews +ExecCGI AllowOverride AuthConfig Indexes Limit Options FileInfo - + SetHandler fcgid-script FCGIWrapper /var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter .php + + Require all granted + Order allow,deny Allow from all + DirectoryIndex index.php + IPCCommTimeout 7200 + MaxRequestLen 15728640 + + + + DocumentRoot /usr/local/ispconfig/interface/web + SuexecUserGroup ispconfig ispconfig + DirectoryIndex index.php + + + Options -Indexes +FollowSymLinks +MultiViews +ExecCGI + AllowOverride AuthConfig Indexes Limit Options FileInfo + + Require all granted + + Order allow,deny + Allow from all + + + #SetHandler "proxy:unix:/var/lib/php5-fpm/ispconfig.sock|fcgi://localhost" + SetHandler "proxy:fcgi://127.0.0.1:9000" + + - + DocumentRoot /usr/local/ispconfig/interface/web/ + AssignUserId ispconfig ispconfig AddType application/x-httpd-php .php + # php_admin_value open_basedir "/usr/local/ispconfig/interface:/usr/share:/tmp" Options +FollowSymLinks AllowOverride None + + Require all granted + Order allow,deny Allow from all - php_value magic_quotes_gpc 0 + + php_value magic_quotes_gpc 0 @@ -51,20 +93,53 @@ # SSL Configuration - {ssl_comment}SSLEngine On - {ssl_comment}SSLCertificateFile /usr/local/ispconfig/interface/ssl/ispserver.crt - {ssl_comment}SSLCertificateKeyFile /usr/local/ispconfig/interface/ssl/ispserver.key + SSLEngine On + + SSLProtocol All -SSLv3 -TLSv1 -TLSv1.1 + + SSLProtocol All -SSLv2 -SSLv3 + + SSLCertificateFile /usr/local/ispconfig/interface/ssl/ispserver.crt + SSLCertificateKeyFile /usr/local/ispconfig/interface/ssl/ispserver.key + SSLCACertificateFile /usr/local/ispconfig/interface/ssl/ispserver.bundle - + SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 + SSLHonorCipherOrder On + + SSLCompression Off + + + SSLSessionTickets Off + - - AllowOverride None - Order Deny,Allow - Deny from all - + + # ISPConfig 3.1 currently requires unsafe-line for both scripts and styles, as well as unsafe-eval + Header set Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data:; object-src 'none'" + Header set Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data:; object-src 'none'; upgrade-insecure-requests" + Header set X-Content-Type-Options: nosniff + Header set X-Frame-Options: SAMEORIGIN + Header set X-XSS-Protection: "1; mode=block" + Header always edit Set-Cookie (.*) "$1; HTTPOnly" + Header always edit Set-Cookie (.*) "$1; Secure" + + = 2.4.7> + Header setifempty Strict-Transport-Security "max-age=15768000" + + + Header set Strict-Transport-Security "max-age=15768000" + + + RequestHeader unset Proxy early + + + + SSLUseStapling On + SSLStaplingResponderTimeout 5 + SSLStaplingReturnResponderErrors Off + + + # Redirect http to https + ErrorDocument 400 "

Error 400 - trying to redirect

" + +
- - AllowOverride None - Order Deny,Allow - Deny from all - -- GitLab From 69c4da025798cf0147173c394a9f5b7822f2b7b8 Mon Sep 17 00:00:00 2001 From: dachris1 Date: Tue, 15 Nov 2022 20:12:06 +0100 Subject: [PATCH 4/4] updated based on debian config install/tpl/gentoo_postfix.conf.master updated based on debian config --- install/tpl/gentoo_postfix.conf.master | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/install/tpl/gentoo_postfix.conf.master b/install/tpl/gentoo_postfix.conf.master index c6b1c2f9c5..8bd34f6928 100644 --- a/install/tpl/gentoo_postfix.conf.master +++ b/install/tpl/gentoo_postfix.conf.master @@ -1,3 +1,5 @@ +alias_maps = hash:/etc/aliases, hash:/var/lib/mailman/data/aliases +alias_database = hash:/etc/aliases, hash:/var/lib/mailman/data/aliases virtual_alias_domains = proxy:mysql:{config_dir}/mysql-virtual_alias_domains.cf virtual_alias_maps = hash:/var/lib/mailman/data/virtual-mailman, proxy:mysql:{config_dir}/mysql-virtual_forwardings.cf, proxy:mysql:{config_dir}/mysql-virtual_alias_maps.cf, proxy:mysql:{config_dir}/mysql-virtual_email2email.cf virtual_mailbox_domains = proxy:mysql:{config_dir}/mysql-virtual_domains.cf @@ -5,6 +7,9 @@ virtual_mailbox_maps = proxy:mysql:{config_dir}/mysql-virtual_mailboxes.cf virtual_mailbox_base = {vmail_mailbox_base} virtual_uid_maps = proxy:mysql:/etc/postfix/mysql-virtual_uids.cf virtual_gid_maps = proxy:mysql:/etc/postfix/mysql-virtual_gids.cf +sender_bcc_maps = proxy:mysql:{config_dir}/mysql-virtual_outgoing_bcc.cf +inet_protocols=all +inet_interfaces = all smtpd_sasl_auth_enable = yes broken_sasl_auth_clients = yes smtpd_sasl_authenticated_header = yes @@ -35,7 +40,7 @@ header_checks = regexp:{config_dir}/header_checks mime_header_checks = regexp:{config_dir}/mime_header_checks nested_header_checks = regexp:{config_dir}/nested_header_checks body_checks = regexp:{config_dir}/body_checks -inet_interfaces = all +owner_request_special = no smtp_tls_security_level = may smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3 smtpd_tls_protocols = !SSLv2,!SSLv3 -- GitLab