From 80e3c9acf3fc9b6d15ea4fea7c89e0a2e12db412 Mon Sep 17 00:00:00 2001
From: tbrehm <t.brehm@ispconfig.org>
Date: Tue, 26 Apr 2011 06:41:58 -0400
Subject: [PATCH] - Improved nginx reverse proxy support. - Added UFW firewall support.

---
 interface/web/sites/templates/web_domain_advanced.htm  |    4 
 server/mods-available/dns_module.inc.php               |    6 
 interface/web/admin/lib/lang/en_server_list.lng        |    2 
 server/conf/nginx_vhost.conf.master                    |   69 +
 server/plugins-available/squid_plugin.inc.php          |  171 ++++
 install/lib/update.lib.php                             |    3 
 interface/lib/classes/plugin.inc.php                   |    9 
 interface/web/admin/form/server.tform.php              |   12 
 interface/web/sites/lib/module.conf.php                |   12 
 install/dist/conf/debian40.conf.php                    |   24 
 install/update.php                                     |   53 +
 server/conf/ufw.before.rules.master                    |   78 ++
 interface/web/login/index.php                          |    6 
 install/dist/conf/debian60.conf.php                    |   23 
 interface/web/admin/form/server_config.tform.php       |   62 +
 server/conf/squidRewriteRules.py.master                |  196 +++++
 install/lib/installer_base.lib.php                     |   86 ++
 install/tpl/squid.conf.master                          |  224 +++++
 install/sql/ispconfig3.sql                             |   69 +
 interface/lib/classes/tform_actions.inc.php            |    2 
 install/tpl/nginx_proxy.conf.master                    |   34 
 interface/web/admin/templates/server_list.htm          |    8 
 server/conf/ufw.conf.master                            |    8 
 server/plugins-available/nginx_plugin.inc.php          |  368 +++++++++
 interface/web/sites/form/web_domain.tform.php          |   12 
 server/conf/ufw.default.master                         |   39 +
 server/conf/nginx_rewrites.conf.master                 |    9 
 install/tpl/nginx_cache.conf.master                    |    6 
 interface/web/admin/templates/server_edit_services.htm |   12 
 interface/web/sites/lib/lang/en_web_domain.lng         |    1 
 install/sql/incremental/upd_0009.sql                   |   66 +
 interface/web/admin/lib/lang/en_server_config.lng      |   17 
 server/plugins-available/ufw_firewall_plugin.inc.php   |  504 ++++++++++++
 interface/lib/config.inc.php                           |    3 
 install/install.php                                    |   67 +
 install/tpl/ufw.conf.master                            |    8 
 interface/lib/plugins/sites_web_domain_plugin.inc.php  |    3 
 server/plugins-available/firewall_plugin.inc.php       |    6 
 interface/web/admin/lib/lang/en_server.lng             |    2 
 interface/web/admin/lib/module.conf.php                |   20 
 40 files changed, 2,259 insertions(+), 45 deletions(-)

diff --git a/install/dist/conf/debian40.conf.php b/install/dist/conf/debian40.conf.php
index a3db4dd..e635b1f 100644
--- a/install/dist/conf/debian40.conf.php
+++ b/install/dist/conf/debian40.conf.php
@@ -51,6 +51,8 @@
 $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']['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 f4e8ba6..71c8a62 100644
--- a/install/dist/conf/debian60.conf.php
+++ b/install/dist/conf/debian60.conf.php
@@ -51,6 +51,8 @@
 $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']['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 d79450f..ba2b087 100644
--- a/install/install.php
+++ b/install/install.php
@@ -230,9 +230,31 @@
 	$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($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 @@
 	$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 @@
 		
 	}
 	
+	//** 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 @@
 	
 	//** 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 2e74e2e..32f34ed 100644
--- a/install/lib/installer_base.lib.php
+++ b/install/lib/installer_base.lib.php
@@ -130,7 +130,12 @@
 		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 @@
 		$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 @@
 		$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 @@
 		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 @@
 
 		} 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 @@
 		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 @@
 		$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 8faff1a..4cc7355 100644
--- a/install/lib/update.lib.php
+++ b/install/lib/update.lib.php
@@ -95,6 +95,9 @@
 	$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 0000000..9da60c1
