From 42f191ba77aa9293098b3327d6415f02483fcf6b Mon Sep 17 00:00:00 2001
From: tbrehm <t.brehm@ispconfig.org>
Date: Thu, 07 Jun 2012 05:09:37 -0400
Subject: [PATCH] Implemented support for UFW firewall (FS#1757 - New IPTables firewall script for IPv4 and IPv6)
---
server/plugins-available/firewall_plugin.inc.php | 229 +++++++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 196 insertions(+), 33 deletions(-)
diff --git a/server/plugins-available/firewall_plugin.inc.php b/server/plugins-available/firewall_plugin.inc.php
index 6697798..08f735c 100644
--- a/server/plugins-available/firewall_plugin.inc.php
+++ b/server/plugins-available/firewall_plugin.inc.php
@@ -30,12 +30,12 @@
class firewall_plugin {
- var $plugin_name = 'firewall_plugin';
- var $class_name = 'firewall_plugin';
+ private $plugin_name = 'firewall_plugin';
+ private $class_name = 'firewall_plugin';
//* This function is called during ispconfig installation to determine
// if a symlink shall be created for this plugin.
- function onInstall() {
+ public function onInstall() {
global $conf;
if($conf['bastille']['installed'] = true && $conf['services']['firewall'] == true) {
@@ -51,7 +51,7 @@
This function is called when the plugin is loaded
*/
- function onLoad() {
+ public function onLoad() {
global $app;
/*
@@ -62,51 +62,182 @@
$app->plugins->registerEvent('firewall_insert',$this->plugin_name,'insert');
$app->plugins->registerEvent('firewall_update',$this->plugin_name,'update');
$app->plugins->registerEvent('firewall_delete',$this->plugin_name,'delete');
-
-
}
- function insert($event_name,$data) {
+ public function insert($event_name,$data) {
global $app, $conf;
$this->update($event_name,$data);
}
- function update($event_name,$data) {
+ public function update($event_name,$data) {
global $app, $conf;
- $tcp_ports = '';
- $udp_ports = '';
+ //* load the server configuration options
+ $app->uses('getconf');
+ $server_config = $app->getconf->get_server_config($conf['server_id'], 'server');
+ if($server_config['firewall'] == 'ufw') {
+ $this->ufw_update($event_name,$data);
+ } else {
+ $this->bastille_update($event_name,$data);
+ }
- $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);
- }
- $tcp_ports .= $p_clean . ' ';
+ }
+
+ public function delete($event_name,$data) {
+ global $app, $conf;
+
+ //* load the server configuration options
+ $app->uses('getconf');
+ $server_config = $app->getconf->get_server_config($conf['server_id'], 'server');
+
+ if($server_config['firewall'] == 'ufw') {
+ $this->ufw_delete($event_name,$data);
+ } else {
+ $this->bastille_delete($event_name,$data);
+ }
+
+ }
+
+ private function ufw_update($event_name,$data) {
+ global $app, $conf;
+
+ $app->uses('system');
+
+ if(!$app->system->is_installed('ufw')) {
+ $app->log('UFW Firewall is not installed',LOGLEVEL_WARN);
+ return false;
+ }
+
+ exec('ufw --version',$out);
+ $parts = explode(' ',$out[0]);
+ $ufwversion = $parts[1];
+ unset($parts);
+ unset($out);
+
+ if(version_compare ( $ufwversion , '0.30') < 0) {
+ $app->log('The installed UFW Firewall version is too old. Minimum required version 0.30',LOGLEVEL_WARN);
+ return false;
+ }
+
+ //* Basic firewall setup when the firewall is added the first time
+ if($event_name == 'firewall_insert') {
+ exec('ufw --force disable');
+ exec('ufw --force reset');
+ exec('ufw default deny incoming');
+ exec('ufw default allow outgoing');
+ }
+
+ $tcp_ports_new = $this->clean_ports($data['new']['tcp_port'],',');
+ $tcp_ports_old = $this->clean_ports($data['old']['tcp_port'],',');
+ $udp_ports_new = $this->clean_ports($data['new']['udp_port'],',');
+ $udp_ports_old = $this->clean_ports($data['old']['udp_port'],',');
+
+ $tcp_ports_new_array = explode(',',$tcp_ports_new);
+ $tcp_ports_old_array = explode(',',$tcp_ports_old);
+ $udp_ports_new_array = explode(',',$udp_ports_new);
+ $udp_ports_old_array = explode(',',$udp_ports_old);
+
+ //* add tcp ports
+ foreach($tcp_ports_new_array as $port) {
+ if(!in_array($port,$tcp_ports_old_array) && $port > 0) {
+ exec('ufw allow '.$port.'/tcp');
+ $app->log('ufw allow '.$port.'/tcp',LOGLEVEL_DEBUG);
+ sleep(1);
}
}
- $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);
- }
- $udp_ports .= $p_clean . ' ';
+ //* remove tcp ports
+ foreach($tcp_ports_old_array as $port) {
+ if(!in_array($port,$tcp_ports_new_array) && $port > 0) {
+ exec('ufw delete allow '.$port.'/tcp');
+ $app->log('ufw delete allow '.$port.'/tcp',LOGLEVEL_DEBUG);
+ sleep(1);
}
}
- $udp_ports = trim($udp_ports);
+
+ //* add udp ports
+ foreach($udp_ports_new_array as $port) {
+ if(!in_array($port,$udp_ports_old_array) && $port > 0) {
+ exec('ufw allow '.$port.'/udp');
+ $app->log('ufw allow '.$port.'/udp',LOGLEVEL_DEBUG);
+ sleep(1);
+ }
+ }
+
+ //* remove udp ports
+ foreach($udp_ports_old_array as $port) {
+ if(!in_array($port,$udp_ports_new_array) && $port > 0) {
+ exec('ufw delete allow '.$port.'/udp');
+ $app->log('ufw delete allow '.$port.'/udp',LOGLEVEL_DEBUG);
+ sleep(1);
+ }
+ }
+
+ /*
+ if($tcp_ports_new != $tcp_ports_old) {
+ exec('ufw allow to any proto tcp port '.$tcp_ports_new);
+ $app->log('ufw allow to any proto tcp port '.$tcp_ports_new,LOGLEVEL_DEBUG);
+ if($event_name == 'firewall_update') {
+ exec('ufw delete allow to any proto tcp port '.$tcp_ports_old);
+ $app->log('ufw delete allow to any proto tcp port '.$tcp_ports_old,LOGLEVEL_DEBUG);
+ }
+ }
+
+ if($udp_ports_new != $udp_ports_old) {
+ exec('ufw allow to any proto udp port '.$udp_ports_new);
+ $app->log('ufw allow to any proto udp port '.$udp_ports_new,LOGLEVEL_DEBUG);
+ if($event_name == 'firewall_update') {
+ exec('ufw delete allow to any proto udp port '.$udp_ports_old);
+ $app->log('ufw delete allow to any proto udp port '.$udp_ports_old,LOGLEVEL_DEBUG);
+ }
+ }
+ */
+
+ if($data['new']['active'] == 'y') {
+ if($data['new']['active'] == $data['old']['active']) {
+ exec('ufw reload');
+ $app->log('Reloading the firewall',LOGLEVEL_DEBUG);
+ } else {
+ //* Ensure that bastille firewall is stopped
+ exec($conf['init_scripts'] . '/' . 'bastille-firewall stop');
+ if(@is_file('/etc/debian_version')) exec('update-rc.d -f bastille-firewall remove');
+
+ //* Start ufw firewall
+ exec('ufw --force enable');
+ $app->log('Starting the firewall',LOGLEVEL_DEBUG);
+ }
+ } else {
+ exec('ufw disable');
+ $app->log('Stopping the firewall',LOGLEVEL_DEBUG);
+ }
+ }
+
+ private function ufw_delete($event_name,$data) {
+ global $app, $conf;
+
+ $app->uses('system');
+
+ if(!$app->system->is_installed('ufw')) {
+ $app->log('UFW Firewall is not installed',LOGLEVEL_DEBUG);
+ return false;
+ }
+
+ exec('ufw --force reset');
+ exec('ufw disable');
+ $app->log('Stopping the firewall',LOGLEVEL_DEBUG);
+
+ }
+
+ private function bastille_update($event_name,$data) {
+ global $app, $conf;
+
+ $app->uses('system');
+
+ $tcp_ports = $this->clean_ports($data['new']['tcp_port'],' ');
+ $udp_ports = $this->clean_ports($data['new']['udp_port'],' ');
$app->load('tpl');
$tpl = new tpl();
@@ -120,6 +251,10 @@
unset($tpl);
if($data['new']['active'] == 'y') {
+ //* ensure that ufw firewall is disabled in case both firewalls are installed
+ if($app->system->is_installed('ufw')) {
+ exec('ufw disable');
+ }
exec($conf['init_scripts'] . '/' . 'bastille-firewall restart');
if(@is_file('/etc/debian_version')) exec('update-rc.d bastille-firewall defaults');
$app->log('Restarting the firewall',LOGLEVEL_DEBUG);
@@ -132,7 +267,7 @@
}
- function delete($event_name,$data) {
+ private function bastille_delete($event_name,$data) {
global $app, $conf;
exec($conf['init_scripts'] . '/' . 'bastille-firewall stop');
@@ -142,6 +277,34 @@
}
+ private function clean_ports($portlist,$spacer) {
+
+ $ports = explode(',',$portlist);
+ $ports_out = '';
+
+ if(is_array($ports)) {
+ foreach($ports as $p) {
+ $p_clean = '';
+ if(strstr($p,':')) {
+ $p_parts = explode(':',$p);
+ $tmp_lower = intval($p_parts[0]);
+ $tmp_higher = intval($p_parts[1]);
+ if($tmp_lower > 0 && $tmp_lower <= 65535 && $tmp_higher > 0 && $tmp_higher <= 65535 && $tmp_lower < $tmp_higher) {
+ $p_clean = $tmp_lower.':'.$tmp_higher;
+ }
+ } else {
+ $tmp = intval($p);
+ if($tmp > 0 && $tmp <= 65535) {
+ $p_clean = $tmp;
+ }
+ }
+ if($p_clean != '') $ports_out .= $p_clean . $spacer;
+
+ }
+ }
+ return substr($ports_out,0,strlen($spacer)*-1);
+ }
+
} // end class
--
Gitblit v1.9.1