From e1ceb050e19c7574bca146a8da7047ee4ff456b5 Mon Sep 17 00:00:00 2001
From: Marius Burkard <m.burkard@pixcept.de>
Date: Sun, 10 Jul 2016 05:02:35 -0400
Subject: [PATCH] Merge branch 'stable-3.1'
---
server/plugins-available/firewall_plugin.inc.php | 327 +++++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 259 insertions(+), 68 deletions(-)
diff --git a/server/plugins-available/firewall_plugin.inc.php b/server/plugins-available/firewall_plugin.inc.php
index f3d81f1..d3538cc 100644
--- a/server/plugins-available/firewall_plugin.inc.php
+++ b/server/plugins-available/firewall_plugin.inc.php
@@ -1,7 +1,7 @@
<?php
/*
-Copyright (c) 2008, Till Brehm, projektfarm Gmbh
+Copyright (c) 2007, Till Brehm, projektfarm Gmbh
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -29,98 +29,289 @@
*/
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.
+ public function onInstall() {
+ global $conf;
+
+ if($conf['bastille']['installed'] == true && $conf['services']['firewall'] == true) {
+ return true;
+ } else {
+ return false;
+ }
+
+ }
+
+
/*
This function is called when the plugin is loaded
*/
-
- function onLoad() {
+
+ public function onLoad() {
global $app;
-
+
/*
Register for the events
*/
-
+
//* Mailboxes
- $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');
-
-
+ $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);
-
+
+ $this->update($event_name, $data);
+
}
-
- function update($event_name,$data) {
+
+ public function update($event_name, $data) {
global $app, $conf;
-
- $tcp_ports = '';
- $udp_ports = '';
-
- $ports = explode(',',$data["new"]["tcp_port"]);
- if(is_array($ports)) {
- foreach($ports as $p) {
- $p_int = intval($p);
- if($p_int > 0) $tcp_ports .= $p_int . ' ';
+
+ //* load the server configuration options
+ if(!$data['mirrored']) {
+ $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);
}
}
- $tcp_ports = trim($tcp_ports);
-
- $ports = explode(',',$data["new"]["udp_port"]);
- if(is_array($ports)) {
- foreach($ports as $p) {
- $p_int = intval($p);
- if($p_int > 0) $udp_ports .= $p_int . ' ';
+ }
+
+ public function delete($event_name, $data) {
+ global $app, $conf;
+
+ //* load the server configuration options
+ if(!$data['mirrored']) {
+ $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);
}
}
- $udp_ports = trim($udp_ports);
-
+ }
+
+ 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);
+ }
+ }
+
+ //* 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);
+ }
+ }
+
+ //* 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 2>/dev/null');
+ 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();
- $tpl->newTemplate("bastille-firewall.cfg.master");
-
- $tpl->setVar("TCP_PUBLIC_SERVICES",$tcp_ports);
- $tpl->setVar("UDP_PUBLIC_SERVICES",$udp_ports);
-
- file_put_contents('/etc/Bastille/bastille-firewall.cfg',$tpl->grab());
- $app->log('Writing firewall configuration /etc/Bastille/bastille-firewall.cfg',LOGLEVEL_DEBUG);
+ $tpl->newTemplate('bastille-firewall.cfg.master');
+
+ $tpl->setVar('TCP_PUBLIC_SERVICES', $tcp_ports);
+ $tpl->setVar('UDP_PUBLIC_SERVICES', $udp_ports);
+
+ file_put_contents('/etc/Bastille/bastille-firewall.cfg', $tpl->grab());
+ $app->log('Writing firewall configuration /etc/Bastille/bastille-firewall.cfg', LOGLEVEL_DEBUG);
unset($tpl);
-
- if($data["new"]["active"] == 'y') {
- exec('/etc/init.d/bastille-firewall restart');
+
+ 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 2>/dev/null');
if(@is_file('/etc/debian_version')) exec('update-rc.d bastille-firewall defaults');
- $app->log('Restarting the firewall',LOGLEVEL_DEBUG);
+ if(@is_file('/sbin/insserv')) exec('insserv -d bastille-firewall');
+ $app->log('Restarting the firewall', LOGLEVEL_DEBUG);
} else {
- exec('/etc/init.d/bastille-firewall stop');
- if(@is_file('/etc/debian_version')) exec('update-rc.d bastille-firewall remove');
- $app->log('Stopping the firewall',LOGLEVEL_DEBUG);
+ exec($conf['init_scripts'] . '/' . 'bastille-firewall stop 2>/dev/null');
+ if(@is_file('/etc/debian_version')) exec('update-rc.d -f bastille-firewall remove');
+ if(@is_file('/sbin/insserv')) exec('insserv -r -f bastille-firewall');
+ $app->log('Stopping the firewall', LOGLEVEL_DEBUG);
}
-
-
+
+
}
-
- function delete($event_name,$data) {
+
+ private function bastille_delete($event_name, $data) {
global $app, $conf;
-
- exec('/etc/init.d/bastille-firewall stop');
- if(@is_file('/etc/debian_version')) exec('update-rc.d bastille-firewall remove');
- $app->log('Stopping the firewall',LOGLEVEL_DEBUG);
-
+
+ exec($conf['init_scripts'] . '/' . 'bastille-firewall stop 2>/dev/null');
+ if(@is_file('/etc/debian_version')) exec('update-rc.d -f bastille-firewall remove');
+ if(@is_file('/sbin/insserv')) exec('insserv -r -f bastille-firewall');
+ $app->log('Stopping the firewall', LOGLEVEL_DEBUG);
+
}
-
-
-
+
+
+ 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
-?>
\ No newline at end of file
+?>
--
Gitblit v1.9.1