3030
3131class firewall_plugin {
3232
33- var $ plugin_name = 'firewall_plugin ' ;
34- var $ class_name = 'firewall_plugin ' ;
33+ private $ plugin_name = 'firewall_plugin ' ;
34+ private $ class_name = 'firewall_plugin ' ;
3535
3636 //* This function is called during ispconfig installation to determine
3737 // if a symlink shall be created for this plugin.
38- function onInstall () {
38+ public function onInstall () {
3939 global $ conf ;
4040
4141 if ($ conf ['bastille ' ]['installed ' ] = true && $ conf ['services ' ]['firewall ' ] == true ) {
@@ -51,7 +51,7 @@ function onInstall() {
5151 This function is called when the plugin is loaded
5252 */
5353
54- function onLoad () {
54+ public function onLoad () {
5555 global $ app ;
5656
5757 /*
@@ -62,51 +62,182 @@ function onLoad() {
6262 $ app ->plugins ->registerEvent ('firewall_insert ' ,$ this ->plugin_name ,'insert ' );
6363 $ app ->plugins ->registerEvent ('firewall_update ' ,$ this ->plugin_name ,'update ' );
6464 $ app ->plugins ->registerEvent ('firewall_delete ' ,$ this ->plugin_name ,'delete ' );
65+ }
66+
67+
68+ public function insert ($ event_name ,$ data ) {
69+ global $ app , $ conf ;
6570
71+ $ this ->update ($ event_name ,$ data );
6672
6773 }
6874
75+ public function update ($ event_name ,$ data ) {
76+ global $ app , $ conf ;
77+
78+ //* load the server configuration options
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+ }
86+
87+ }
6988
70- function insert ($ event_name ,$ data ) {
89+ public function delete ($ event_name ,$ data ) {
7190 global $ app , $ conf ;
7291
73- $ this ->update ($ event_name ,$ data );
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+ }
74101
75102 }
76103
77- function update ($ event_name ,$ data ) {
104+ private function ufw_update ($ event_name ,$ data ) {
78105 global $ app , $ conf ;
79106
80- $ tcp_ports = '' ;
81- $ udp_ports = '' ;
107+ $ app ->uses ('system ' );
82108
83- $ ports = explode (', ' ,$ data ['new ' ]['tcp_port ' ]);
84- if (is_array ($ ports )) {
85- foreach ($ ports as $ p ) {
86- if (strstr ($ p ,': ' )) {
87- $ p_parts = explode (': ' ,$ p );
88- $ p_clean = intval ($ p_parts [0 ]).': ' .intval ($ p_parts [1 ]);
89- } else {
90- $ p_clean = intval ($ p );
91- }
92- $ tcp_ports .= $ p_clean . ' ' ;
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 );
93149 }
94150 }
95- $ tcp_ports = trim ($ tcp_ports );
96151
97- $ ports = explode (', ' ,$ data ['new ' ]['udp_port ' ]);
98- if (is_array ($ ports )) {
99- foreach ($ ports as $ p ) {
100- if (strstr ($ p ,': ' )) {
101- $ p_parts = explode (': ' ,$ p );
102- $ p_clean = intval ($ p_parts [0 ]).': ' .intval ($ p_parts [1 ]);
103- } else {
104- $ p_clean = intval ($ p );
105- }
106- $ udp_ports .= $ p_clean . ' ' ;
152+ //* remove tcp ports
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 );
158+ }
159+ }
160+
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
205+ exec ($ conf ['init_scripts ' ] . '/ ' . 'bastille-firewall stop ' );
206+ if (@is_file ('/etc/debian_version ' )) exec ('update-rc.d -f bastille-firewall remove ' );
207+
208+ //* Start ufw firewall
209+ exec ('ufw --force enable ' );
210+ $ app ->log ('Starting the firewall ' ,LOGLEVEL_DEBUG );
107211 }
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 ;
108226 }
109- $ udp_ports = trim ($ udp_ports );
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 ' ],' ' );
110241
111242 $ app ->load ('tpl ' );
112243 $ tpl = new tpl ();
@@ -120,6 +251,10 @@ function update($event_name,$data) {
120251 unset($ tpl );
121252
122253 if ($ data ['new ' ]['active ' ] == 'y ' ) {
254+ //* ensure that ufw firewall is disabled in case both firewalls are installed
255+ if ($ app ->system ->is_installed ('ufw ' )) {
256+ exec ('ufw disable ' );
257+ }
123258 exec ($ conf ['init_scripts ' ] . '/ ' . 'bastille-firewall restart ' );
124259 if (@is_file ('/etc/debian_version ' )) exec ('update-rc.d bastille-firewall defaults ' );
125260 $ app ->log ('Restarting the firewall ' ,LOGLEVEL_DEBUG );
@@ -132,7 +267,7 @@ function update($event_name,$data) {
132267
133268 }
134269
135- function delete ($ event_name ,$ data ) {
270+ private function bastille_delete ($ event_name ,$ data ) {
136271 global $ app , $ conf ;
137272
138273 exec ($ conf ['init_scripts ' ] . '/ ' . 'bastille-firewall stop ' );
@@ -142,6 +277,34 @@ function delete($event_name,$data) {
142277 }
143278
144279
280+ private function clean_ports ($ portlist ,$ spacer ) {
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+
145308
146309
147310} // end class
0 commit comments