tbrehm
2013-02-22 526b997c9891a796b152cdbab8e329b356b1f596
server/plugins-available/firewall_plugin.inc.php
@@ -30,15 +30,19 @@
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;
      
      return true;
      if($conf['bastille']['installed'] = true && $conf['services']['firewall'] == true) {
         return true;
      } else {
         return false;
      }
      
   }
   
@@ -47,7 +51,7 @@
       This function is called when the plugin is loaded
   */
   
   function onLoad() {
   public function onLoad() {
      global $app;
      
      /*
@@ -58,69 +62,204 @@
      $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);
            }
            if($p_int > 0) $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);
            }
            if($p_int > 0) $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 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->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 2>/dev/null');
         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');
         exec($conf['init_scripts'] . '/' . 'bastille-firewall stop 2>/dev/null');
         if(@is_file('/etc/debian_version')) exec('update-rc.d -f bastille-firewall remove');
         $app->log('Stopping the firewall',LOGLEVEL_DEBUG);
      }
@@ -128,18 +267,46 @@
      
   }
   
   function delete($event_name,$data) {
   private function bastille_delete($event_name,$data) {
      global $app, $conf;
      
      exec('/etc/init.d/bastille-firewall stop');
      exec($conf['init_scripts'] . '/' . 'bastille-firewall stop 2>/dev/null');
      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
?>
?>