From 80e3c9acf3fc9b6d15ea4fea7c89e0a2e12db412 Mon Sep 17 00:00:00 2001 From: tbrehm Date: Tue, 26 Apr 2011 10:41:58 +0000 Subject: [PATCH] - Improved nginx reverse proxy support. - Added UFW firewall support. --- install/dist/conf/debian40.conf.php | 24 + install/dist/conf/debian60.conf.php | 23 + install/install.php | 67 ++- install/lib/installer_base.lib.php | 86 ++- install/lib/update.lib.php | 3 + install/sql/incremental/upd_0009.sql | 66 +++ install/sql/ispconfig3.sql | 69 +++ install/tpl/nginx_cache.conf.master | 6 + install/tpl/nginx_proxy.conf.master | 34 ++ install/tpl/squid.conf.master | 224 ++++++++ install/tpl/ufw.conf.master | 8 + install/update.php | 53 +- interface/lib/classes/plugin.inc.php | 9 +- interface/lib/classes/tform_actions.inc.php | 2 +- interface/lib/config.inc.php | 3 +- .../plugins/sites_web_domain_plugin.inc.php | 3 +- interface/web/admin/form/server.tform.php | 12 + .../web/admin/form/server_config.tform.php | 62 +++ interface/web/admin/lib/lang/en_server.lng | 2 + .../web/admin/lib/lang/en_server_config.lng | 17 +- .../web/admin/lib/lang/en_server_list.lng | 2 + interface/web/admin/lib/module.conf.php | 20 +- .../admin/templates/server_edit_services.htm | 12 + interface/web/admin/templates/server_list.htm | 8 +- interface/web/login/index.php | 6 + interface/web/sites/form/web_domain.tform.php | 12 +- .../web/sites/lib/lang/en_web_domain.lng | 1 + interface/web/sites/lib/module.conf.php | 12 + .../sites/templates/web_domain_advanced.htm | 4 + server/conf/nginx_rewrites.conf.master | 9 + server/conf/nginx_vhost.conf.master | 69 +++ server/conf/squidRewriteRules.py.master | 196 +++++++ server/conf/ufw.before.rules.master | 78 +++ server/conf/ufw.conf.master | 8 + server/conf/ufw.default.master | 39 ++ server/mods-available/dns_module.inc.php | 6 +- .../plugins-available/firewall_plugin.inc.php | 6 +- server/plugins-available/nginx_plugin.inc.php | 368 +++++++++++++ server/plugins-available/squid_plugin.inc.php | 171 ++++++ .../ufw_firewall_plugin.inc.php | 504 ++++++++++++++++++ 40 files changed, 2259 insertions(+), 45 deletions(-) create mode 100644 install/sql/incremental/upd_0009.sql create mode 100644 install/tpl/nginx_cache.conf.master create mode 100644 install/tpl/nginx_proxy.conf.master create mode 100644 install/tpl/squid.conf.master create mode 100644 install/tpl/ufw.conf.master create mode 100644 server/conf/nginx_rewrites.conf.master create mode 100644 server/conf/nginx_vhost.conf.master create mode 100644 server/conf/squidRewriteRules.py.master create mode 100644 server/conf/ufw.before.rules.master create mode 100644 server/conf/ufw.conf.master create mode 100644 server/conf/ufw.default.master create mode 100644 server/plugins-available/nginx_plugin.inc.php create mode 100644 server/plugins-available/squid_plugin.inc.php create mode 100644 server/plugins-available/ufw_firewall_plugin.inc.php diff --git a/install/dist/conf/debian40.conf.php b/install/dist/conf/debian40.conf.php index a3db4dd81..e635b1fa5 100644 --- a/install/dist/conf/debian40.conf.php +++ b/install/dist/conf/debian40.conf.php @@ -51,6 +51,8 @@ $conf['services']['dns'] = true; $conf['services']['file'] = true; $conf['services']['db'] = true; $conf['services']['vserver'] = true; +$conf['services']['proxy'] = false; +$conf['services']['firewall'] = false; //* MySQL $conf['mysql']['installed'] = false; // will be detected automatically during installation @@ -183,6 +185,28 @@ $conf['jailkit']['jk_chrootsh'] = 'jk_chrootsh.ini'; $conf['jailkit']['jailkit_chroot_app_programs'] = '/usr/bin/groups /usr/bin/id /usr/bin/dircolors /usr/bin/lesspipe /usr/bin/basename /usr/bin/dirname /usr/bin/nano /usr/bin/pico'; $conf['jailkit']['jailkit_chroot_cron_programs'] = '/usr/bin/php /usr/bin/perl /usr/share/perl /usr/share/php'; +//* Squid +$conf['squid']['installed'] = false; // will be detected automatically during installation +$conf['squid']['config_dir'] = '/etc/squid'; +$conf['squid']['init_script'] = 'squid'; + +//* Nginx +$conf['nginx']['installed'] = false; // will be detected automatically during installation +$conf['nginx']['config_dir'] = '/etc/nginx'; +$conf['nginx']['vhost_conf_dir'] = '/etc/nginx/sites-available'; +$conf['nginx']['vhost_conf_enabled_dir'] = '/etc/nginx/sites-enabled'; +$conf['nginx']['init_script'] = 'nginx'; + +//*Ufw +$conf['ufw']['installed'] = false; +$conf['ufw']['config_dir'] = '/etc/ufw'; +$conf['ufw']['init_script'] = 'ufw'; + +//*Bastille-Firwall +$conf['bastille']['installed'] = false; +$conf['bastille']['config_dir'] = '/etc/Bastille'; + + //* vlogger $conf['vlogger']['config_dir'] = '/etc'; diff --git a/install/dist/conf/debian60.conf.php b/install/dist/conf/debian60.conf.php index f4e8ba6ac..71c8a6227 100644 --- a/install/dist/conf/debian60.conf.php +++ b/install/dist/conf/debian60.conf.php @@ -51,6 +51,8 @@ $conf['services']['dns'] = true; $conf['services']['file'] = true; $conf['services']['db'] = true; $conf['services']['vserver'] = true; +$conf['services']['proxy'] = false; +$conf['services']['firewall'] = false; //* MySQL $conf['mysql']['installed'] = false; // will be detected automatically during installation @@ -183,6 +185,27 @@ $conf['jailkit']['jk_chrootsh'] = 'jk_chrootsh.ini'; $conf['jailkit']['jailkit_chroot_app_programs'] = '/usr/bin/groups /usr/bin/id /usr/bin/dircolors /usr/bin/lesspipe /usr/bin/basename /usr/bin/dirname /usr/bin/nano /usr/bin/pico'; $conf['jailkit']['jailkit_chroot_cron_programs'] = '/usr/bin/php /usr/bin/perl /usr/share/perl /usr/share/php'; +//* Squid +$conf['squid']['installed'] = false; // will be detected automatically during installation +$conf['squid']['config_dir'] = '/etc/squid'; +$conf['squid']['init_script'] = 'squid'; + +//* Nginx +$conf['nginx']['installed'] = false; // will be detected automatically during installation +$conf['nginx']['config_dir'] = '/etc/nginx'; +$conf['nginx']['vhost_conf_dir'] = '/etc/nginx/sites-available'; +$conf['nginx']['vhost_conf_enabled_dir'] = '/etc/nginx/sites-enabled'; +$conf['nginx']['init_script'] = 'nginx'; + +//* Ufw +$conf['ufw']['installed'] = false; +$conf['squid']['config_dir'] = '/etc/ufw'; +$conf['squid']['init_script'] = 'ufw'; + +//*Bastille-Firwall +$conf['bastille']['installed'] = false; +$conf['bastille']['config_dir'] = '/etc/Bastille'; + //* vlogger $conf['vlogger']['config_dir'] = '/etc'; diff --git a/install/install.php b/install/install.php index d79450f72..ba2b087c4 100644 --- a/install/install.php +++ b/install/install.php @@ -230,9 +230,31 @@ if($install_mode == 'standard') { $inst->configure_apps_vhost(); //* Configure Firewall - swriteln('Configuring Firewall'); - $inst->configure_firewall(); - + //swriteln('Configuring Firewall'); + //$inst->configure_firewall(); + //** Configure Firewall + if($conf['bastille']['installed'] == true) { + //* Configure Bastille Firewall + $conf['services']['firewall'] = true; + swriteln('Configuring Bastille Firewall'); + $inst->configure_firewall(); + } elseif($conf['ufw']['installed'] == true) { + //* Configure Ubuntu Firewall + $conf['services']['firewall'] = true; + swriteln('Configuring Ubuntu Firewall'); + $inst->configure_ufw_firewall(); + } + + if($conf['squid']['installed'] == true) { + $conf['services']['proxy'] = true; + swriteln('Configuring Squid'); + $inst->configure_squid(); + } else if($conf['nginx']['installed'] == true) { + $conf['services']['proxy'] = true; + swriteln('Configuring Nginx'); + $inst->configure_nginx(); + } + //* Configure ISPConfig swriteln('Installing ISPConfig'); @@ -267,7 +289,9 @@ if($install_mode == 'standard') { if($conf['mydns']['installed'] == true && $conf['mydns']['init_script'] != '' && is_executable($conf['init_scripts'].'/'.$conf['mydns']['init_script'])) system($conf['init_scripts'].'/'.$conf['mydns']['init_script'].' restart &> /dev/null'); if($conf['powerdns']['installed'] == true && $conf['powerdns']['init_script'] != '' && is_executable($conf['init_scripts'].'/'.$conf['powerdns']['init_script'])) system($conf['init_scripts'].'/'.$conf['powerdns']['init_script'].' restart &> /dev/null'); if($conf['bind']['installed'] == true && $conf['bind']['init_script'] != '' && is_executable($conf['init_scripts'].'/'.$conf['bind']['init_script'])) system($conf['init_scripts'].'/'.$conf['bind']['init_script'].' restart &> /dev/null'); - + if($conf['squid']['installed'] == true && $conf['squid']['init_script'] != '' && is_file($conf['init_scripts'].'/'.$conf['squid']['init_script'])) system($conf['init_scripts'].'/'.$conf['squid']['init_script'].' restart &> /dev/null'); + if($conf['nginx']['installed'] == true && $conf['nginx']['init_script'] != '' && is_file($conf['init_scripts'].'/'.$conf['nginx']['init_script'])) system($conf['init_scripts'].'/'.$conf['nginx']['init_script'].' restart &> /dev/null'); + if($conf['ufw']['installed'] == true && $conf['ufw']['init_script'] != '' && is_file($conf['init_scripts'].'/'.$conf['ufw']['init_script'])) system($conf['init_scripts'].'/'.$conf['ufw']['init_script'].' restart &> /dev/null'); }else{ //* In expert mode, we select the services in the following steps, only db is always available @@ -275,6 +299,8 @@ if($install_mode == 'standard') { $conf['services']['web'] = false; $conf['services']['dns'] = false; $conf['services']['db'] = true; + $conf['services']['firewall'] = false; + $conf['services']['proxy'] = false; //** Get Server ID @@ -416,6 +442,21 @@ if($install_mode == 'standard') { } + //** Configure Squid + if(strtolower($inst->simple_query('Configure Proxy Server', array('y','n'),'y') ) == 'y') { + if($conf['squid']['installed'] == true) { + $conf['services']['proxy'] = true; + swriteln('Configuring Squid'); + $inst->configure_squid(); + if($conf['squid']['init_script'] != '' && is_executable($conf['init_scripts'].'/'.$conf['squid']['init_script']))system($conf['init_scripts'].'/'.$conf['squid']['init_script'].' restart &> /dev/null'); + } else if($conf['nginx']['installed'] == true) { + $conf['services']['proxy'] = true; + swriteln('Configuring Nginx'); + $inst->configure_nginx(); + if($conf['nginx']['init_script'] != '' && is_executable($conf['init_scripts'].'/'.$conf['nginx']['init_script']))system($conf['init_scripts'].'/'.$conf['nginx']['init_script'].' restart &> /dev/null'); + } + } + //** Configure Apache swriteln("\nHint: If this server shall run the ISPConfig interface, select 'y' in the 'Configure Apache Server' option.\n"); if(strtolower($inst->simple_query('Configure Apache Server',array('y','n'),'y')) == 'y') { @@ -434,9 +475,25 @@ if($install_mode == 'standard') { //** Configure Firewall if(strtolower($inst->simple_query('Configure Firewall Server',array('y','n'),'y')) == 'y') { + if($conf['bastille']['installed'] == true) { + //* Configure Bastille Firewall + $conf['services']['firewall'] = true; + swriteln('Configuring Bastille Firewall'); + $inst->configure_firewall(); + } elseif($conf['ufw']['installed'] == true) { + //* Configure Ubuntu Firewall + $conf['services']['firewall'] = true; + swriteln('Configuring Ubuntu Firewall'); + $inst->configure_ufw_firewall(); + } + } + + //** Configure Firewall + /*if(strtolower($inst->simple_query('Configure Firewall Server',array('y','n'),'y')) == 'y') { swriteln('Configuring Firewall'); $inst->configure_firewall(); - } + }*/ + //** Configure ISPConfig :-) if(strtolower($inst->simple_query('Install ISPConfig Web Interface',array('y','n'),'y')) == 'y') { swriteln('Installing ISPConfig'); diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 2e74e2e7b..32f34ed66 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -130,7 +130,12 @@ class installer_base { if(is_installed('jk_chrootsh')) $conf['jailkit']['installed'] = true; if(is_installed('pdns_server') || is_installed('pdns_control')) $conf['powerdns']['installed'] = true; if(is_installed('named') || is_installed('bind') || is_installed('bind9')) $conf['bind']['installed'] = true; - + if(is_installed('squid')) $conf['squid']['installed'] = true; + if(is_installed('nginx')) $conf['nginx']['installed'] = true; + if(is_installed('iptables') && is_installed('ufw')) $conf['ufw']['installed'] = true; + if(is_dir("/etc/Bastille")) $conf['bastille']['installed'] = true; + + if ($conf['services']['web'] && $conf['apache']['installed'] && is_file($conf['apache']["vhost_conf_enabled_dir"]."/000-ispconfig.vhost")) $this->ispconfig_interface_installed = true; } /** Create the database for ISPConfig */ @@ -227,6 +232,11 @@ class installer_base { $tpl_ini_array['dns']['named_conf_path'] = $conf['bind']['named_conf_path']; $tpl_ini_array['dns']['named_conf_local_path'] = $conf['bind']['named_conf_local_path']; + if ($conf['nginx']['installed'] == true) { + $tpl_ini_array['nginx']['vhost_conf_dir'] = $conf['nginx']['vhost_conf_dir']; + $tpl_ini_array['nginx']['vhost_conf_enabled_dir'] = $conf['nginx']['vhost_conf_enabled_dir']; + } + if (array_key_exists('awstats', $conf)) { foreach ($conf['awstats'] as $aw_sett => $aw_value) { $tpl_ini_array['web']['awstats_'.$aw_sett] = $aw_value; @@ -242,6 +252,8 @@ class installer_base { $file_server_enabled = ($conf['services']['file'])?1:0; $db_server_enabled = ($conf['services']['db'])?1:0; $vserver_server_enabled = ($conf['services']['vserver'])?1:0; + $proxy_server_enabled = ($conf['services']['proxy'])?1:0; + $firewall_server_enabled = ($conf['services']['firewall'])?1:0; //** Get the database version number based on the patchfiles $found = true; @@ -261,13 +273,13 @@ class installer_base { if($conf['mysql']['master_slave_setup'] == 'y') { //* Insert the server record in master DB - $sql = "INSERT INTO `server` (`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_name`, `mail_server`, `web_server`, `dns_server`, `file_server`, `db_server`, `vserver_server`, `config`, `updated`, `active`, `dbversion`) VALUES (1, 1, 'riud', 'riud', 'r', '".$conf['hostname']."', '$mail_server_enabled', '$web_server_enabled', '$dns_server_enabled', '$file_server_enabled', '$db_server_enabled', '$vserver_server_enabled', '$server_ini_content', 0, 1, $current_db_version);"; + $sql = "INSERT INTO `server` (`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_name`, `mail_server`, `web_server`, `dns_server`, `file_server`, `db_server`, `vserver_server`, `config`, `updated`, `active`, `dbversion`,`firewall_server`,`proxy_server`) VALUES (1, 1, 'riud', 'riud', 'r', '".$conf['hostname']."', '$mail_server_enabled', '$web_server_enabled', '$dns_server_enabled', '$file_server_enabled', '$db_server_enabled', '$vserver_server_enabled', '$server_ini_content', 0, 1, $current_db_version, $proxy_server_enabled, $firewall_server_enabled);"; $this->dbmaster->query($sql); $conf['server_id'] = $this->dbmaster->insertID(); $conf['server_id'] = $conf['server_id']; //* Insert the same record in the local DB - $sql = "INSERT INTO `server` (`server_id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_name`, `mail_server`, `web_server`, `dns_server`, `file_server`, `db_server`, `vserver_server`, `config`, `updated`, `active`, `dbversion`) VALUES ('".$conf['server_id']."',1, 1, 'riud', 'riud', 'r', '".$conf['hostname']."', '$mail_server_enabled', '$web_server_enabled', '$dns_server_enabled', '$file_server_enabled', '$db_server_enabled', '$vserver_server_enabled', '$server_ini_content', 0, 1, $current_db_version);"; + $sql = "INSERT INTO `server` (`server_id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_name`, `mail_server`, `web_server`, `dns_server`, `file_server`, `db_server`, `vserver_server`, `config`, `updated`, `active`, `dbversion`,`firewall_server`,`proxy_server`) VALUES ('".$conf['server_id']."',1, 1, 'riud', 'riud', 'r', '".$conf['hostname']."', '$mail_server_enabled', '$web_server_enabled', '$dns_server_enabled', '$file_server_enabled', '$db_server_enabled', '$vserver_server_enabled', '$server_ini_content', 0, 1, $current_db_version, $proxy_server_enabled, $firewall_server_enabled);"; $this->db->query($sql); //* username for the ispconfig user @@ -277,7 +289,7 @@ class installer_base { } else { //* Insert the server, if its not a mster / slave setup - $sql = "INSERT INTO `server` (`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_name`, `mail_server`, `web_server`, `dns_server`, `file_server`, `db_server`, `vserver_server`, `config`, `updated`, `active`, `dbversion`) VALUES (1, 1, 'riud', 'riud', 'r', '".$conf['hostname']."', '$mail_server_enabled', '$web_server_enabled', '$dns_server_enabled', '$file_server_enabled', '$db_server_enabled', '$vserver_server_enabled', '$server_ini_content', 0, 1, $current_db_version);"; + $sql = "INSERT INTO `server` (`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_name`, `mail_server`, `web_server`, `dns_server`, `file_server`, `db_server`, `vserver_server`, `config`, `updated`, `active`, `dbversion`,`firewall_server`,`proxy_server`) VALUES (1, 1, 'riud', 'riud', 'r', '".$conf['hostname']."', '$mail_server_enabled', '$web_server_enabled', '$dns_server_enabled', '$file_server_enabled', '$db_server_enabled', '$vserver_server_enabled', '$server_ini_content', 0, 1, $current_db_version, $proxy_server_enabled, $firewall_server_enabled);"; $this->db->query($sql); $conf['server_id'] = $this->db->insertID(); $conf['server_id'] = $conf['server_id']; @@ -1108,6 +1120,67 @@ class installer_base { if(!is_group('sshusers')) caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); } + + public function configure_nginx() + { + global $conf; + $row = $this->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = ".$conf["server_id"].""); + $ip_address = gethostbyname($row["server_name"]); + $server_name = $row["server_name"]; + + //setup proxy.conf + $configfile = 'proxy.conf'; + if(is_file($conf["nginx"]["config_dir"].'/'.$configfile)) copy($conf["nginx"]["config_dir"].'/'.$configfile,$conf["nginx"]["config_dir"].'/'.$configfile.'~'); + if(is_file($conf["nginx"]["config_dir"].'/'.$configfile.'~')) exec('chmod 400 '.$conf["nginx"]["config_dir"].'/'.$configfile.'~'); + $content = rf("tpl/nginx_".$configfile.".master"); + wf($conf["nginx"]["config_dir"].'/'.$configfile,$content); + exec('chmod 600 '.$conf["nginx"]["config_dir"].'/'.$configfile); + exec('chown root:root '.$conf["nginx"]["config_dir"].'/'.$configfile); + + //setup conf.d/cache.conf + $configfile = 'cache.conf'; + if(is_file($conf["nginx"]["config_dir"].'/conf.d/'.$configfile)) copy($conf["nginx"]["config_dir"].'/conf.d/'.$configfile,$conf["nginx"]["config_dir"].'/conf.d/'.$configfile.'~'); + if(is_file($conf["nginx"]["config_dir"].'/conf.d/'.$configfile.'~')) exec('chmod 400 '.$conf["nginx"]["config_dir"].'/conf.d/'.$configfile.'~'); + $content = rf("tpl/nginx_".$configfile.".master"); + wf($conf["nginx"]["config_dir"].'/conf.d/'.$configfile,$content); + exec('chmod 600 '.$conf["nginx"]["config_dir"].'/conf.d/'.$configfile); + exec('chown root:root '.$conf["nginx"]["config_dir"].'/conf.d/'.$configfile); + + //setup cache directories + mkdir('/var/cache/nginx/cache'); + exec('chown www-data:www-data /var/cache/nginx/cache'); + mkdir('/var/cache/nginx/temp'); + exec('chown www-data:www-data /var/cache/nginx/temp'); + } + + public function configure_squid() + { + global $conf; + $row = $this->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = ".$conf["server_id"].""); + $ip_address = gethostbyname($row["server_name"]); + $server_name = $row["server_name"]; + + $configfile = 'squid.conf'; + if(is_file($conf["squid"]["config_dir"].'/'.$configfile)) copy($conf["squid"]["config_dir"].'/'.$configfile,$conf["squid"]["config_dir"].'/'.$configfile.'~'); + if(is_file($conf["squid"]["config_dir"].'/'.$configfile.'~')) exec('chmod 400 '.$conf["squid"]["config_dir"].'/'.$configfile.'~'); + $content = rf("tpl/".$configfile.".master"); + $content = str_replace('{server_name}',$server_name,$content); + $content = str_replace('{ip_address}',$ip_address, $content); + $content = str_replace('{config_dir}',$conf['squid']['config_dir'], $content); + wf($conf["squid"]["config_dir"].'/'.$configfile,$content); + exec('chmod 600 '.$conf["squid"]["config_dir"].'/'.$configfile); + exec('chown root:root '.$conf["squid"]["config_dir"].'/'.$configfile); + } + + public function configure_ufw_firewall() + { + $configfile = 'ufw.conf'; + if(is_file('/etc/ufw/ufw.conf')) copy('/etc/ufw/ufw.conf','/etc/ufw/ufw.conf~'); + $content = rf("tpl/".$configfile.".master"); + wf('/etc/ufw/ufw.conf',$content); + exec('chmod 600 /etc/ufw/ufw.conf'); + exec('chown root:root /etc/ufw/ufw.conf'); + } public function configure_firewall() { global $conf; @@ -1426,13 +1499,14 @@ class installer_base { $file_server_enabled = ($conf['services']['file'])?1:0; $db_server_enabled = ($conf['services']['db'])?1:0; $vserver_server_enabled = ($conf['services']['vserver'])?1:0; + $proxy_server_enabled = ($conf['services']['proxy'])?1:0; + $firewall_server_enabled = ($conf['services']['firewall'])?1:0; - - $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' WHERE server_id = ".intval($conf['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' WHERE server_id = ".intval($conf['server_id']); if($conf['mysql']['master_slave_setup'] == 'y') { $this->dbmaster->query($sql); diff --git a/install/lib/update.lib.php b/install/lib/update.lib.php index 8faff1a2c..4cc735568 100644 --- a/install/lib/update.lib.php +++ b/install/lib/update.lib.php @@ -95,6 +95,9 @@ function updateDbAndIni() { $conf['services']['file'] = ($tmp['file_server'] == 1)?true:false; $conf['services']['db'] = ($tmp['db_server'] == 1)?true:false; $conf['services']['vserver'] = ($tmp['vserver_server'] == 1)?true:false; + $conf['services']['proxy'] = ($tmp['proxy_server'] == 1)?true:false; + $conf['services']['firewall'] = ($tmp['firewall_server'] == 1)?true:false; + $conf['postfix']['vmail_mailbox_base'] = $ini_array['mail']['homedir_path']; //* Do incremental DB updates only on installed ISPConfig versions > 3.0.3 diff --git a/install/sql/incremental/upd_0009.sql b/install/sql/incremental/upd_0009.sql new file mode 100644 index 000000000..9da60c134 --- /dev/null +++ b/install/sql/incremental/upd_0009.sql @@ -0,0 +1,66 @@ +CREATE TABLE IF NOT EXISTS `proxy_reverse` ( + `rewrite_id` int(11) NOT NULL auto_increment, + `sys_userid` int(11) unsigned NOT NULL default '0', + `sys_groupid` int(11) unsigned NOT NULL default '0', + `sys_perm_user` varchar(5) default NULL, + `sys_perm_group` varchar(5) default NULL, + `sys_perm_other` varchar(5) default NULL, + `server_id` int(11) unsigned NOT NULL default '0', + `rewrite_url_src` varchar(100) NOT NULL, + `rewrite_url_dst` varchar(100) NOT NULL, + `active` enum('n','y') NOT NULL default 'y', + PRIMARY KEY (`rewrite_id`) +) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; + + +CREATE TABLE IF NOT EXISTS `firewall_filter` ( + `firewall_id` int(11) unsigned NOT NULL auto_increment, + `sys_userid` int(11) unsigned NOT NULL default '0', + `domain_id` int(11) NOT NULL, + `sys_groupid` int(11) unsigned NOT NULL default '0', + `sys_perm_user` varchar(5) default NULL, + `sys_perm_group` varchar(5) default NULL, + `sys_perm_other` varchar(5) default NULL, + `server_id` int(11) unsigned NOT NULL default '0', + `rule_name` varchar(100) default NULL, + `rule_id` int(11) default 1, + `src_ip` varchar(20) NOT NULL, + `src_netmask` varchar(20) NOT NULL, + `dst_ip` varchar(20) NOT NULL, + `dst_netmask` varchar(20) NOT NULL, + `src_from_port` varchar(10) NOT NULL, + `src_to_port` varchar(10) NOT NULL, + `dst_to_port` varchar(10) NOT NULL, + `dst_from_port` varchar(10) NOT NULL, + `protocol` varchar(10) default 'tcp', + `inbound_policy` enum('allow','deny','reject','limit') default 'allow', + `outbound_policy` enum('allow','deny','reject','limit') default 'allow', + `active` enum('n','y') NOT NULL default 'y', + `client_id` int(11) NOT NULL, + PRIMARY KEY (`firewall_id`) +) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `firewall_forward` ( + `firewall_id` int(11) unsigned NOT NULL auto_increment, + `sys_userid` int(11) unsigned NOT NULL default '0', + `domain_id` int(11) NOT NULL, + `sys_groupid` int(11) unsigned NOT NULL default '0', + `sys_perm_user` varchar(5) default NULL, + `sys_perm_group` varchar(5) default NULL, + `sys_perm_other` varchar(5) default NULL, + `server_id` int(11) unsigned NOT NULL default '0', + `application_name` varchar(100) default NULL, + `dst_ip` varchar(20) NOT NULL, + `src_from_port` varchar(10) NOT NULL, + `src_to_port` varchar(10) NOT NULL, + `dst_to_port` varchar(10) NOT NULL, + `dst_from_port` varchar(10) NOT NULL, + `protocol` int(3) default 0, + `active` enum('n','y') NOT NULL default 'y', + `client_id` int(11) NOT NULL, + PRIMARY KEY (`firewall_id`) +) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=utf8; + +alter table `server` add column `proxy_server` tinyint(1) not null after `vserver_server`; +alter table `server` add column `firewall_server` tinyint(1) not null after `proxy_server`; +alter table `web_domain` add column `nginx_directives` mediumtext not null after `apache_directives`; diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index 1eb1d5793..ff0cfb14e 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -691,6 +691,8 @@ CREATE TABLE `server` ( `file_server` tinyint(1) NOT NULL default '0', `db_server` tinyint(1) NOT NULL default '0', `vserver_server` tinyint(1) NOT NULL default '0', + `proxy_server` tinyint(1) NOT NULL default '0', + `firewall_server` tinyint(1) NOT NULL default '0', `config` text NOT NULL, `updated` bigint(20) unsigned NOT NULL default '0', `mirror_server_id` int(11) unsigned NOT NULL default '0', @@ -1141,6 +1143,7 @@ CREATE TABLE `web_domain` ( `stats_type` varchar(255) default 'webalizer', `allow_override` varchar(255) NOT NULL default 'All', `apache_directives` mediumtext, + `nginx_directives` mediumtext, `php_open_basedir` mediumtext, `custom_php_ini` mediumtext, `backup_interval` VARCHAR( 255 ) NOT NULL DEFAULT 'none', @@ -1150,6 +1153,8 @@ CREATE TABLE `web_domain` ( PRIMARY KEY (`domain_id`) ) ENGINE=MyISAM AUTO_INCREMENT=1; + + -- -------------------------------------------------------- -- @@ -1660,6 +1665,70 @@ INSERT INTO `help_faq` VALUES (1,1,0,'I\'d like to know ...','Yes, of course.',1 ALTER TABLE client ADD COLUMN company_id varchar(30); + +CREATE TABLE `proxy_reverse` ( + `rewrite_id` int(11) NOT NULL auto_increment, + `sys_userid` int(11) unsigned NOT NULL default '0', + `sys_groupid` int(11) unsigned NOT NULL default '0', + `sys_perm_user` varchar(5) default NULL, + `sys_perm_group` varchar(5) default NULL, + `sys_perm_other` varchar(5) default NULL, + `server_id` int(11) unsigned NOT NULL default '0', + `rewrite_url_src` varchar(100) NOT NULL, + `rewrite_url_dst` varchar(100) NOT NULL, + `active` enum('n','y') NOT NULL default 'y', + PRIMARY KEY (`rewrite_id`) +) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; + + +CREATE TABLE `firewall_filter` ( + `firewall_id` int(11) unsigned NOT NULL auto_increment, + `sys_userid` int(11) unsigned NOT NULL default '0', + `domain_id` int(11) NOT NULL, + `sys_groupid` int(11) unsigned NOT NULL default '0', + `sys_perm_user` varchar(5) default NULL, + `sys_perm_group` varchar(5) default NULL, + `sys_perm_other` varchar(5) default NULL, + `server_id` int(11) unsigned NOT NULL default '0', + `rule_name` varchar(100) default NULL, + `rule_id` int(11) default 1, + `src_ip` varchar(20) NOT NULL, + `src_netmask` varchar(20) NOT NULL, + `dst_ip` varchar(20) NOT NULL, + `dst_netmask` varchar(20) NOT NULL, + `src_from_port` varchar(10) NOT NULL, + `src_to_port` varchar(10) NOT NULL, + `dst_to_port` varchar(10) NOT NULL, + `dst_from_port` varchar(10) NOT NULL, + `protocol` varchar(10) default 'tcp', + `inbound_policy` enum('allow','deny','reject','limit') default 'allow', + `outbound_policy` enum('allow','deny','reject','limit') default 'allow', + `active` enum('n','y') NOT NULL default 'y', + `client_id` int(11) NOT NULL, + PRIMARY KEY (`firewall_id`) +) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=utf8; + +CREATE TABLE `firewall_forward` ( + `firewall_id` int(11) unsigned NOT NULL auto_increment, + `sys_userid` int(11) unsigned NOT NULL default '0', + `domain_id` int(11) NOT NULL, + `sys_groupid` int(11) unsigned NOT NULL default '0', + `sys_perm_user` varchar(5) default NULL, + `sys_perm_group` varchar(5) default NULL, + `sys_perm_other` varchar(5) default NULL, + `server_id` int(11) unsigned NOT NULL default '0', + `application_name` varchar(100) default NULL, + `dst_ip` varchar(20) NOT NULL, + `src_from_port` varchar(10) NOT NULL, + `src_to_port` varchar(10) NOT NULL, + `dst_to_port` varchar(10) NOT NULL, + `dst_from_port` varchar(10) NOT NULL, + `protocol` int(3) default 0, + `active` enum('n','y') NOT NULL default 'y', + `client_id` int(11) NOT NULL, + PRIMARY KEY (`firewall_id`) +) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=utf8; + -- -------------------------------------------------------- SET FOREIGN_KEY_CHECKS = 1; diff --git a/install/tpl/nginx_cache.conf.master b/install/tpl/nginx_cache.conf.master new file mode 100644 index 000000000..1cd286382 --- /dev/null +++ b/install/tpl/nginx_cache.conf.master @@ -0,0 +1,6 @@ +proxy_temp_path /var/cache/nginx/temp; +proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=global:60m inactive=15m max_size=1G; +proxy_cache_valid 200 302 10m; +proxy_cache_valid 301 1h; +proxy_cache_valid 404 3m; +proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504; diff --git a/install/tpl/nginx_proxy.conf.master b/install/tpl/nginx_proxy.conf.master new file mode 100644 index 000000000..d8711d046 --- /dev/null +++ b/install/tpl/nginx_proxy.conf.master @@ -0,0 +1,34 @@ +proxy_cache global; +proxy_redirect off; +proxy_set_header Host $host; +proxy_set_header X-Real-IP $remote_addr; +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +proxy_pass_header Set-Cookie; +client_max_body_size 10m; +client_body_buffer_size 128k; +proxy_connect_timeout 90; +proxy_send_timeout 90; +proxy_read_timeout 90; +proxy_buffers 32 4k; + +set $cache_key $scheme$host$uri$is_args$args$cookie_user; +proxy_cache_key $cache_key; +proxy_cache_valid 200 10h; +expires 3d; + +### force timeouts if one of backend is died ## +proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; + +location = /status { + stub_status on; + allow 127.0.0.1; + allow 192.168.1.0; + deny all; +} + +location ~ /purge(/.*) { + allow 127.0.0.1; + allow 192.168.1.0; + deny all; + proxy_cache_purge global $cache_key; +} diff --git a/install/tpl/squid.conf.master b/install/tpl/squid.conf.master new file mode 100644 index 000000000..2ae00d24d --- /dev/null +++ b/install/tpl/squid.conf.master @@ -0,0 +1,224 @@ + +# This configuration file requires squid 2.5+. It is untested with squid 3.x. + +# BASIC CONFIGURATION +# ------------------------------------------------------------------------------ + +visible_hostname {server_name} + + + +# port on which to listen + +http_port {ip_address}:80 vhost defaultsite={server_name} + + +# set cache directory and size (1000 MB) - be sure to set the cache size to +# about 10% less than the physical space available to leave room for squid's +# swap files and other temp files +cache_dir ufs /var/spool/squid 100 16 256 +cache_mgr webmaster@{server_name} + + + + +# LOGS +# ------------------------------------------------------------------------------ +log_icp_queries off +cache_access_log /var/log/squid/access.log +cache_log /var/log/squid/cache.log +cache_store_log /var/log/squid/store.log +cache_effective_user nobody +cache_effective_group nogroup +# emulate_httpd_log off + + +# RESOURCES +# ------------------------------------------------------------------------------ +# amount of memory used for caching recently accessed objects - defaults to 8 MB +cache_mem 64 MB +maximum_object_size 10 MB # max cached object size +maximum_object_size_in_memory 300 KB # max cached-in-memory object size + + +# ACCESS CONTROL +# ------------------------------------------------------------------------------ + +# Basic ACLs +acl all src 0.0.0.0/0.0.0.0 +acl localhost src 127.0.0.1/32 +acl ssl_ports port 443 563 +acl safe_ports port 80 443 + +acl openvz_instances src 192.168.1.0/24 +acl squid_server src localhost +acl manager proto cache_object +acl connect method connect + + +# deny requests to unknown ports +http_access deny !safe_ports + +acl accelerated_protocols proto http https +acl accelerated_domains dstdomain url_regex -i "{config_dir}/domains.txt" +acl accelerated_ports myport 80 443 + +http_access allow accelerated_domains +http_access allow accelerated_ports +http_access allow accelerated_protocols + + +acl purge method PURGE +http_access allow squid_server purge +http_access allow openvz_instances purge +http_access deny purge + +# Reply access +http_reply_access allow all + +# Cache manager setup - cache manager can only connect from localhost +# only allow cache manager access from localhost +http_access allow manager localhost +http_access deny manager +# deny connect to other than ssl ports +http_access deny connect !ssl_ports + +# ICP access - anybody can access icp methods +icp_access allow localhost + +# And finally deny all other access to this proxy +http_access deny all + + +# CACHE PEERS +# ------------------------------------------------------------------------------ + +# CONFIGURE THE CACHE PEERS. FIRST PORT IS THE HTTP PORT, SECOND PORT +# IS THE ICP PORT. REMEMBER TO ENABLE 'icp-server' ON YOUR 'zope.conf' +# LISTENING ON THE ICP PORT YOU USE HERE. +# acl in_backendpool dstdomain backendpool +# cache_peer 127.0.0.1 parent 8080 9090 no-digest no-netdb-exchange +# cache_peer 192.168.0.3 parent 8081 9091 no-digest no-netdb-exchange + +# cache_peer_access 127.0.0.1 allow in_backendpool +# cache_peer_access 127.0.0.1 deny all + +# cache_peer_access 192.168.0.3 allow in_backendpool +# cache_peer_access 192.168.0.3 deny all + +# IF YOU NEED TO FORWARD REQUESTS TO HOSTS NOT IN THE POOL THIS IS +# WHERE YOU ALLOW THE TARGET DOMAINS +# acl local_servers dstdomain some.mysite.com other.mysite.com +always_direct allow all + +# THE FOLLOWING DIRECTIVE IS NEEDED TO MAKE 'backendpool' RESOLVE TO +# THE POOL OF CACHE PEERS. +# never_direct allow all +# icp_access allow all + +# PROXY ON, NEEDED TO MAKE CACHE PEERS INTERCOMMUNICATE +# httpd_accel_with_proxy on + + +# REDIRECTOR PROGRAM +# ------------------------------------------------------------------------------ + + +url_rewrite_program {config_dir}/iRedirector.py +url_rewrite_children 1 +url_rewrite_concurrency 20 +url_rewrite_host_header off + + +# SPECIFY WHAT REQUESTS SQUID SHOULD CACHE +# ------------------------------------------------------------------------------ + +# Control what squid caches. We want to have squid handle content that is not +# personalized and that does not require any kind of authorization. +# +# 1) Always cache static content in squid + +acl static_content urlpath_regex -i \.(jpg|jpeg|gif|png|tiff|tif|svg|swf|ico|css|js|vsd|doc|ppt|pps|xls|pdf|mp3|mp4|m4a|ogg|mov|avi|wmv|sxw|zip|gz|bz2|tgz|tar|rar|odc|odb|odf|odg|odi|odp|ods|odt|sxc|sxd|sxi|sxw|dmg|torrent|deb|msi|iso|rpm)$ +no_cache allow static_content + +# 2) (OPTIONAL) Prevent squid from caching an item that is the result of a POST + +acl post_requests method POST +no_cache deny post_requests + +# 3) (OPTIONAL) Prevent squid from caching items with items in the query string +# If this is uncommented, squid will treat a url with 2 different query strings +# as 2 different urls when caching. + +# XXX: where did this example go? + +# 4) Prevent squid from caching requests from authenticated users or conditional +# GETs with an If-None-Match header (since squid doesn't know about ETags) +# We use an external python method to check these conditions and pass in the +# value of the __ac cookie (two different ways to allow for different cookie +# delimiters), the HTTP Authorization header, and the If-None-Match header. +# +# Squid caches the results of the external python method, so for debugging, set +# the options ttl=0 negative_ttl=0 so you can see what is going on + +# external_acl_type is_cacheable_type children=20 ttl=0 negative_ttl=0 %{Cookie:__ac} %{Cookie:;__ac} %{Authorization} %{If-None-Match} /etc/squid/squidAcl.py + +#external_acl_type is_cacheable_type protocol=2.5 children=20 %{Cookie:__ac} %{Cookie:;__ac} %{Authorization} %{If-None-Match} /etc/squid/squidAcl.py +#acl is_cacheable external is_cacheable_type +#no_cache allow is_cacheable + + +collapsed_forwarding on +#refresh_stale_hit on + + +# Explicitly disallow squid from handling anything else +no_cache deny all + + +# SPECIFY EFFECTS OF A BROWSER REFRESH +# ------------------------------------------------------------------------------ + +# RELOAD_INTO_IMS CAUSES WEIRD SQUID BEHAVIOR - IT APPEARS TO CAUSE FILES WITH +# INAPPROPRIATE HEADERS TO END UP IN THE CACHE, AND AS A RESULT BROWSERS END +# UP MAKING LOTS OF EXTRA (CONDITIONAL) REQUESTS WHEN THEY WOULD OTHERWISE MAKE +# NO REQUESTS. DO NOT USE! + +# Tell squid how to handle expiration times for content with no explicit expiration +# Assume static content is fresh for at least an hour and at most a day +#refresh_pattern -i \.(jpg|jpeg|gif|png|tiff|tif|svg|swf|ico|css|js|vsd|doc|ppt|pps|xls|pdf|mp3|mp4|m4a|ogg|mov|avi|wmv|sxw|zip|gz|bz2|tar|rar|odc|odb|odf|odg|odi|odp|ods|odt|sxc|sxd|sxi|sxw|dmg|torrent|deb|msi|iso|rpm)$ 60 50% 1440 reload-into-ims +#refresh_pattern . 0 20% 1440 + +# Change force-refresh requests into conditional gets using if-modified-since +#reload_into_ims on + +# DEBUGGING +# ------------------------------------------------------------------------------ +# debug_options ALL,1 33,2 # use this for debugging acls + debug_options ALL,8 + + +# MISCELLANEOUS +# ------------------------------------------------------------------------------ +# have squid handle all requests with ranges +# range_offset_limit -1 + +# amount of time squid waits for existing requests to be serviced before shutting down +shutdown_lifetime 1 seconds + +# allow squid to process multiple requests simultaneously if client is pipelining +pipeline_prefetch on + +# allow white spaces to be included in URLs +uri_whitespace allow + + +# OTHER PARAMETERS THAT MAY BE OF INTEREST +# ------------------------------------------------------------------------------ + +# logfile_rotate 0 +# reload_into_ims off +#error_directory /usr/local/squid/share/errors/English + + + diff --git a/install/tpl/ufw.conf.master b/install/tpl/ufw.conf.master new file mode 100644 index 000000000..9dc02d367 --- /dev/null +++ b/install/tpl/ufw.conf.master @@ -0,0 +1,8 @@ +# /etc/ufw/ufw.conf +# + +# set to yes to start on boot +ENABLED=yes + +# set to one of 'off', 'low', 'medium', 'high' +LOGLEVEL=low diff --git a/install/update.php b/install/update.php index fa1cb8313..920729924 100644 --- a/install/update.php +++ b/install/update.php @@ -256,7 +256,7 @@ if($reconfigure_services_answer == 'yes') { $inst->configure_getmail(); } - if($conf['services']['web']) { + if($conf['services']['web'] && $conf['pureftpd']['installed'] == true) { //** Configure Pureftpd swriteln('Configuring Pureftpd'); $inst->configure_pureftpd(); @@ -295,25 +295,41 @@ if($reconfigure_services_answer == 'yes') { swriteln('Configuring Database'); $inst->configure_dbserver(); - - //if(@is_dir('/etc/Bastille')) { - //* Configure Firewall - swriteln('Configuring Firewall'); - $inst->configure_firewall(); - //} + + if($conf['services']['firewall']) { + if($conf['bastille']['installed'] == true) { + //* Configure Bastille Firewall + swriteln('Configuring Bastille Firewall'); + $inst->configure_firewall(); + } elseif($conf['ufw']['installed'] == true) { + //* Configure Ubuntu Firewall + swriteln('Configuring Ubuntu Firewall'); + $inst->configure_ufw_firewall(); + } + } + + if($conf['squid']['installed'] == true) { + swriteln('Configuring Squid'); + $inst->configure_squid(); + } else if($conf['nginx']['installed'] == true) { + swriteln('Configuring Nginx'); + $inst->configure_nginx(); + } } //** Configure ISPConfig swriteln('Updating ISPConfig'); -//** Customise the port ISPConfig runs on -$ispconfig_port_number = get_ispconfig_port_number(); -$conf['apache']['vhost_port'] = $inst->free_query('ISPConfig Port', $ispconfig_port_number); - -// $ispconfig_ssl_default = (is_ispconfig_ssl_enabled() == true)?'y':'n'; -if(strtolower($inst->simple_query('Create new ISPConfig SSL certificate',array('yes','no'),'no')) == 'yes') { - $inst->make_ispconfig_ssl_cert(); +if ($conf['services']['web'] && $inst->ispconfig_interface_installed) { + //** Customise the port ISPConfig runs on + $ispconfig_port_number = get_ispconfig_port_number(); + $conf['apache']['vhost_port'] = $inst->free_query('ISPConfig Port', $ispconfig_port_number); + + // $ispconfig_ssl_default = (is_ispconfig_ssl_enabled() == true)?'y':'n'; + if(strtolower($inst->simple_query('Create new ISPConfig SSL certificate',array('yes','no'),'no')) == 'yes') { + $inst->make_ispconfig_ssl_cert(); + } } $inst->install_ispconfig(); @@ -351,6 +367,15 @@ if($reconfigure_services_answer == 'yes') { if($conf['powerdns']['installed'] == true && $conf['powerdns']['init_script'] != '' && is_executable($conf['init_scripts'].'/'.$conf['powerdns']['init_script'])) system($conf['init_scripts'].'/'.$conf['powerdns']['init_script'].' restart &> /dev/null'); if($conf['bind']['installed'] == true && $conf['bind']['init_script'] != '' && is_executable($conf['init_scripts'].'/'.$conf['bind']['init_script'])) system($conf['init_scripts'].'/'.$conf['bind']['init_script'].' restart &> /dev/null'); } + + if($conf['services']['proxy']) { + if($conf['squid']['installed'] == true && $conf['squid']['init_script'] != '' && is_executable($conf['init_scripts'].'/'.$conf['squid']['init_script'])) system($conf['init_scripts'].'/'.$conf['squid']['init_script'].' restart &> /dev/null'); + if($conf['nginx']['installed'] == true && $conf['nginx']['init_script'] != '' && is_executable($conf['init_scripts'].'/'.$conf['nginx']['init_script'])) system($conf['init_scripts'].'/'.$conf['nginx']['init_script'].' restart &> /dev/null'); + } + + if($conf['services']['firewall']) { + if($conf['ufw']['installed'] == true && $conf['ufw']['init_script'] != '' && is_executable($conf['init_scripts'].'/'.$conf['ufw']['init_script'])) system($conf['init_scripts'].'/'.$conf['squid']['init_script'].' restart &> /dev/null'); + } } echo "Update finished.\n"; diff --git a/interface/lib/classes/plugin.inc.php b/interface/lib/classes/plugin.inc.php index 450efd04a..910cc5705 100644 --- a/interface/lib/classes/plugin.inc.php +++ b/interface/lib/classes/plugin.inc.php @@ -86,7 +86,6 @@ class plugin { $_SESSION['s']['plugin_cache'][$event_name][] = array('plugin' => $plugin_name, 'function' => $function_name); if($this->debug) $app->log("Plugin '$plugin_name' has registered the function '$function_name' for the event '$event_name'",LOGLEVEL_DEBUG); - } /* @@ -135,25 +134,31 @@ class plugin { //* Internal function to load the plugin and call the event function in the plugin. private function callPluginEvent($event_name,$data) { global $app; - + //* execute the functions for the events if(is_array($_SESSION['s']['plugin_cache'][$event_name])) { foreach($_SESSION['s']['plugin_cache'][$event_name] as $rec) { $plugin_name = $rec['plugin']; $function_name = $rec['function']; $plugin_file = ISPC_LIB_PATH.FS_DIV.'plugins'.FS_DIV.$plugin_name.'.inc.php'; + + if(is_file($plugin_file)) { if(!isset($app->loaded_plugins[$plugin_name])) { include_once($plugin_file); $app->loaded_plugins[$plugin_name] = new $plugin_name; } + if($this->debug) $app->log("Called method: '$function_name' in plugin '$plugin_name' for event '$event_name'",LOGLEVEL_DEBUG); // call_user_method($function_name,$app->loaded_plugins[$plugin_name],$event_name,$data); + call_user_func(array($app->loaded_plugins[$plugin_name],$function_name),$event_name,$data); + } } } + } // end functiom callPluginEvent diff --git a/interface/lib/classes/tform_actions.inc.php b/interface/lib/classes/tform_actions.inc.php index f1978ff2f..d5254c850 100644 --- a/interface/lib/classes/tform_actions.inc.php +++ b/interface/lib/classes/tform_actions.inc.php @@ -315,7 +315,7 @@ class tform_actions { $next_tab = $app->tform->getCurrentTab(); $this->loadPlugins($next_tab); - + // Call plugin foreach($this->plugins as $plugin) { $plugin->onDelete(); diff --git a/interface/lib/config.inc.php b/interface/lib/config.inc.php index 84a15e603..b584146bb 100644 --- a/interface/lib/config.inc.php +++ b/interface/lib/config.inc.php @@ -50,7 +50,7 @@ define('ISPC_APP_VERSION', '3.0.2'); //** Database $conf['db_type'] = 'mysql'; $conf['db_host'] = 'localhost'; -$conf['db_database'] = 'ispconfig3_stable'; +$conf['db_database'] = 'dbispconfig'; $conf['db_user'] = 'root'; $conf['db_password'] = ''; $conf['db_charset'] = 'utf8'; // same charset as html-charset - (HTML --> MYSQL: "utf-8" --> "utf8", "iso-8859-1" --> "latin1") @@ -133,6 +133,7 @@ $conf['logo'] = 'themes/default/images/ispc_logo.png'; $conf['language'] = 'en'; $conf['debug_language'] = false; + //** Misc. $conf['interface_logout_url'] = ''; // example: http://www.domain.tld/ diff --git a/interface/lib/plugins/sites_web_domain_plugin.inc.php b/interface/lib/plugins/sites_web_domain_plugin.inc.php index 85a4cc04f..f41edd620 100644 --- a/interface/lib/plugins/sites_web_domain_plugin.inc.php +++ b/interface/lib/plugins/sites_web_domain_plugin.inc.php @@ -39,8 +39,7 @@ class sites_web_domain_plugin { Function to create the sites_web_domain rule and insert it into the custom rules */ function sites_web_domain_edit($event_name, $page_form) { - global $app, $conf; - + global $app, $conf; // make sure that the record belongs to the clinet group and not the admin group when a dmin inserts it // also make sure that the user can not delete domain created by a admin if($_SESSION["s"]["user"]["typ"] == 'admin' && isset($page_form->dataRecord["client_group_id"])) { diff --git a/interface/web/admin/form/server.tform.php b/interface/web/admin/form/server.tform.php index 20947c8a0..bd556b27b 100644 --- a/interface/web/admin/form/server.tform.php +++ b/interface/web/admin/form/server.tform.php @@ -102,6 +102,18 @@ $form["tabs"]['services'] = array ( 'default' => '0', 'value' => array(0 => 0,1 => 1) ), + 'proxy_server' => array ( + 'datatype' => 'INTEGER', + 'formtype' => 'CHECKBOX', + 'default' => '0', + 'value' => array(0 => 0,1 => 1) + ), + 'firewall_server' => array ( + 'datatype' => 'INTEGER', + 'formtype' => 'CHECKBOX', + 'default' => '0', + 'value' => array(0 => 0,1 => 1) + ), 'mirror_server_id' => array ( 'datatype' => 'INTEGER', 'formtype' => 'TEXT', diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php index c9b3500f0..4db9551ed 100644 --- a/interface/web/admin/form/server_config.tform.php +++ b/interface/web/admin/form/server_config.tform.php @@ -751,6 +751,68 @@ $form["tabs"]['jailkit'] = array( ) ); +$form["tabs"]['ufw_firewall'] = array ( + 'title' => "UFW Firewall", + 'width' => 80, + 'template' => "templates/server_config_ufw_edit.htm", + 'fields' => array ( + ################################## + # Begin Datatable fields + ################################## + 'ufw_enable' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'no', + 'value' => array(0 => 'no',1 => 'yes') + ), + 'ufw_manage_builtins' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'no', + 'value' => array(0 => 'no',1 => 'yes') + ), + 'ufw_ipv6' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'no', + 'value' => array(0 => 'no',1 => 'yes') + ), + 'ufw_default_input_policy' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'default' => 'ACCEPT', + 'value' => array('ACCEPT' => 'accept', 'DROP' => 'drop', 'REJECT' => 'reject') + ), + 'ufw_default_output_policy' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'default' => 'ACCEPT', + 'value' => array('ACCEPT' => 'accept', 'DROP' => 'drop', 'REJECT' => 'reject') + ), + 'ufw_default_forward_policy' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'default' => 'ACCEPT', + 'value' => array('ACCEPT' => 'accept', 'DROP' => 'drop', 'REJECT' => 'reject') + ), + 'ufw_default_application_policy' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'default' => 'DROP', + 'value' => array('ACCEPT' => 'accept', 'DROP' => 'drop', 'REJECT' => 'reject') + ), + 'ufw_log_level' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'default' => 'low', + 'value' => array('low' => 'low', 'medium' => 'medium', 'high' => 'high') + ) + ################################## + # ENDE Datatable fields + ################################## + ) +); + $form["tabs"]['vlogger'] = array( 'title' => "vlogger", diff --git a/interface/web/admin/lib/lang/en_server.lng b/interface/web/admin/lib/lang/en_server.lng index dcd46c582..4130201b7 100644 --- a/interface/web/admin/lib/lang/en_server.lng +++ b/interface/web/admin/lib/lang/en_server.lng @@ -7,6 +7,8 @@ $wb["dns_server_txt"] = 'DNS-Server'; $wb["file_server_txt"] = 'Fileserver'; $wb["db_server_txt"] = 'DB-Server'; $wb["vserver_server_txt"] = 'VServer-Server'; +$wb["proxy_server_txt"] = 'Proxy-Server'; +$wb["firewall_server_txt"] = 'Firewall-Server'; $wb["active_txt"] = 'Active'; $wb["mirror_server_id_txt"] = 'Is mirror of Server'; $wb["- None -"] = '- None -'; diff --git a/interface/web/admin/lib/lang/en_server_config.lng b/interface/web/admin/lib/lang/en_server_config.lng index f672e9943..7c0c459f1 100644 --- a/interface/web/admin/lib/lang/en_server_config.lng +++ b/interface/web/admin/lib/lang/en_server_config.lng @@ -1,12 +1,17 @@ \ No newline at end of file diff --git a/interface/web/admin/lib/lang/en_server_list.lng b/interface/web/admin/lib/lang/en_server_list.lng index d15701e80..164468e70 100644 --- a/interface/web/admin/lib/lang/en_server_list.lng +++ b/interface/web/admin/lib/lang/en_server_list.lng @@ -7,5 +7,7 @@ $wb["dns_server_txt"] = 'DNS'; $wb["file_server_txt"] = 'File'; $wb["db_server_txt"] = 'DB'; $wb["vserver_server_txt"] = 'VServer'; +$wb["proxy_server_txt"] = 'Proxy'; +$wb["firewall_server_txt"] = 'Firewall'; $wb["add_new_record_txt"] = 'Add new Server'; ?> \ No newline at end of file diff --git a/interface/web/admin/lib/module.conf.php b/interface/web/admin/lib/module.conf.php index 25c38bc7b..1ec23dea9 100644 --- a/interface/web/admin/lib/module.conf.php +++ b/interface/web/admin/lib/module.conf.php @@ -85,11 +85,27 @@ $module['nav'][] = array( 'title' => 'System', // cleanup unset($items); - +/* $items[] = array( 'title' => 'Firewall', 'target' => 'content', 'link' => 'admin/firewall_list.php', - 'html_id'=> 'firewall_list'); + 'html_id'=> 'firewall_list');*/ + +$items[] = array( 'title' => 'Basic', + 'target' => 'content', + 'link' => 'admin/firewall_list.php'); + +$items[] = array( 'title' => 'Packet Filter', + 'target' => 'content', + 'link' => 'admin/firewall_filter_list.php'); + + +$items[] = array( 'title' => 'Port Forward', + 'target' => 'content', + 'link' => 'admin/firewall_forward_list.php'); + + + $module['nav'][] = array( 'title' => 'Firewall', diff --git a/interface/web/admin/templates/server_edit_services.htm b/interface/web/admin/templates/server_edit_services.htm index 8eca2909c..17ff55d5e 100644 --- a/interface/web/admin/templates/server_edit_services.htm +++ b/interface/web/admin/templates/server_edit_services.htm @@ -45,6 +45,18 @@ {tmpl_var name='vserver_server'} +
+

