From d87f76019fc231ec20d95126a7fee0487e7be5f0 Mon Sep 17 00:00:00 2001
From: tbrehm <t.brehm@ispconfig.org>
Date: Tue, 14 Aug 2012 10:56:20 -0400
Subject: [PATCH] - Added new web folder named private to web folder layout. The folder is intended to store data that shall not be visible in the web directory, it is owned by the user of the web. - Changed ownership of web root directory to root user in all security modes to prevent symlink attacks. - Apache log files are now owned by user root. - Improved functions in system library.
---
server/plugins-available/firewall_plugin.inc.php | 252 +++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 219 insertions(+), 33 deletions(-)
diff --git a/server/plugins-available/firewall_plugin.inc.php b/server/plugins-available/firewall_plugin.inc.php
index f3d81f1..08f735c 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,
@@ -30,15 +30,28 @@
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;
/*
@@ -49,78 +62,251 @@
$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) {
- $p_int = intval($p);
- if($p_int > 0) $tcp_ports .= $p_int . ' ';
+ }
+
+ 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) {
- $p_int = intval($p);
- if($p_int > 0) $udp_ports .= $p_int . ' ';
+ //* 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();
- $tpl->newTemplate("bastille-firewall.cfg.master");
+ $tpl->newTemplate('bastille-firewall.cfg.master');
- $tpl->setVar("TCP_PUBLIC_SERVICES",$tcp_ports);
- $tpl->setVar("UDP_PUBLIC_SERVICES",$udp_ports);
+ $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');
if(@is_file('/etc/debian_version')) exec('update-rc.d bastille-firewall defaults');
$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');
+ exec($conf['init_scripts'] . '/' . 'bastille-firewall stop');
+ if(@is_file('/etc/debian_version')) exec('update-rc.d -f bastille-firewall remove');
$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');
+ exec($conf['init_scripts'] . '/' . 'bastille-firewall stop');
+ if(@is_file('/etc/debian_version')) exec('update-rc.d -f bastille-firewall remove');
$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