tbrehm
2013-02-22 526b997c9891a796b152cdbab8e329b356b1f596
commit | author | age
7c99ef 1 <?php
T 2
3 /*
436ed8 4 Copyright (c) 2007, Till Brehm, projektfarm Gmbh
7c99ef 5 All rights reserved.
T 6
7 Redistribution and use in source and binary forms, with or without modification,
8 are permitted provided that the following conditions are met:
9
10     * Redistributions of source code must retain the above copyright notice,
11       this list of conditions and the following disclaimer.
12     * Redistributions in binary form must reproduce the above copyright notice,
13       this list of conditions and the following disclaimer in the documentation
14       and/or other materials provided with the distribution.
15     * Neither the name of ISPConfig nor the names of its contributors
16       may be used to endorse or promote products derived from this software without
17       specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26 OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 class firewall_plugin {
32     
42f191 33     private $plugin_name = 'firewall_plugin';
T 34     private $class_name  = 'firewall_plugin';
7c99ef 35     
392450 36     //* This function is called during ispconfig installation to determine
T 37     //  if a symlink shall be created for this plugin.
42f191 38     public function onInstall() {
392450 39         global $conf;
T 40         
80e3c9 41         if($conf['bastille']['installed'] = true && $conf['services']['firewall'] == true) {
T 42             return true;
43         } else {
44             return false;
45         }
392450 46         
T 47     }
48     
7c99ef 49         
T 50     /*
51          This function is called when the plugin is loaded
52     */
53     
42f191 54     public function onLoad() {
7c99ef 55         global $app;
T 56         
57         /*
58         Register for the events
59         */
60         
61         //* Mailboxes
62         $app->plugins->registerEvent('firewall_insert',$this->plugin_name,'insert');
63         $app->plugins->registerEvent('firewall_update',$this->plugin_name,'update');
64         $app->plugins->registerEvent('firewall_delete',$this->plugin_name,'delete');
65     }
66     
67     
42f191 68     public function insert($event_name,$data) {
7c99ef 69         global $app, $conf;
T 70         
71         $this->update($event_name,$data);
72         
73     }
74     
42f191 75     public function update($event_name,$data) {
7c99ef 76         global $app, $conf;
T 77         
42f191 78         //* load the server configuration options
T 79         $app->uses('getconf');
80         $server_config = $app->getconf->get_server_config($conf['server_id'], 'server');
81         if($server_config['firewall'] == 'ufw') {
82             $this->ufw_update($event_name,$data);
83         } else {
84             $this->bastille_update($event_name,$data);
85         }
7c99ef 86         
42f191 87     }
T 88     
89     public function delete($event_name,$data) {
90         global $app, $conf;
91         
92         //* load the server configuration options
93         $app->uses('getconf');
94         $server_config = $app->getconf->get_server_config($conf['server_id'], 'server');
95         
96         if($server_config['firewall'] == 'ufw') {
97             $this->ufw_delete($event_name,$data);
98         } else {
99             $this->bastille_delete($event_name,$data);
100         }
101         
102     }
103     
104     private function ufw_update($event_name,$data) {
105         global $app, $conf;
106         
107         $app->uses('system');
108         
109         if(!$app->system->is_installed('ufw')) {
110             $app->log('UFW Firewall is not installed',LOGLEVEL_WARN);
111             return false;
112         }
113         
114         exec('ufw --version',$out);
115         $parts = explode(' ',$out[0]);
116         $ufwversion = $parts[1];
117         unset($parts);
118         unset($out);
119
120         if(version_compare ( $ufwversion , '0.30') < 0) {
121             $app->log('The installed UFW Firewall version is too old. Minimum required version 0.30',LOGLEVEL_WARN);
122             return false;
123         }
124         
125         //* Basic firewall setup when the firewall is added the first time
126         if($event_name == 'firewall_insert') {
127             exec('ufw --force disable');
128             exec('ufw --force reset');
129             exec('ufw default deny incoming');
130             exec('ufw default allow outgoing');
131         }
132         
133         $tcp_ports_new = $this->clean_ports($data['new']['tcp_port'],',');
134         $tcp_ports_old = $this->clean_ports($data['old']['tcp_port'],',');
135         $udp_ports_new = $this->clean_ports($data['new']['udp_port'],',');
136         $udp_ports_old = $this->clean_ports($data['old']['udp_port'],',');
137         
138         $tcp_ports_new_array = explode(',',$tcp_ports_new);
139         $tcp_ports_old_array = explode(',',$tcp_ports_old);
140         $udp_ports_new_array = explode(',',$udp_ports_new);
141         $udp_ports_old_array = explode(',',$udp_ports_old);
142         
143         //* add tcp ports
144         foreach($tcp_ports_new_array as $port) {
145             if(!in_array($port,$tcp_ports_old_array) && $port > 0) {
146                 exec('ufw allow '.$port.'/tcp');
147                 $app->log('ufw allow '.$port.'/tcp',LOGLEVEL_DEBUG);
148                 sleep(1);
7c99ef 149             }
T 150         }
151         
42f191 152         //* remove tcp ports
T 153         foreach($tcp_ports_old_array as $port) {
154             if(!in_array($port,$tcp_ports_new_array) && $port > 0) {
155                 exec('ufw delete allow '.$port.'/tcp');
156                 $app->log('ufw delete allow '.$port.'/tcp',LOGLEVEL_DEBUG);
157                 sleep(1);
7c99ef 158             }
T 159         }
42f191 160         
T 161         //* add udp ports
162         foreach($udp_ports_new_array as $port) {
163             if(!in_array($port,$udp_ports_old_array) && $port > 0) {
164                 exec('ufw allow '.$port.'/udp');
165                 $app->log('ufw allow '.$port.'/udp',LOGLEVEL_DEBUG);
166                 sleep(1);
167             }
168         }
169         
170         //* remove udp ports
171         foreach($udp_ports_old_array as $port) {
172             if(!in_array($port,$udp_ports_new_array) && $port > 0) {
173                 exec('ufw delete allow '.$port.'/udp');
174                 $app->log('ufw delete allow '.$port.'/udp',LOGLEVEL_DEBUG);
175                 sleep(1);
176             }
177         }
178         
179         /*
180         if($tcp_ports_new != $tcp_ports_old) {
181             exec('ufw allow to any proto tcp port '.$tcp_ports_new);
182             $app->log('ufw allow to any proto tcp port '.$tcp_ports_new,LOGLEVEL_DEBUG);
183             if($event_name == 'firewall_update') {
184                 exec('ufw delete allow to any proto tcp port '.$tcp_ports_old);
185                 $app->log('ufw delete allow to any proto tcp port '.$tcp_ports_old,LOGLEVEL_DEBUG);
186             }
187         }
188         
189         if($udp_ports_new != $udp_ports_old) {
190             exec('ufw allow to any proto udp port '.$udp_ports_new);
191             $app->log('ufw allow to any proto udp port '.$udp_ports_new,LOGLEVEL_DEBUG);
192             if($event_name == 'firewall_update') {
193                 exec('ufw delete allow to any proto udp port '.$udp_ports_old);
194                 $app->log('ufw delete allow to any proto udp port '.$udp_ports_old,LOGLEVEL_DEBUG);
195             }
196         }
197         */
198         
199         if($data['new']['active'] == 'y') {
200             if($data['new']['active'] == $data['old']['active']) {
201                 exec('ufw reload');
202                 $app->log('Reloading the firewall',LOGLEVEL_DEBUG);
203             } else {
204                 //* Ensure that bastille firewall is stopped
526b99 205                 exec($conf['init_scripts'] . '/' . 'bastille-firewall stop 2>/dev/null');
42f191 206                 if(@is_file('/etc/debian_version')) exec('update-rc.d -f bastille-firewall remove');
T 207             
208                 //* Start ufw firewall
209                 exec('ufw --force enable');
210                 $app->log('Starting the firewall',LOGLEVEL_DEBUG);
211             }
212         } else {
213             exec('ufw disable');
214             $app->log('Stopping the firewall',LOGLEVEL_DEBUG);
215         }
216     }
217     
218     private function ufw_delete($event_name,$data) {
219         global $app, $conf;
220         
221         $app->uses('system');
222         
223         if(!$app->system->is_installed('ufw')) {
224             $app->log('UFW Firewall is not installed',LOGLEVEL_DEBUG);
225             return false;
226         }
227         
228         exec('ufw --force reset');
229         exec('ufw disable');
230         $app->log('Stopping the firewall',LOGLEVEL_DEBUG);
231         
232     }
233     
234     private function bastille_update($event_name,$data) {
235         global $app, $conf;
236         
237         $app->uses('system');
238         
239         $tcp_ports = $this->clean_ports($data['new']['tcp_port'],' ');
240         $udp_ports = $this->clean_ports($data['new']['udp_port'],' ');
7c99ef 241         
334a9f 242         $app->load('tpl');
7c99ef 243         $tpl = new tpl();
663caf 244         $tpl->newTemplate('bastille-firewall.cfg.master');
7c99ef 245         
663caf 246         $tpl->setVar('TCP_PUBLIC_SERVICES',$tcp_ports);
J 247         $tpl->setVar('UDP_PUBLIC_SERVICES',$udp_ports);
7c99ef 248         
T 249         file_put_contents('/etc/Bastille/bastille-firewall.cfg',$tpl->grab());
250         $app->log('Writing firewall configuration /etc/Bastille/bastille-firewall.cfg',LOGLEVEL_DEBUG);
251         unset($tpl);
252         
663caf 253         if($data['new']['active'] == 'y') {
42f191 254             //* ensure that ufw firewall is disabled in case both firewalls are installed
T 255             if($app->system->is_installed('ufw')) {
256                 exec('ufw disable');
257             }
526b99 258             exec($conf['init_scripts'] . '/' . 'bastille-firewall restart 2>/dev/null');
7c99ef 259             if(@is_file('/etc/debian_version')) exec('update-rc.d bastille-firewall defaults');
T 260             $app->log('Restarting the firewall',LOGLEVEL_DEBUG);
261         } else {
526b99 262             exec($conf['init_scripts'] . '/' . 'bastille-firewall stop 2>/dev/null');
a57e06 263             if(@is_file('/etc/debian_version')) exec('update-rc.d -f bastille-firewall remove');
7c99ef 264             $app->log('Stopping the firewall',LOGLEVEL_DEBUG);
T 265         }
266         
267         
268     }
269     
42f191 270     private function bastille_delete($event_name,$data) {
7c99ef 271         global $app, $conf;
T 272         
526b99 273         exec($conf['init_scripts'] . '/' . 'bastille-firewall stop 2>/dev/null');
a57e06 274         if(@is_file('/etc/debian_version')) exec('update-rc.d -f bastille-firewall remove');
7c99ef 275         $app->log('Stopping the firewall',LOGLEVEL_DEBUG);
T 276         
277     }
278     
279     
42f191 280     private function clean_ports($portlist,$spacer) {
T 281         
282         $ports = explode(',',$portlist);
283         $ports_out = '';
284         
285         if(is_array($ports)) {
286             foreach($ports as $p) {
287                 $p_clean = '';
288                 if(strstr($p,':')) {
289                     $p_parts = explode(':',$p);
290                     $tmp_lower = intval($p_parts[0]);
291                     $tmp_higher = intval($p_parts[1]);
292                     if($tmp_lower > 0 && $tmp_lower <= 65535 && $tmp_higher > 0 && $tmp_higher <= 65535 && $tmp_lower < $tmp_higher) {
293                         $p_clean = $tmp_lower.':'.$tmp_higher;
294                     }
295                 } else {
296                     $tmp = intval($p);
297                     if($tmp > 0 && $tmp <= 65535) {
298                         $p_clean = $tmp;
299                     }
300                 }
301                 if($p_clean != '') $ports_out .= $p_clean . $spacer;
302                 
303             }
304         }
305         return substr($ports_out,0,strlen($spacer)*-1);
306     }
307     
7c99ef 308     
T 309
310 } // end class
311
663caf 312 ?>