{tmpl_var name='proxy_server_txt'}

+
+ {tmpl_var name='proxy_server'} +
+
+
+

{tmpl_var name='firewall_server_txt'}

+
+ {tmpl_var name='firewall_server'} +
+
{tmpl_var name='search_file_server'} -
+ + +
@@ -38,6 +42,8 @@ {tmpl_var name="file_server"} {tmpl_var name="db_server"} {tmpl_var name="vserver_server"} + {tmpl_var name="proxy_server"} + {tmpl_var name="firewall_server"}
{tmpl_var name='delete_txt'} diff --git a/interface/web/login/index.php b/interface/web/login/index.php index be91708f5..9216f79b6 100644 --- a/interface/web/login/index.php +++ b/interface/web/login/index.php @@ -106,21 +106,27 @@ class login_index { if($alreadyfailed['times'] > 5) { $error = $app->lng('error_user_too_many_logins'); } else { + if ($loginAs){ $sql = "SELECT * FROM sys_user WHERE USERNAME = '$username' and PASSWORT = '". $passwort. "'"; $user = $app->db->queryOneRecord($sql); } else { $sql = "SELECT * FROM sys_user WHERE USERNAME = '$username'"; $user = $app->db->queryOneRecord($sql); + if($user && $user['active'] == 1) { + $saved_password = stripslashes($user['passwort']); + if(substr($saved_password,0,3) == '$1$') { //* The password is crypt-md5 encrypted $salt = '$1$'.substr($saved_password,3,8).'$'; + if(crypt($passwort,$salt) != $saved_password) { $user = false; } } else { + //* The password is md5 encrypted if(md5($passwort) != $saved_password) { $user = false; diff --git a/interface/web/sites/form/web_domain.tform.php b/interface/web/sites/form/web_domain.tform.php index 29952e755..5f690791d 100644 --- a/interface/web/sites/form/web_domain.tform.php +++ b/interface/web/sites/form/web_domain.tform.php @@ -485,9 +485,9 @@ $form["tabs"]['advanced'] = array ( 'php_open_basedir' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'TEXT', - 'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY', + /*'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY', 'errmsg'=> 'php_open_basedir_error_empty'), - ), + ), */ 'default' => 'All', 'value' => '', 'width' => '30', @@ -509,6 +509,14 @@ $form["tabs"]['advanced'] = array ( 'width' => '30', 'maxlength' => '255' ), + 'nginx_directives' => array ( + 'datatype' => 'TEXT', + 'formtype' => 'TEXT', + 'default' => '', + 'value' => '', + 'width' => '30', + 'maxlength' => '255' + ) ################################## # ENDE Datatable fields ################################## diff --git a/interface/web/sites/lib/lang/en_web_domain.lng b/interface/web/sites/lib/lang/en_web_domain.lng index d709cc50f..e9b4bbf96 100644 --- a/interface/web/sites/lib/lang/en_web_domain.lng +++ b/interface/web/sites/lib/lang/en_web_domain.lng @@ -37,6 +37,7 @@ $wb["limit_web_domain_txt"] = 'The max. number of web domains for your account i $wb["limit_web_aliasdomain_txt"] = 'The max. number of aliasdomains for your account is reached.'; $wb["limit_web_subdomain_txt"] = 'The max. number of web subdomains for your account is reached.'; $wb["apache_directives_txt"] = 'Apache directives'; +$wb["nginx_directives_txt"] = 'Nginx directives'; $wb["domain_error_empty"] = 'Domain is empty.'; $wb["domain_error_unique"] = 'There is already a website or sub / aliasdomain with this domain name.'; $wb["domain_error_regex"] = 'Domain name invalid.'; diff --git a/interface/web/sites/lib/module.conf.php b/interface/web/sites/lib/module.conf.php index 46502ce4e..b96ac1dd0 100644 --- a/interface/web/sites/lib/module.conf.php +++ b/interface/web/sites/lib/module.conf.php @@ -153,6 +153,18 @@ $module['nav'][] = array( 'title' => 'Statistics', +// clean up +unset($items); + +$items[] = array( 'title' => "Rewrite Rules", + 'target' => 'content', + 'link' => 'sites/proxy_reverse_list.php'); + + +$module["nav"][] = array( 'title' => 'Reverse Proxy', + 'open' => 1, + 'items' => $items); + // clean up unset($items); diff --git a/interface/web/sites/templates/web_domain_advanced.htm b/interface/web/sites/templates/web_domain_advanced.htm index 9ad803c56..488fff2a6 100644 --- a/interface/web/sites/templates/web_domain_advanced.htm +++ b/interface/web/sites/templates/web_domain_advanced.htm @@ -32,6 +32,10 @@
+
+ + +
diff --git a/server/conf/nginx_rewrites.conf.master b/server/conf/nginx_rewrites.conf.master new file mode 100644 index 000000000..b5d2ad55a --- /dev/null +++ b/server/conf/nginx_rewrites.conf.master @@ -0,0 +1,9 @@ +server { + listen 80 default_server; + listen 443 default_server; + server_name _; + include /etc/nginx/proxy.conf; + + rewrite ^{tmpl_var name="rewrite_url_src"} {tmpl_var name="rewrite_url_dst"}; + +} diff --git a/server/conf/nginx_vhost.conf.master b/server/conf/nginx_vhost.conf.master new file mode 100644 index 000000000..83ed251b5 --- /dev/null +++ b/server/conf/nginx_vhost.conf.master @@ -0,0 +1,69 @@ +server { + listen 80; + server_name ; + + access_log /var/log/ispconfig/nginx//access.log; + error_log /var/log/ispconfig/nginx//error.log; + + include /etc/nginx/proxy.conf; + + location / { + proxy_pass http://:80; + } + + location ~* \.(jpg|png|gif|jpeg|css|js|mp3|wav|swf|mov|doc|pdf|xls|ppt|docx|pptx|xlsx)$ { + # Cache static-looking files for 120 minutes, setting a 10 day expiry time in the HTTP header, + # whether logged in or not (may be too heavy-handed). + proxy_cache_valid 200 120m; + expires 864000; + proxy_pass http://:80; + } + + + + + + + +} + + + +########################################################### +# SSL Vhost +########################################################### +server { + listen 443; + server_name ; + + access_log /var/log/ispconfig/nginx//access.log + error_log /var/log/ispconfig/nginx//error.log + + ### SSL cert files ### + ssl_certificate /ssl/.crt + ssl_certificate_key /ssl/.crt + + + ssl_client_certificate /ssl/.bundle + + + ### Add SSL specific settings here ### + keepalive_timeout 60; + + ### Limiting Ciphers ######################## + # Uncomment as per your setup + #ssl_ciphers HIGH:!ADH; + #ssl_perfer_server_ciphers on; + #ssl_protocols SSLv3; + ############################################## + + include /etc/nginx/proxy.conf; + + ### Most PHP, Python, Rails, Java App can use this header ### + proxy_set_header X-Forwarded-Proto https; + + location / { + proxy_pass https://:443; + } +} + diff --git a/server/conf/squidRewriteRules.py.master b/server/conf/squidRewriteRules.py.master new file mode 100644 index 000000000..6005bb3b2 --- /dev/null +++ b/server/conf/squidRewriteRules.py.master @@ -0,0 +1,196 @@ +""" +/********************************************************************** +FILE : $RCSfile: squidRewriteRules.py,v $ +PURPOSE : Rule set for icoya redirector +NOTES : +AUTHOR : Simon Eisenmann +COPYRIGHT: (c) 2003,2004 by struktur AG +DATE : 28JAN2003 +REVISION : $Revision: 1.12 $ +VERSION : $Id: squidRewriteRules.py,v 1.12 2004/08/06 08:16:19 longsleep Exp $ (Author: $Author: longsleep $) + +struktur AG Phone: +49 711 8966560 +Junghansstr. 5 Fax: +49 711 89665610 +70469 Stuttgart email: info@struktur.de +GERMANY + +http://www.struktur.de +http://www.strukturag.com + +**********************************************************************/ + + Reloadable module allows arbitrary url transformations. + + + Automatic reload of the rules + +++++++++++++++++++++++++++++++++++ + + NOTE: use the reload after parameter to auto reload this module + after x requests. Use -1 to disable auto reload + + + Logging + +++++++++++++++++++++++++++++++++++ + + NOTE: set debug to 1 to enable logging + define the logfile in the logfile variable (enter full path) + + +""" +import re, sys + +try: + import py +except ImportError: + pass + +""" ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +begin of configuration +""" + +# log mode (set to 1 to enable logging) +debug = 0 + +# logfile for debugging (only required when debug == 1) +logfile = "/etc/squid/redirector_class.log" + +# set this to -1 to get best performance (no reload) +reload_after = -1 + +# define sitemap matching regex mapping + +# MODIFY THIS REWRITE RULE AS NEEDED FOR YOUR SITE + +rewrites = ( + +### HTTP SSL/encrypted webmail rewrite ### You can use this as an example for your ssl virtualhosted website + + + (r'{tmpl_var name="rewrite_url_src"}', r'{tmpl_var name="rewrite_url_dest"}\1', 'P,L'), + + + + + + +) + + + +""" +end of configuration ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +""" + +compiled_rewrites = None + +def log(s): + """ Logging facility. + """ + try: + f = open(logfile, "a") + except IOError: + print >> sys.stderr, s + return + f.write('%s\n' % s) + f.flush() + f.close() + +def init(): + global compiled_rewrites + + compiled_rewrites = [] + for rewrite in rewrites: + regexp = re.compile(rewrite[0]) + template = rewrite[1] + flags = {} + for flag in rewrite[2].split(','): + parts = flag.split('=') + flag = parts[0] + option = None + if flag == 'R': + if len(parts) > 1: + option = "%s:" % parts[1] + else: + option = '302:' + flags[flag] = option + compiled = (regexp, template, flags) + if debug: + log('compiled: %s' % str((regexp.pattern, template, flags))) + compiled_rewrites.append(compiled) + compiled_rewrites = tuple(compiled_rewrites) + +def rewrite(url, src_address=''): + """ just rewrites urls. + """ + + if debug: + log("args: %s" % str((url, src_address))) + + newurl = None + for regexp, template, flags in compiled_rewrites: + m = regexp.match(url) + if m is not None and template != '-': + if debug: + log("match.groups ('%s'): %s" % (regexp.pattern, str(m.groups()))) + url = newurl = "%s%s" % (flags.get('R', ''), m.expand(template)) + if debug: + log('newurl: %s' % newurl) + if 'L' in flags: + break + + if newurl is not None: + if debug: + log('finalurl: %s' % newurl) + return newurl + + # redirect to something we can match by a squid acl + # this special non existing domain should be denied + # by squid with a http_reply_access line + return "http://denypool/denyme" + +def test_foobar_redirection(): + assert rewrite('http://foobar.com/foo/bar') == '302:http://www.foobar.com/foo/bar' + assert rewrite('http://foobar.de/foo/bar') == '302:http://www.foobar.com/foo/bar' + assert rewrite('http://www.foobar.de/foo/bar') == '302:http://www.foobar.com/foo/bar' + assert rewrite('http://foobar-portal.de/foo/bar') == '302:http://www.foobar.com/foo/bar' + assert rewrite('http://www.foobar-portal.de/foo/bar') == '302:http://www.foobar.com/foo/bar' + assert rewrite('http://foobar-portal-europe.de/foo/bar') == '302:http://www.foobar.com/foo/bar' + assert rewrite('http://www.foobar-portal-europe.de/foo/bar') == '302:http://www.foobar.com/foo/bar' + # shouldn't redirect, just rewrite + assert not rewrite('http://www.foobar.com/foo/bar').startswith('302:') + +def test_foobarbacon_redirection(): + assert rewrite('http://foobar-bacon.com/foo/bar') == '302:http://www.foobar-bacon.com/foo/bar' + assert rewrite('http://foobar-bacon.de/foo/bar') == '302:http://www.foobar-bacon.com/foo/bar' + assert rewrite('http://www.foobar-bacon.de/foo/bar') == '302:http://www.foobar-bacon.com/foo/bar' + assert rewrite('http://foobar-bacon-europe.de/foo/bar') == '302:http://www.foobar-bacon.com/foo/bar' + assert rewrite('http://www.foobar-bacon-europe.de/foo/bar') == '302:http://www.foobar-bacon.com/foo/bar' + assert rewrite('http://foobar-bacon-europe.com/foo/bar') == '302:http://www.foobar-bacon.com/foo/bar' + assert rewrite('http://www.foobar-bacon-europe.com/foo/bar') == '302:http://www.foobar-bacon.com/foo/bar' + assert rewrite('http://foobar-bacon.net/foo/bar') == '302:http://www.foobar-bacon.com/foo/bar' + assert rewrite('http://www.foobar-bacon.net/foo/bar') == '302:http://www.foobar-bacon.com/foo/bar' + # shouldn't redirect, just rewrite + assert not rewrite('http://www.foobar-bacon.com/foo/bar').startswith('302:') + +def test_virtual_hosting(): + assert rewrite('http://www.foobar.com/foo/bar') == 'http://backendpool/VirtualHostBase/http/www.foobar.com/foobarportal/VirtualHostRoot/foo/bar' + assert rewrite('http://www.foobar.com:8088/foo/bar') == 'http://backendpool/VirtualHostBase/http/www.foobar.com:8088/foobarportal/VirtualHostRoot/foo/bar' + assert rewrite('http://www.foobar-bacon.com/foo/bar') == 'http://backendpool/VirtualHostBase/http/www.foobar-bacon.com/foobarbacon/VirtualHostRoot/foo/bar' + assert rewrite('http://www.foobar-bacon.com:8088/foo/bar') == 'http://backendpool/VirtualHostBase/http/www.foobar-bacon.com:8088/foobarbacon/VirtualHostRoot/foo/bar' + +def test_zmi(): + assert rewrite('http://www.foobar.com/--zmi--/foo/bar') == 'http://backendpool/VirtualHostBase/http/www.foobar.com/VirtualHostRoot/_vh_--zmi--/foo/bar' + assert rewrite('http://www.foobar.com:8088/--zmi--/foo/bar') == 'http://backendpool/VirtualHostBase/http/www.foobar.com:8088/VirtualHostRoot/_vh_--zmi--/foo/bar' + +def test_repos(): + assert rewrite('http://www.foobar.com/--repos--/foo/bar') == 'http://localhost/--repos--/foo/bar' + assert rewrite('http://www.foobar.com:8088/--repos--/foo/bar') == 'http://localhost/--repos--/foo/bar' + +if debug: + log("reloading user redirector module") +init() +if debug: + log("reloaded user redirector module") + diff --git a/server/conf/ufw.before.rules.master b/server/conf/ufw.before.rules.master new file mode 100644 index 000000000..ab451718e --- /dev/null +++ b/server/conf/ufw.before.rules.master @@ -0,0 +1,78 @@ +# +# rules.before +# +# Rules that should be run before the ufw command line added rules. Custom +# rules should be added to one of these chains: +# ufw-before-input +# ufw-before-output +# ufw-before-forward +# + +# Don't delete these required lines, otherwise there will be errors +*filter +:ufw-before-input - [0:0] +:ufw-before-output - [0:0] +:ufw-before-forward - [0:0] +:ufw-not-local - [0:0] +# End required lines + + +# allow all on loopback +-A ufw-before-input -i lo -j ACCEPT +-A ufw-before-output -o lo -j ACCEPT + +# connection tracking rules +-A ufw-before-input -m state --state RELATED,ESTABLISHED -j ACCEPT + +# drop INVALID packets (logs these in loglevel medium and higher) +-A ufw-before-input -m state --state INVALID -j ufw-logging-deny +-A ufw-before-input -m state --state INVALID -j DROP + +# connection tracking for outbound +-A ufw-before-output -p tcp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT +-A ufw-before-output -p udp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT + +# ok icmp codes +-A ufw-before-input -p icmp --icmp-type destination-unreachable -j ACCEPT +-A ufw-before-input -p icmp --icmp-type source-quench -j ACCEPT +-A ufw-before-input -p icmp --icmp-type time-exceeded -j ACCEPT +-A ufw-before-input -p icmp --icmp-type parameter-problem -j ACCEPT +-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT + +# allow dhcp client to work +-A ufw-before-input -p udp --sport 67 --dport 68 -j ACCEPT + +# +# ufw-not-local +# +-A ufw-before-input -j ufw-not-local + +# if LOCAL, RETURN +-A ufw-not-local -m addrtype --dst-type LOCAL -j RETURN + +# if MULTICAST, RETURN +-A ufw-not-local -m addrtype --dst-type MULTICAST -j RETURN + +# if BROADCAST, RETURN +-A ufw-not-local -m addrtype --dst-type BROADCAST -j RETURN + +# all other non-local packets are dropped +-A ufw-not-local -m limit --limit 3/min --limit-burst 10 -j ufw-logging-deny +-A ufw-not-local -j DROP + +# allow MULTICAST, be sure the MULTICAST line above is uncommented +-A ufw-before-input -s 224.0.0.0/4 -j ACCEPT +-A ufw-before-input -d 224.0.0.0/4 -j ACCEPT + +COMMIT + +# nat Table rules +*nat +:POSTROUTING ACCEPT [0:0] + +-A POSTROUTING -s 192.168.5.2/24 -o eth0 -j SNAT --to 192.168.5.105 + +-A PREROUTING -p tcp -d 192.168.5.105 --dport 80 -i eth0 -j DNAT --to-destination 192.168.5.200:80 + +# don't delete the 'COMMIT' line or these rules won't be processed +COMMIT diff --git a/server/conf/ufw.conf.master b/server/conf/ufw.conf.master new file mode 100644 index 000000000..7870d63ef --- /dev/null +++ b/server/conf/ufw.conf.master @@ -0,0 +1,8 @@ +# /etc/ufw/ufw.conf +# + +# set to yes to start on boot +ENABLED={tmpl_var name='enable'} + +# set to one of 'off', 'low', 'medium', 'high' +LOGLEVEL={tmpl_var name='log_level'} diff --git a/server/conf/ufw.default.master b/server/conf/ufw.default.master new file mode 100644 index 000000000..6a205006d --- /dev/null +++ b/server/conf/ufw.default.master @@ -0,0 +1,39 @@ +# /etc/default/ufw +# + +# set to yes to apply rules to support IPv6 (no means only IPv6 on loopback +# accepted). You will need to 'disable' and then 'enable' the firewall for +# the changes to take affect. +IPV6={tmpl_var name='ipv6'} + +# set the default input policy to ACCEPT, DROP or REJECT. Please note that if +# you change this you will most likely want to adjust your rules +DEFAULT_INPUT_POLICY="{tmpl_var name='default_input_policy'}" + +# set the default output policy to ACCEPT, DROP, or REJECT. Please note that +# if you change this you will most likely want to adjust your rules +DEFAULT_OUTPUT_POLICY="{tmpl_var name='default_output_policy'}T" + +# set the default forward policy to ACCEPT, DROP or REJECT. Please note that +# if you change this you will most likely want to adjust your rules +DEFAULT_FORWARD_POLICY="{tmpl_var name='default_forward_policy'}" + +# set the default application policy to ACCEPT, DROP, REJECT or SKIP. Please +# note that setting this to ACCEPT may be a security risk. See 'man ufw' for +# details +DEFAULT_APPLICATION_POLICY="{tmpl_var name='default_application_policy'}" + +# By default, ufw only touches its own chains. Set this to 'yes' to have ufw +# manage the built-in chains too. Warning: setting this to 'yes' will break +# non-ufw managed firewall rules +MANAGE_BUILTINS={tmpl_var name='manage_builtins'} + +# +# IPT backend +# +# only enable if using iptables backend +IPT_SYSCTL=/etc/ufw/sysctl.conf + +# extra connection tracking modules to load +IPT_MODULES="nf_conntrack_ftp nf_nat_ftp nf_conntrack_irc nf_nat_irc" + diff --git a/server/mods-available/dns_module.inc.php b/server/mods-available/dns_module.inc.php index d5c9ac792..01c4526a4 100644 --- a/server/mods-available/dns_module.inc.php +++ b/server/mods-available/dns_module.inc.php @@ -47,7 +47,11 @@ class dns_module { function onInstall() { global $conf; - return true; + if($conf['services']['dns'] == true) { + return true; + } else { + return false; + } } diff --git a/server/plugins-available/firewall_plugin.inc.php b/server/plugins-available/firewall_plugin.inc.php index d9d1272ce..669779858 100644 --- a/server/plugins-available/firewall_plugin.inc.php +++ b/server/plugins-available/firewall_plugin.inc.php @@ -38,7 +38,11 @@ class firewall_plugin { function onInstall() { global $conf; - return true; + if($conf['bastille']['installed'] = true && $conf['services']['firewall'] == true) { + return true; + } else { + return false; + } } diff --git a/server/plugins-available/nginx_plugin.inc.php b/server/plugins-available/nginx_plugin.inc.php new file mode 100644 index 000000000..a200dafca --- /dev/null +++ b/server/plugins-available/nginx_plugin.inc.php @@ -0,0 +1,368 @@ +plugins->registerEvent('web_domain_insert',$this->plugin_name,'ssl'); + $app->plugins->registerEvent('web_domain_update',$this->plugin_name,'ssl'); + $app->plugins->registerEvent('web_domain_delete',$this->plugin_name,'ssl'); + + $app->plugins->registerEvent('web_domain_insert',$this->plugin_name,'insert'); + $app->plugins->registerEvent('web_domain_update',$this->plugin_name,'update'); + $app->plugins->registerEvent('web_domain_delete',$this->plugin_name,'delete'); + + // $app->plugins->registerEvent('proxy_reverse_insert',$this->plugin_name,'rewrite_insert'); + // $app->plugins->registerEvent('proxy_reverse_update',$this->plugin_name,'rewrite_update'); + // $app->plugins->registerEvent('proxy_reverse_delete',$this->plugin_name,'rewrite_delete'); + + + + } + + + function insert($event_name,$data) { + global $app, $conf; + + // just run the update function + $this->update($event_name,$data); + } + + + function update($event_name,$data) { + global $app, $conf; + + if($this->action != 'insert') $this->action = 'update'; + + if($data['new']['type'] != 'vhost' && $data['new']['parent_domain_id'] > 0) { + + $old_parent_domain_id = intval($data['old']['parent_domain_id']); + $new_parent_domain_id = intval($data['new']['parent_domain_id']); + + // If the parent_domain_id has been chenged, we will have to update the old site as well. + if($this->action == 'update' && $data['new']['parent_domain_id'] != $data['old']['parent_domain_id']) { + $tmp = $app->dbmaster->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$old_parent_domain_id." AND active = 'y'"); + $data['new'] = $tmp; + $data['old'] = $tmp; + $this->action = 'update'; + $this->update($event_name,$data); + } + + // This is not a vhost, so we need to update the parent record instead. + $tmp = $app->dbmaster->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$new_parent_domain_id." AND active = 'y'"); + $data['new'] = $tmp; + $data['old'] = $tmp; + $this->action = 'update'; + } + + + + + // load the server configuration options + $app->uses('getconf'); + $nginx_config = $app->getconf->get_server_config($conf['server_id'], 'nginx'); + + // Create group and user, if not exist + $app->uses('system'); + + //* Create the vhost config file + $app->load('tpl'); + + $tpl = new tpl(); + $tpl->newTemplate('nginx_vhost.conf.master'); + + $vhost_data = $data['new']; + $vhost_data['config_dir'] = $config['nginx']['config_dir']; + + $vhost_data['ssl_domain'] = $data['new']['ssl_domain']; + // Check if a SSL cert exists + $ssl_dir = $config['nginx']['config_dir'].'/ssl'; + $domain = $data['new']['ssl_domain']; + $key_file = $ssl_dir.'/'.$domain.'.key'; + $crt_file = $ssl_dir.'/'.$domain.'.crt'; + $bundle_file = $ssl_dir.'/'.$domain.'.bundle'; + + $vhost_data['nginx_directives'] = preg_replace("/\[IP\]/", $vhost_data['ip_address'], $vhost_data['nginx_directives']); + + + if($data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file)) { + $vhost_data['ssl_enabled'] = 1; + $app->log('Enable SSL for: '.$domain,LOGLEVEL_DEBUG); + } else { + $vhost_data['ssl_enabled'] = 0; + $app->log('Disable SSL for: '.$domain,LOGLEVEL_DEBUG); + } + + if(@is_file($bundle_file)) $vhost_data['has_bundle_cert'] = 1; + + + $tpl->setVar($vhost_data); + + + + // get alias domains (co-domains and subdomains) + $aliases = $app->dbmaster->queryAllRecords('SELECT * FROM web_domain WHERE parent_domain_id = '.$data['new']['domain_id']." AND active = 'y'"); + $server_alias = array(); + switch($data['new']['subdomain']) { + case 'www': + $server_alias[] .= 'www.'.$data['new']['domain'].' '; + break; + case '*': + $server_alias[] .= '*.'.$data['new']['domain'].' '; + break; + } + if(is_array($aliases)) { + foreach($aliases as $alias) { + switch($alias['subdomain']) { + case 'www': + $server_alias[] .= 'www.'.$alias['domain'].' '.$alias['domain'].' '; + break; + case '*': + $server_alias[] .= '*.'.$alias['domain'].' '.$alias['domain'].' '; + break; + default: + $server_alias[] .= $alias['domain'].' '; + break; + } + $app->log('Add server alias: '.$alias['domain'],LOGLEVEL_DEBUG); + + } + } + + //* If we have some alias records + if(count($server_alias) > 0) { + $server_alias_str = ''; + $n = 0; + + // begin a new ServerAlias line after 30 alias domains + foreach($server_alias as $tmp_alias) { + if($n % 30 == 0) $server_alias_str .= " "; + $server_alias_str .= $tmp_alias; + } + unset($tmp_alias); + + $tpl->setVar('alias',trim($server_alias_str)); + } else { + $tpl->setVar('alias',''); + } + + + $vhost_file = escapeshellcmd($nginx_config['vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost'); + //* Make a backup copy of vhost file + copy($vhost_file,$vhost_file.'~'); + + //* Write vhost file + file_put_contents($vhost_file,$tpl->grab()); + $app->log('Writing the vhost file: '.$vhost_file,LOGLEVEL_DEBUG); + unset($tpl); + + + // Set the symlink to enable the vhost + $vhost_symlink = escapeshellcmd($nginx_config['vhost_conf_enabled_dir'].'/'.$data['new']['domain'].'.vhost'); + if($data['new']['active'] == 'y' && !is_link($vhost_symlink)) { + symlink($vhost_file,$vhost_symlink); + $app->log('Creating symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); + } + + // Remove the symlink, if site is inactive + if($data['new']['active'] == 'n' && is_link($vhost_symlink)) { + unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); + } + + if(!is_dir('/var/log/ispconfig/nginx/'.$data['new']['domain'])) exec('mkdir -p /var/log/ispconfig/nginx/'.$data['new']['domain']); + + // remove old symlink and vhost file, if domain name of the site has changed + if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { + $vhost_symlink = escapeshellcmd($nginx_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); + unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); + $vhost_file = escapeshellcmd($nginx_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); + unlink($vhost_file); + $app->log('Removing file: '.$vhost_file,LOGLEVEL_DEBUG); + + if(is_dir('/var/log/ispconfig/nginx/'.$data['old']['domain'])) exec('rm -rf /var/log/ispconfig/nginx/'.$data['old']['domain']); + } + + // request a httpd reload when all records have been processed + $app->services->restartServiceDelayed('nginx','restart'); + + // Remove the backup copy of the config file. + if(@is_file($vhost_file.'~')) unlink($vhost_file.'~'); + + + //* Unset action to clean it for next processed vhost. + $this->action = ''; + + } + + + + + // Handle the creation of SSL certificates + function ssl($event_name,$data) { + global $app, $conf; + + if(!is_dir($conf['nginx']['config_dir'].'/ssl')) exec('mkdir -p '.$conf['nginx']['config_dir'].'/ssl'); + $ssl_dir = $conf['nginx']['config_dir'].'/ssl'; + $domain = $data['new']['ssl_domain']; + $key_file = $ssl_dir.'/'.$domain.'.key.org'; + $key_file2 = $ssl_dir.'/'.$domain.'.key'; + $csr_file = $ssl_dir.'/'.$domain.'.csr'; + $crt_file = $ssl_dir.'/'.$domain.'.crt'; + + + //* Save a SSL certificate to disk + if($data["new"]["ssl_action"] == 'save') { + $web = $app->masterdb->queryOneRecord("select wd.document_root, sp.ip_address from web_domain wd INNER JOIN server_ip sp USING(server_id) WHERE domain = '".$data['new']['domain']."'"); + + $src_ssl_dir = $web["document_root"]."/ssl"; + //$domain = $data["new"]["ssl_domain"]; + //$csr_file = $ssl_dir.'/'.$domain.".csr"; + //$crt_file = $ssl_dir.'/'.$domain.".crt"; + //$bundle_file = $ssl_dir.'/'.$domain.".bundle"; + $this->_exec('rsync -v -e ssh root@'.$web['ip_address'].':~/$src_ssl_dir '.$ssl_dir); + + $app->log('Syncing SSL Cert for: '.$domain,LOGLEVEL_DEBUG); + } + + //* Delete a SSL certificate + if($data['new']['ssl_action'] == 'del') { + //$ssl_dir = $data['new']['document_root'].'/ssl'; + $domain = $data['new']['ssl_domain']; + $csr_file = $ssl_dir.'/'.$domain.'.csr'; + $crt_file = $ssl_dir.'/'.$domain.'.crt'; + $bundle_file = $ssl_dir.'/'.$domain.'.bundle'; + unlink($csr_file); + unlink($crt_file); + unlink($bundle_file); + $app->log('Deleting SSL Cert for: '.$domain,LOGLEVEL_DEBUG); + } + + + } + + + function delete($event_name,$data) { + global $app, $conf; + + // load the server configuration options + $app->uses('getconf'); + $nginx_config = $app->getconf->get_server_config($conf['server_id'], 'nginx'); + + + if($data['old']['type'] == 'vhost') { + + //* This is a website + // Deleting the vhost file, symlink and the data directory + $vhost_symlink = escapeshellcmd($nginx_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); + unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); + + $vhost_file = escapeshellcmd($nginx_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); + unlink($vhost_file); + $app->log('Removing vhost file: '.$vhost_file,LOGLEVEL_DEBUG); + + + + // Delete the log file directory + $vhost_logfile_dir = escapeshellcmd('/var/log/ispconfig/nginx/'.$data['old']['domain']); + if($data['old']['domain'] != '' && !stristr($vhost_logfile_dir,'..')) exec('rm -rf '.$vhost_logfile_dir); + $app->log('Removing website logfile directory: '.$vhost_logfile_dir,LOGLEVEL_DEBUG); + + } + } + + //* Wrapper for exec function for easier debugging + private function _exec($command) { + global $app; + $app->log('exec: '.$command,LOGLEVEL_DEBUG); + exec($command); + } + + function rewrite_insert($event_name,$data) { + global $app, $conf; + + // just run the update function + $this->update($event_name,$data); + } + + function rewrite_update($event_name,$data) { + global $app, $conf; + + $rules = $this->_getRewriteRules($app); + + $app->uses('getconf'); + $nginx_config = $app->getconf->get_server_config($conf['server_id'], 'nginx'); + + $app->load('tpl'); + $tpl = new tpl(); + $tpl->newTemplate("nginx-rewrites.conf.master"); + if (!empty($rules))$tpl->setLoop('nginx_rewrite_rules',$rules); + + $rewrites_file = escapeshellcmd($nginx_config['vhost_conf_dir'].'/default.rewrites.conf'); + //* Make a backup copy of vhost file + copy($rewrites_file,$rewrites_file.'~'); + + //* Write vhost file + file_put_contents($rewrites_file,$tpl->grab()); + $app->log('Writing the nginx rewrites file: '.$rewrites_file,LOGLEVEL_DEBUG); + unset($tpl); + + + // Set the symlink to enable the vhost + $rewrite_symlink = escapeshellcmd($nginx_config['vhost_conf_enabled_dir'].'/default.rewrites.conf'); + + if(!is_link($rewrite_symlink)) { + symlink($rewrites_file,$rewrite_symlink); + $app->log('Creating symlink for nginx rewrites: '.$rewrite_symlink.'->'.$rewrites_file,LOGLEVEL_DEBUG); + } + } + + function rewrite_delete($event_name,$data) { + global $app, $conf; + + // just run the update function + $this->rewrite_update($event_name,$data); + } + + + function _getRewriteRules($app) + { + $rules = array(); + $rules = $app->db->queryAllRecords("SELECT rewrite_url_src, rewrite_url_dst FROM proxy_reverse ORDER BY rewrite_id ASC"); + return $rules; + } + +} // end class + +?> diff --git a/server/plugins-available/squid_plugin.inc.php b/server/plugins-available/squid_plugin.inc.php new file mode 100644 index 000000000..fb667e050 --- /dev/null +++ b/server/plugins-available/squid_plugin.inc.php @@ -0,0 +1,171 @@ +plugins->registerEvent('proxy_reverse_insert',$this->plugin_name,'insert'); + $app->plugins->registerEvent('proxy_reverse_update',$this->plugin_name,'update'); + $app->plugins->registerEvent('proxy_reverse_delete',$this->plugin_name,'delete'); + + $app->plugins->registerEvent('web_domain_insert',$this->plugin_name,'insert'); + $app->plugins->registerEvent('web_domain_update',$this->plugin_name,'update'); + $app->plugins->registerEvent('web_domain_delete',$this->plugin_name,'delete'); + + + + } + + + + + function insert($event_name,$data) { + global $app, $conf; + + + // just run the update function + $this->update($event_name,$data); + + + } + + + function update($event_name,$data) { + global $app, $conf; + + $domains = $this->_getSquidDomains($app); + $rules = $this->_getSquidRewriteRules($app); + + $app->load('tpl'); + $tpl = new tpl(); + $tpl->newTemplate("squidRewriteRules.py.master"); + if (!empty($rules))$tpl->setLoop('squid_rewrite_rules',$rules); + file_put_contents('/etc/squid/squidRewriteRules.py',$tpl->grab()); + unset($tpl); + $app->log('Writing squid rewrite configuration to /etc/squid/squidRewriteRules.py',LOGLEVEL_DEBUG); + + + $tpl = new tpl(); + $tpl->newTemplate("domains.txt.master"); + $tpl->setLoop('squid_domains',$domains); + file_put_contents('/etc/squid/domains.txt',$tpl->grab()); + unset($tpl); + $app->log('Writing squid domains configuration to /etc/squid/domains.txt',LOGLEVEL_DEBUG); + + + // request a httpd reload when all records have been processed + $app->services->restartServiceDelayed('squid','restart'); + + } + + function delete($event_name,$data) { + global $app, $conf; + + // load the server configuration options + + // just run the update function + $this->update($event_name,$data); + + } + + function _getSquidDomains($app) + { + $records = $app->dbmaster->queryAllRecords("SELECT ds.origin, dr.name, IF(origin=name,true,false) AS isRoot FROM dns_soa ds inner join dns_rr dr ON ds.id=dr.zone WHERE ds.active='Y' AND dr.type IN ('A','CNAME') AND dr.name NOT IN ('mail','ns1')"); + $domains = array(); + foreach ($records as $record) { + + $origin = substr($record["origin"],0,-1); + if ($record["isRoot"]) + { + array_push($domains, array("domain" => $origin)); + } else { + array_push($domains, array("domain" => $record["name"].".".$origin)); + } + + } + + return $domains; + + } + + function _getSquidRewriteRules($app) + { + $rules = array(); + + $rules = $app->db->queryAllRecords("SELECT rewrite_url_src, rewrite_url_dest FROM squid_reverse ORDER BY rewrite_id ASC"); + $web_domains = $app->db->queryAllRecords("SELECT wd.subdomain, wd.domain, si.ip_address FROM web_domain wd INNER JOIN server s USING(server_id) INNER JOIN server_ip si USING(server_id)"); + + foreach ($web_domains as $domain) { + if ($domain["subdomain"] == "www") { + array_push($rules,array("rewrite_url_src"=>"^http://www.".$domain["domain"]."/(.*)","rewrite_url_dest"=>"http://".$domain["ip_address"].":80/")); + array_push($rules,array("rewrite_url_src"=>"^http://".$domain["domain"]."/(.*)","rewrite_url_dest"=>"http://".$domain["ip_address"].":80/")); + } else { + array_push($rules,array("rewrite_url_src"=>"^http://www.".$domain["domain"]."/(.*)","rewrite_url_dest"=>"http://".$domain["ip_address"].":80/")); + } + } + return $rules; + } + + + +} // end class + +?> diff --git a/server/plugins-available/ufw_firewall_plugin.inc.php b/server/plugins-available/ufw_firewall_plugin.inc.php new file mode 100644 index 000000000..4eb1e1f96 --- /dev/null +++ b/server/plugins-available/ufw_firewall_plugin.inc.php @@ -0,0 +1,504 @@ +plugins->registerEvent('firewall_insert',$this->plugin_name,'insert_basic'); + $app->plugins->registerEvent('firewall_update',$this->plugin_name,'update_basic'); + $app->plugins->registerEvent('firewall_delete',$this->plugin_name,'update_basic'); + + $app->plugins->registerEvent('firewall_forward_insert',$this->plugin_name,'insert_forward'); + $app->plugins->registerEvent('firewall_forward_update',$this->plugin_name,'update_forward'); + $app->plugins->registerEvent('firewall_forward_delete',$this->plugin_name,'update_forward'); + + $app->plugins->registerEvent('firewall_filter_insert',$this->plugin_name,'insert_filter'); + $app->plugins->registerEvent('firewall_filter_update',$this->plugin_name,'update_filter'); + $app->plugins->registerEvent('firewall_filter_delete',$this->plugin_name,'delete_filter'); + + $app->plugins->registerEvent('server_insert',$this->plugin_name,'updateSettings'); + $app->plugins->registerEvent('server_update',$this->plugin_name,'updateSettings'); + + + + } + + + function insert_basic($event_name,$data) { + global $app, $conf; + + $this->update_basic($event_name,$data); + + } + + function update_basic($event_name,$data) { + global $app, $conf; + + $tcp_ports = ''; + $udp_ports = ''; + + $delete_rule = ($data["new"]["active"] == "n" ? "delete " : ""); + /* + $ports = explode(',',$data["new"]["tcp_port"]); + if(is_array($ports)) { + foreach($ports as $p) { + if(strstr($p,':')) { + $p_parts = explode(':',$p); + $p_clean = intval($p_parts[0]).':'.intval($p_parts[1]); + } else { + $p_clean = intval($p); + } + + //system("ufw $delete_rule allow " . $p_clean . "/tcp"); + + } + }*/ + + system("ufw $delete_rule allow out" . $data["new"]["tcp_port"] . "/tcp"); + system("ufw $delete_rule allow in" . $data["new"]["tcp_port"] . "/tcp"); + system("ufw $delete_rule allow out" . $data["new"]["udp_port"] . "/udp"); + system("ufw $delete_rule allow in" . $data["new"]["udp_port"] . "/udp"); + //$tcp_ports = trim($tcp_ports); + /* + $ports = explode(',',$data["new"]["udp_port"]); + if(is_array($ports)) { + foreach($ports as $p) { + if(strstr($p,':')) { + $p_parts = explode(':',$p); + $p_clean = intval($p_parts[0]).':'.intval($p_parts[1]); + } else { + $p_clean = intval($p); + } + + + } + } + + system("ufw $delete_rule allow " . $p_clean . "/udp"); + */ + + if($data["new"]["active"] == 'y') { + exec('/etc/init.d/ufw force-reload'); + $app->log('Restarting the firewall',LOGLEVEL_DEBUG); + } else { + exec('/etc/init.d/ufw force-reload'); + $app->log('Flushing the firewall',LOGLEVEL_DEBUG); + } + + + } + + + function insert_filter($event_name,$data) { + global $app, $conf; + + $this->update_filter($event_name,$data); + + } + + function getCidr($mask) { + $long = ip2long($mask); + $base = ip2long('255.255.255.255'); + return 32-log(($long ^ $base)+1,2); + } + + function update_filter($event_name,$data) { + global $app, $conf; + + $app->uses("getconf"); + $server_config = $app->getconf->get_server_config($conf["server_id"], 'ufw'); + $network = $server_config["ufw_network"]; + + $records = $app->db->queryAllRecords( + "SELECT + protocol, + IF + (src_from_port=src_to_port, src_from_port, CONCAT(src_from_port, ':',src_to_port)) + AS + src_port, + IF + (dst_from_port=dst_to_port, dst_from_port, CONCAT(dst_from_port, ':',dst_to_port)) + AS + dst_port, + IF + (src_ip='0.0.0.0','any',src_ip) + AS + src_ip, + IF + (dst_ip='0.0.0.0','any',dst_ip) + AS + dst_ip, + src_netmask, + dst_netmask, + inbound_policy, + outbound_policy, + rule_id, + active + FROM + firewall_filter + ORDER BY + rule_id + ASC"); + + $commands = array(); + foreach ($records as $record) { + $src_netmask = $this->getCidr($record["src_netmask"]); + $dst_netmask = $this->getCidr($record["dst_netmask"]); + $src_port = ($record["src_port"] == "0:65535" ? "" : " port " .$record["src_port"]); + $dst_port = ($record["dst_port"] == "0:65535" ? "" : " port " . $record["dst_port"]); + $src_ip = ($record["src_ip"] == "any" ? "any" : $record["src_ip"] . "/" . $src_netmask); + $dst_ip = ($record["dst_ip"] == "any" ? "any" : $record["dst_ip"] . "/" . $dst_netmask); + //$protocol = $record["protocol"]; + $delete = ($record["active"] == "n" ? true : false); + //$protocols = array_split($record["protocol"]); + //$inbound = ($record["inbound"] == 0 ? "deny " : "allow"); + //$outbound = ($record["outbound"] == 0 ? "deny out" : "allow out"); + + //foreach ($protocols as $protocol) { + + + $ufw = new UFW(); + //$ufw->setDelete($record["active"] == "n"); + $ufw->setRuleID($record["rule_id"]); + $ufw->setSrcIP($src_ip); + $ufw->setDstIP($dst_ip); + $ufw->setSrcPort($src_port); + $ufw->setDstPort($dst_port); + $ufw->setInboundPolicy($record["inbound_policy"]); + $ufw->setOutboundPolicy($record["outbound_policy"]); + $ufw->setProtocol($record["protocol"]); + $ufw->setNetwork($network); + + if ($delete) { + $ufw->delete(); + } else { + $ufw->insert(); + } + //} + + /* + if ($record["active"] == 'n') { + $inbound = ($record["inbound"] == 0 ? "deny " : "allow"); + $outbound = ($record["outbound"] == 0 ? "deny out" : "allow out"); + array_push($commands, "ufw deny proto udp from $src_ip $src_port to $dst_ip $dst_port"); + if ($protocol == "tcp/udp") { + array_push($commands, "ufw delete $inbound proto udp from $src_ip $src_port to $dst_ip $dst_port"); + array_push($commands, "ufw delete $outbound proto udp from $src_ip $src_port to $dst_ip $dst_port"); + array_push($commands, "ufw delete $inbound proto tcp from $src_ip $src_port to $dst_ip $dst_port"); + array_push($commands, "ufw delete $outbound proto tcp from $src_ip $src_port to $dst_ip $dst_port"); + } else { + array_push($commands, "ufw delete $inbound proto $protocol from $src_ip $src_port to $dst_ip $dst_port"); + array_push($commands, "ufw delete $outbound proto $protocol from $src_ip $src_port to $dst_ip $dst_port"); + } + } elseif ($record["inbound"] == 0) { + if ($protocol == "tcp/udp") { + array_push($commands, "ufw deny proto udp from $src_ip $src_port to $dst_ip $dst_port"); + array_push($commands, "ufw deny proto tcp from $src_ip $src_port to $dst_ip $dst_port"); + } else { + array_push($commands, "ufw deny proto $protocol from $src_ip $src_port to $dst_ip $dst_port"); + } + + } elseif ($record["outbound"] == 0) { + if ($protocol == "tcp/udp") { + array_push($commands, "ufw deny out proto udp from $network to any $dst_port"); + array_push($commands, "ufw deny out proto tcp from $network to any $dst_port"); + } else { + array_push($commands, "ufw deny out proto $protocol from $network to any $dst_port"); + } + }*/ + + + } + + /* + + $records = $app->db->queryAllRecords( + "SELECT + protocol, + IF + (src_from_port=src_to_port, src_from_port, CONCAT(src_from_port, ':',src_to_port)) + AS + src_port, + IF + (dst_from_port=dst_to_port, dst_from_port, CONCAT(dst_from_port, ':',dst_to_port)) + AS + dst_port, + IF + (src_ip='0.0.0.0','any',src_ip) + AS + src_ip, + IF + (dst_ip='0.0.0.0','any',dst_ip) + AS + dst_ip, + src_netmask, + dst_netmask, + inbound, + outbound, + active + FROM + firewall_filter + WHERE + inbound=1 + OR + outbound=1 + AND + active='y'"); + + + foreach ($records as $record) { + $src_netmask = $this->getCidr($record["src_netmask"]); + $dst_netmask = $this->getCidr($record["dst_netmask"]); + $src_port = ($record["src_port"] == "0:65535" ? "" : " port " .$record["src_port"]); + $dst_port = ($record["dst_port"] == "0:65535" ? "" : " port " . $record["dst_port"]); + $src_ip = ($record["src_ip"] == "any" ? "any" : $record["src_ip"] . "/" . $src_netmask); + $dst_ip = ($record["dst_ip"] == "any" ? "any" : $record["dst_ip"] . "/" . $dst_netmask); + $protocol = $record["protocol"]; + $outbound = ($record["outbound"] == 1 ? "out" : ""); + + + + if ($record["inbound"] == 1) { + if ($protocol == "tcp/udp") { + array_push($commands, "ufw allow proto udp from $src_ip $src_port to $dst_ip $dst_port"); + array_push($commands, "ufw allow proto tcp from $src_ip $src_port to $dst_ip $dst_port"); + } else { + array_push($commands, "ufw allow proto $protocol from $src_ip $src_port to $dst_ip $dst_port"); + } + + } elseif ($record["outbound"] == 1) { + if ($protocol == "tcp/udp") { + array_push($commands, "ufw allow out proto udp from $network to any $dst_port"); + array_push($commands, "ufw allow out proto tcp from $network to any $dst_port"); + } else { + array_push($commands, "ufw allow out proto $protocol from $network to any $dst_port"); + } + } + + + } + + foreach ($commands as $command) { + system($command); + } + */ + } + + function insert_forward($event_name,$data) { + global $app, $conf; + + $this->update_filter($event_name,$data); + + } + + function update_forward($event_name,$data) { + global $app, $conf; + + + + } + + //update server config + + function backupConfigs() + { + copy('/etc/default/ufw','/etc/default/ufw~'); + copy('/etc/ufw/ufw.conf','/etc/ufw/ufw.conf~'); + copy('/etc/ufw/before.rules','/etc/ufw/before.rules~'); + } + + function updateSettings($event_name,$data) { + global $app, $conf; + + // get the config + $app->uses("getconf"); + $server_config = $app->getconf->get_server_config($conf["server_id"], 'ufw'); + + + if(is_dir('/etc/ufw') && is_file('/etc/default/ufw')) { + $this->backupConfigs(); + + $app->load('tpl'); + + $ufw_tpl = new tpl(); + $ufw_tpl->newTemplate("ufw.conf.master"); + + $ufw_tpl->setVar('enable',($server_config["ufw_enable"] == "" ? "no" : $server_config["ufw_enable"])); + $ufw_tpl->setVar('log_level',$server_config["ufw_log_level"]); + + + file_put_contents('/etc/ufw/ufw.conf',$ufw_tpl->grab()); + unset($ufw_tpl); + + $app->log("Changed UFW settings",LOGLEVEL_DEBUG); + + $ufw_tpl = new tpl(); + $ufw_tpl->newTemplate("ufw.default.master"); + + $ufw_tpl->setVar('ipv6',$server_config["ufw_ipv6"] == "" ? "no" : $server_config["ufw_ipv6"]); + $ufw_tpl->setVar('default_input_policy',$server_config["ufw_default_input_policy"]); + $ufw_tpl->setVar('default_output_policy',$server_config["ufw_default_output_policy"]); + $ufw_tpl->setVar('default_forward_policy',$server_config["ufw_default_forward_policy"]); + $ufw_tpl->setVar('default_application_policy',$server_config["ufw_default_application_policy"]); + $ufw_tpl->setVar('manage_builtins',$server_config["ufw_manage_builtins"] == "" ? "no" : $server_config["ufw_manage_builtins"]); + + file_put_contents('/etc/default/ufw',$ufw_tpl->grab()); + unset($ufw_tpl); + + $app->log("Changed default UFW settings",LOGLEVEL_DEBUG); + + $app->services->restartServiceDelayed('ufw','--force-reload'); + + } else { + $app->log("Ubuntu Uncomplicated Firewall configuration not available for this linux distribution.",LOGLEVEL_DEBUG); + } + + } + + + + +} // end class + +class UFW { + + var $_delete = false; + var $_ufwCmd = "ufw"; + var $_inboundPolicy = "allow"; + var $_outboundPolicy = "allow"; + var $_protocol = "tcp"; + var $_ruleID = 1; + var $_srcIP; + var $_dstIP; + var $_srcPort; + var $_dstPort; + var $_network = "0.0.0.0/24"; + + function UFW() { + + } + + function setDelete($delete) { + $this->_delete = $delete; + } + + function setInboundPolicy($policy) { + $this->_inboundPolicy = $policy; + } + + function setOutboundPolicy($policy) { + $this->_outboundPolicy = $policy; + } + + function setProtocol($protocol) { + $this->_outboundPolicy = $protocol; + } + + function setRuleID($id) { + $this->_ruleID = $id; + } + + function setSrcIP($ip) { + $this->_srcIP = $ip; + } + + function setDstIP($ip) { + $this->_dstIP = $ip; + } + + function setSrcPort($port) { + $this->_srcPort = $port; + } + + function setDstPort($port) { + $this->_dstPort = $port; + } + + function setNetwork($network) { + $this->_network = $network; + } + + + function insert() { + $protocols = split("/",$this->_protocol); + foreach ($protocols as $protocol) { + $inbound = sprintf("ufw insert %s %s proto %s from %s port %s to %s port %s ", $this->_ruleID, $this->_inboundPolicy, $protocol, $this->_srcIP, $this->_srcPort, $this->_dstIP, $this->_dstPort); + $outbound = sprintf("ufw insert %s %s proto %s from %s port %s to %s port %s ", $this->_ruleID, $this->_outboundPolicy, $protocol, $this->_network, $this->_srcPort, $this->_dstIP, $this->_dstPort); + + echo $inbound."\n"; + echo $outbound."\n"; + system($inbound); + system($outbound); + } + } + + function delete() { + $protocols = split("/",$this->_protocol); + foreach ($protocols as $protocol) { + $inbound = sprintf("ufw delete %s proto %s from %s port %s to %s port %s ", $this->_ruleID, $this->_inboundPolicy, $protocol, $this->_srcIP, $this->_srcPort, $this->_dstIP, $this->_dstPort); + $outbound = sprintf("ufw delete %s proto %s from %s port %s to %s port %s ", $this->_ruleID, $this->_outboundPolicy, $protocol, $this->_network, $this->_srcPort, $this->_dstIP, $this->_dstPort); + + echo $inbound."\n"; + echo $outbound."\n"; + + system($inbound); + system($outbound); + } + } + +} + +?> -- GitLab