--- /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 1eb1d57..ff0cfb1 100644
--- a/install/sql/ispconfig3.sql
+++ b/install/sql/ispconfig3.sql
@@ -691,6 +691,8 @@
   `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 @@
   `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',
@@ -1149,6 +1152,8 @@
   `traffic_quota_lock` enum('n','y') NOT NULL default 'n',
   PRIMARY KEY  (`domain_id`)
 ) ENGINE=MyISAM AUTO_INCREMENT=1;
+
+
 
 -- --------------------------------------------------------
 
@@ -1660,6 +1665,70 @@
 
 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 0000000..1cd2863
--- /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 0000000..d8711d0
--- /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 0000000..2ae00d2
--- /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 0000000..9dc02d3
--- /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 fa1cb83..9207299 100644
--- a/install/update.php
+++ b/install/update.php
@@ -256,7 +256,7 @@
 		$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 @@
 	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($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 450efd0..910cc57 100644
--- a/interface/lib/classes/plugin.inc.php
+++ b/interface/lib/classes/plugin.inc.php
@@ -86,7 +86,6 @@
 		
 		$_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 @@
 	 //* 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 f1978ff..d5254c8 100644
--- a/interface/lib/classes/tform_actions.inc.php
+++ b/interface/lib/classes/tform_actions.inc.php
@@ -315,7 +315,7 @@
 						$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 84a15e6..b584146 100644
--- a/interface/lib/config.inc.php
+++ b/interface/lib/config.inc.php
@@ -50,7 +50,7 @@
 //** 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['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 85a4cc0..f41edd6 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 @@
 		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 20947c8..bd556b2 100644
--- a/interface/web/admin/form/server.tform.php
+++ b/interface/web/admin/form/server.tform.php
@@ -102,6 +102,18 @@
 			'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 c9b3500..4db9551 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"]['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 dcd46c5..4130201 100644
--- a/interface/web/admin/lib/lang/en_server.lng
+++ b/interface/web/admin/lib/lang/en_server.lng
@@ -7,6 +7,8 @@
 $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 f672e99..7c0c459 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 @@
 <?php
-$wb["try_rescue_txt"] = 'Activate rescue of all services installed at this server';
-$wb["do_not_try_rescue_apache_txt"] = 'If rescue ist activated, do NOT try to rescue Apache';
-$wb["do_not_try_rescue_mysql_txt"] = 'If rescue ist activated, do NOT try to rescue mysql';
-$wb["do_not_try_rescue_mail_txt"] = 'If rescue ist activated, do NOT try to rescue mail';
+$wb["ufw_enable_txt"] = 'Enable';
+$wb["ufw_manage_builtins_txt"] = 'Manage Builtin Rules';
+$wb["ufw_ipv6_txt"] = 'Enable IPv6';
+$wb["ufw_default_input_policy_txt"] = 'Default Input Policy';
+$wb["ufw_default_output_policy_txt"] = 'Default Output Policy';
+$wb["ufw_default_forward_policy_txt"] = 'Default Forward Policy';
+$wb["ufw_default_application_policy_txt"] = 'Default Application Policy';
+$wb["ufw_log_level_txt"] = 'Log Level';
+
 $wb["jailkit_chroot_home_txt"] = 'Jailkit chroot home';
 $wb["jailkit_chroot_app_sections_txt"] = 'Jailkit chroot app sections';
 $wb["jailkit_chroot_app_programs_txt"] = 'Jailkit chrooted applications';
-$wb["jailkit_chroot_cron_programs_txt"] = 'Jailkit cron chrooted applications';
+$wb['jailkit_chroot_cron_programs_txt'] = 'Jailkit cron chrooted applications';
 $wb["website_path_txt"] = 'Website path';
 $wb["website_symlinks_txt"] = 'Website symlinks';
 $wb["website_basedir_txt"] = 'Website basedir';
@@ -79,6 +84,4 @@
 $wb["php_ini_path_apache_txt"] = 'Apache php.ini path';
 $wb["check_apache_config_txt"] = 'Test apache configuration on restart';
 $wb["network_config_warning_txt"] = 'The network configuration option is only available for Debian and Ubuntu Servers. Do not enable this option if your network interface is not eth0.';
-$wb["CA_path_txt"] = 'CA Path';
-$wb["CA_pass_txt"] = 'CA passphrase';
 ?>
\ 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 d15701e..164468e 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["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 25c38bc..1ec23de 100644
--- a/interface/web/admin/lib/module.conf.php
+++ b/interface/web/admin/lib/module.conf.php
@@ -85,11 +85,27 @@
 // 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 8eca290..17ff55d 100644
--- a/interface/web/admin/templates/server_edit_services.htm
+++ b/interface/web/admin/templates/server_edit_services.htm
@@ -46,6 +46,18 @@
 					</div>
 			</div>
 	  <div class="ctrlHolder">
+                <p class="label">{tmpl_var name='proxy_server_txt'}</p>
+                    <div class="multiField">
+                        {tmpl_var name='proxy_server'}
+                    </div>
+      </div>
+      <div class="ctrlHolder">
+                <p class="label">{tmpl_var name='firewall_server_txt'}</p>
+                    <div class="multiField">
+                        {tmpl_var name='firewall_server'}
+                    </div>
+      </div>
+	  <div class="ctrlHolder">
 		<label for="mirror_server_id">{tmpl_var name='mirror_server_id_txt'}</label>
         <select name="mirror_server_id" id="server_id" class="selectInput">
 		  {tmpl_var name='mirror_server_id'}
diff --git a/interface/web/admin/templates/server_list.htm b/interface/web/admin/templates/server_list.htm
index 7163843..2168091 100644
--- a/interface/web/admin/templates/server_list.htm
+++ b/interface/web/admin/templates/server_list.htm
@@ -15,6 +15,8 @@
             <th class="tbl_col_file_server" scope="col"><tmpl_var name="file_server_txt"></th>
             <th class="tbl_col_db_server" scope="col"><tmpl_var name="db_server_txt"></th>
             <th class="tbl_col_vserver_server" scope="col"><tmpl_var name="vserver_server_txt"></th>
+			<th class="tbl_col_proxy_server" scope="col"><tmpl_var name="proxy_server_txt"></th>
+            <th class="tbl_col_firewall_server" scope="col"><tmpl_var name="firewall_server_txt"></th>
             <th class="tbl_col_buttons" scope="col">&nbsp;</th>
           </tr>
           <tr>
@@ -25,7 +27,9 @@
             <td class="tbl_col_file_server"><select name="search_active" onChange="submitForm('pageForm','admin/server_list.php');">{tmpl_var name='search_file_server'}</select></td>
             <td class="tbl_col_db_server"><select name="search_active" onChange="submitForm('pageForm','admin/server_list.php');">{tmpl_var name='search_db_server'}</select></td>
             <td class="tbl_col_vserver_server"><select name="search_active" onChange="submitForm('pageForm','admin/server_list.php');">{tmpl_var name='search_vserver_server'}</select></td>
-            <td class="tbl_col_buttons"><div class="buttons"><button type="button" class="icons16 icoFilter" name="Filter" id="Filter" value="{tmpl_var name="filter_txt"}" onClick="submitForm('pageForm','admin/server_list.php');"><span>{tmpl_var name="filter_txt"}</span></button></div></td>
+            <td class="tbl_col_proxy_server"><select name="search_active" onChange="submitForm('pageForm','admin/server_list.php');">{tmpl_var name='search_proxy_server'}</select></td>
+            <td class="tbl_col_firewallserver"><select name="search_active" onChange="submitForm('pageForm','admin/server_list.php');">{tmpl_var name='search_firewall_server'}</select></td>
+			<td class="tbl_col_buttons"><div class="buttons"><button type="button" class="icons16 icoFilter" name="Filter" id="Filter" value="{tmpl_var name="filter_txt"}" onClick="submitForm('pageForm','admin/server_list.php');"><span>{tmpl_var name="filter_txt"}</span></button></div></td>
           </tr>
         </thead>
         <tbody>
@@ -38,6 +42,8 @@
             <td class="tbl_col_file_server">{tmpl_var name="file_server"}</td>
             <td class="tbl_col_db_server">{tmpl_var name="db_server"}</td>
             <td class="tbl_col_vserver_server">{tmpl_var name="vserver_server"}</td>
+			<td class="tbl_col_proxy_server">{tmpl_var name="proxy_server"}</td>
+            <td class="tbl_col_firewall_server">{tmpl_var name="firewall_server"}</td>
             <td class="tbl_col_buttons">
               <div class="buttons icons16">    
                 <a class="icons16 icoDelete" href="javascript: del_record('admin/server_del.php?id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}','{tmpl_var name='delete_confirmation'}');"><span>{tmpl_var name='delete_txt'}</span></a>
diff --git a/interface/web/login/index.php b/interface/web/login/index.php
index be91708..9216f79 100644
--- a/interface/web/login/index.php
+++ b/interface/web/login/index.php
@@ -106,21 +106,27 @@
 	        	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 29952e7..5f69079 100644
--- a/interface/web/sites/form/web_domain.tform.php
+++ b/interface/web/sites/form/web_domain.tform.php
@@ -485,9 +485,9 @@
 		'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 @@
 			'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 d709cc5..e9b4bbf 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_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 46502ce..b96ac1d 100644
--- a/interface/web/sites/lib/module.conf.php
+++ b/interface/web/sites/lib/module.conf.php
@@ -156,5 +156,17 @@
 // 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);
+
 
 ?>
\ No newline at end of file
diff --git a/interface/web/sites/templates/web_domain_advanced.htm b/interface/web/sites/templates/web_domain_advanced.htm
index 9ad803c..488fff2 100644
--- a/interface/web/sites/templates/web_domain_advanced.htm
+++ b/interface/web/sites/templates/web_domain_advanced.htm
@@ -32,6 +32,10 @@
       	<label for="apache_directives">{tmpl_var name='apache_directives_txt'}</label>
       	<textarea name="apache_directives" id="apache_directives" rows='10' cols='50' style="width:400px;">{tmpl_var name='apache_directives'}</textarea>
 	  </div>
+      <div class="ctrlHolder">
+      	<label for="nginx_directives">{tmpl_var name='nginx_directives_txt'}</label>
+      	<textarea name="nginx_directives" id="nginx_directives" rows='10' cols='50' style="width:400px;">{tmpl_var name='nginx_directives'}</textarea>
+	  </div>
     </fieldset>
 
     <input type="hidden" name="id" value="{tmpl_var name='id'}">
diff --git a/server/conf/nginx_rewrites.conf.master b/server/conf/nginx_rewrites.conf.master
new file mode 100644
index 0000000..b5d2ad5
--- /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;
+    <tmpl_loop name="nginx_rewrite_rules">
+        rewrite ^{tmpl_var name="rewrite_url_src"}  {tmpl_var name="rewrite_url_dst"};
+    </tmpl_loop>
+}
diff --git a/server/conf/nginx_vhost.conf.master b/server/conf/nginx_vhost.conf.master
new file mode 100644
index 0000000..83ed251
--- /dev/null
+++ b/server/conf/nginx_vhost.conf.master
@@ -0,0 +1,69 @@
+server {
+        listen   80;
+        server_name  <tmpl_var name='alias'> <tmpl_var name='domain'>;
+
+        access_log  /var/log/ispconfig/nginx/<tmpl_var name='domain'>/access.log;
+        error_log  /var/log/ispconfig/nginx/<tmpl_var name='domain'>/error.log;
+
+        include         /etc/nginx/proxy.conf;
+
+        location / {
+                proxy_pass      http://<tmpl_var name='ip_address'>: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://<tmpl_var name='ip_address'>:80;
+        }
+
+        <tmpl_if name='nginx_directives'>
+            <tmpl_var name='nginx_directives'>
+        </tmpl_if>
+
+
+
+}
+
+
+<tmpl_if name='ssl_enabled'>
+###########################################################
+# SSL Vhost
+###########################################################
+server {
+        listen   443;
+        server_name  <tmpl_var name='ssl_domain'> <tmpl_var name='alias'>;
+
+        access_log  /var/log/ispconfig/nginx/<tmpl_var name='domain'>/access.log
+        error_log  /var/log/ispconfig/nginx/<tmpl_var name='domain'>/error.log
+        
+        ### SSL cert files ###
+        ssl_certificate      <tmpl_var name='config_dir'>/ssl/<tmpl_var name='ssl_domain'>.crt
+        ssl_certificate_key  <tmpl_var name='config_dir'>/ssl/<tmpl_var name='ssl_domain'>.crt
+        
+        <tmpl_if name='has_bundle_cert'>
+            ssl_client_certificate <tmpl_var name='config_dir'>/ssl/<tmpl_var name='ssl_domain'>.bundle
+        </tmpl_if>
+        
+        ### 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://<tmpl_var name='ip_address'>:443;
+        }
+}
+</tmpl_if>
diff --git a/server/conf/squidRewriteRules.py.master b/server/conf/squidRewriteRules.py.master
new file mode 100644
index 0000000..6005bb3
--- /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
+
+<tmpl_loop name="squid_rewrite_rules">
+    (r'{tmpl_var name="rewrite_url_src"}', r'{tmpl_var name="rewrite_url_dest"}\1', 'P,L'),
+</tmpl_loop>
+
+  
+
+
+
+)
+
+
+
+"""
+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 0000000..ab45171
--- /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 0000000..7870d63
--- /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 0000000..6a20500
--- /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 d5c9ac7..01c4526 100644
--- a/server/mods-available/dns_module.inc.php
+++ b/server/mods-available/dns_module.inc.php
@@ -47,7 +47,11 @@
 	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 d9d1272..6697798 100644
--- a/server/plugins-available/firewall_plugin.inc.php
+++ b/server/plugins-available/firewall_plugin.inc.php
@@ -38,7 +38,11 @@
 	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 0000000..a200daf
--- /dev/null
+++ b/server/plugins-available/nginx_plugin.inc.php
@@ -0,0 +1,368 @@
+<?php
+
+class nginx_plugin {
+
+	var $plugin_name = 'nginx_plugin';
+	var $class_name = 'nginx_plugin';
+
+	// private variables
+	var $action = '';
+
+	//* This function is called during ispconfig installation to determine
+	//  if a symlink shall be created for this plugin.
+	function onInstall() {
+		global $conf;
+
+		if($conf['services']['proxy'] == true && $conf['nginx']['installed'] == true) {
+			return true;
+		} else {
+			return false;
+		}
+
+	}
+
+
+	/*
+	 	This function is called when the plugin is loaded
+	*/
+
+	function onLoad() {
+		global $app;
+
+		/*
+		Register for the events
+		*/
+		
+		$app->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 0000000..fb667e0
--- /dev/null
+++ b/server/plugins-available/squid_plugin.inc.php
@@ -0,0 +1,171 @@
+<?php
+
+/*
+Copyright (c) 2007, Till Brehm, projektfarm Gmbh
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+    * Neither the name of ISPConfig nor the names of its contributors
+      may be used to endorse or promote products derived from this software without
+      specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+class squid_plugin {
+	
+	var $plugin_name = 'squid_plugin';
+	var $class_name = 'squid_plugin';
+	
+	// private variables
+	var $action = '';
+	
+	//* This function is called during ispconfig installation to determine
+	//  if a symlink shall be created for this plugin.
+	function onInstall() {
+		global $conf;
+		
+		if($conf['services']['proxy'] == true && $conf['squid']['installed'] == true) {
+			return true;
+		} else {
+			return false;
+		}
+		
+	}
+	
+		
+	/*
+	 	This function is called when the plugin is loaded
+	*/
+	
+	function onLoad() {
+		global $app;
+		
+		/*
+		Register for the events
+		*/
+		
+		
+		$app->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 0000000..4eb1e1f
--- /dev/null
+++ b/server/plugins-available/ufw_firewall_plugin.inc.php
@@ -0,0 +1,504 @@
+<?php
+
+/*
+Copyright (c) 2007, Till Brehm, projektfarm Gmbh
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+    * Neither the name of ISPConfig nor the names of its contributors
+      may be used to endorse or promote products derived from this software without
+      specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+class ufw_firewall_plugin {
+	
+	var $plugin_name = 'ufw_firewall_plugin';
+	var $class_name  = 'ufw_firewall_plugin';
+	
+	//* This function is called during ispconfig installation to determine
+	//  if a symlink shall be created for this plugin.
+	function onInstall() {
+		global $conf;
+		if ($conf['ufw']['installed'] == true && $conf['services']['firewall'] == true) {
+			return true;
+		} else {
+			return false;
+		}
+		
+	}
+	
+		
+	/*
+	 	This function is called when the plugin is loaded
+	*/
+	
+	function onLoad() {
+		global $app;
+		
+		/*
+		Register for the events
+		*/
+		
+		$app->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);
+		}
+	}
+		
+}
+
+?>

--
Gitblit v1.9.1