Skip to content

Commit b9b6e49

Browse files
committed
CP-308800: Add firewalld control function
Signed-off-by: Bengang Yuan <[email protected]>
1 parent 1fbdaae commit b9b6e49

File tree

3 files changed

+189
-10
lines changed

3 files changed

+189
-10
lines changed

ocaml/xapi/firewall.ml

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
(*
2+
* Copyright (c) Cloud Software Group, Inc.
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU Lesser General Public License as published
6+
* by the Free Software Foundation; version 2.1 only. with the special
7+
* exception on linking described in file LICENSE.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Lesser General Public License for more details.
13+
*)
14+
15+
module D = Debug.Make (struct let name = "firewall" end)
16+
17+
open D
18+
19+
type status = Enabled | Disabled
20+
21+
type service = Dlm | Nbd | Ssh | Vxlan | Http | Xenha
22+
23+
let service_type_to_string = function
24+
| Dlm ->
25+
"dlm"
26+
| Nbd ->
27+
"nbd"
28+
| Ssh ->
29+
"ssh"
30+
| Vxlan ->
31+
"vxlan"
32+
| Http ->
33+
"xapi-insecure"
34+
| Xenha ->
35+
"xenha"
36+
37+
let service_type_to_service_info = function
38+
| Dlm ->
39+
("dlm", !Xapi_globs.xapi_clusterd_port, "TCP")
40+
| Nbd ->
41+
("nbd", 10809, "TCP")
42+
| Ssh ->
43+
("ssh", 22, "TCP")
44+
| Vxlan ->
45+
("vxlan", 4789, "UDP")
46+
| Http ->
47+
("xapi-insecure", Constants.http_port, "TCP")
48+
| Xenha ->
49+
("xenha", Xapi_globs.xha_udp_port, "UDP")
50+
51+
module type FIREWALL = sig
52+
val update_firewall_status : service:service -> status:status -> unit
53+
54+
val is_firewall_service_enabled : service:service -> bool
55+
end
56+
57+
module Firewalld : FIREWALL = struct
58+
let update_firewall_status ~service ~status =
59+
if !Xapi_globs.dynamic_control_firewalld_service then
60+
try
61+
let service_option =
62+
match status with
63+
| Enabled ->
64+
"--add-service"
65+
| Disabled ->
66+
"--remove-service"
67+
in
68+
let service_name, _, _ = service_type_to_service_info service in
69+
Helpers.call_script !Xapi_globs.firewall_cmd
70+
[service_option; service_name]
71+
|> ignore
72+
with e ->
73+
error "Failed to update firewall service status: %s"
74+
(Printexc.to_string e)
75+
76+
let is_firewall_service_enabled ~service =
77+
let service_name, _, _ = service_type_to_service_info service in
78+
try
79+
let output =
80+
Helpers.call_script !Xapi_globs.firewall_cmd
81+
["--query-service"; service_name]
82+
|> String.trim
83+
|> String.lowercase_ascii
84+
in
85+
let status = Scanf.sscanf output "%s" Fun.id in
86+
match status with "yes" -> true | _ -> false
87+
with e ->
88+
error "Failed to check firewall service status: %s" (Printexc.to_string e) ;
89+
false
90+
end
91+
92+
module Iptables : FIREWALL = struct
93+
let update_firewall_status ~service ~status =
94+
let op = match status with Enabled -> "open" | Disabled -> "close" in
95+
let _, port, protocol = service_type_to_service_info service in
96+
ignore
97+
@@ Helpers.call_script
98+
!Xapi_globs.firewall_port_config_script
99+
[op; string_of_int port; protocol]
100+
101+
let is_firewall_service_enabled ~service =
102+
let _, port, protocol = service_type_to_service_info service in
103+
let script_output =
104+
Helpers.call_script
105+
!Xapi_globs.firewall_port_config_script
106+
["check"; string_of_int port; protocol]
107+
in
108+
try
109+
debug "firewall-port check result: %s" script_output ;
110+
let _, enabled =
111+
(* The firewall-port script returns true if port 80 is blocked and false
112+
if it is not. *)
113+
Scanf.sscanf script_output "Port %d open: %B" (fun port is_blocked ->
114+
(port, not is_blocked)
115+
)
116+
in
117+
enabled
118+
with _ ->
119+
Helpers.internal_error
120+
"unexpected output from /etc/xapi.d/plugins/firewall-port: %s"
121+
script_output
122+
end
123+
124+
let firewall_provider (backend : string) : (module FIREWALL) =
125+
match backend with
126+
| "firewalld" ->
127+
(module Firewalld)
128+
| "iptables" ->
129+
(module Iptables)
130+
| _ ->
131+
Helpers.internal_error "unknown firewall backend: %s" backend

ocaml/xapi/firewall.mli

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
(*
2+
* Copyright (c) Cloud Software Group, Inc.
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU Lesser General Public License as published
6+
* by the Free Software Foundation; version 2.1 only. with the special
7+
* exception on linking described in file LICENSE.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Lesser General Public License for more details.
13+
*)
14+
15+
type status = Enabled | Disabled
16+
17+
type service = Dlm | Nbd | Ssh | Vxlan | Http | Xenha
18+
19+
module type FIREWALL = sig
20+
val update_firewall_status : service:service -> status:status -> unit
21+
22+
val is_firewall_service_enabled : service:service -> bool
23+
end
24+
25+
module Firewalld : FIREWALL
26+
27+
module Iptables : FIREWALL
28+
29+
val firewall_provider : string -> (module FIREWALL)

ocaml/xapi/xapi_globs.ml

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,10 @@ let nbd_firewall_config_script =
861861

862862
let firewall_port_config_script = ref "/etc/xapi.d/plugins/firewall-port"
863863

864+
let firewall_cmd = ref "/usr/bin/firewall-cmd"
865+
866+
let firewall_cmd_wrapper = ref "/usr/bin/firewall-cmd-wrapper"
867+
864868
let nbd_client_manager_script =
865869
ref "/opt/xensource/libexec/nbd_client_manager.py"
866870

@@ -1317,6 +1321,12 @@ let ssh_monitor_service = ref "xapi-ssh-monitor"
13171321

13181322
let ssh_auto_mode_default = ref true
13191323

1324+
(* Firewall backend to use. iptables in XS 8, firewalld in XS 9. *)
1325+
let firewall_backend = ref "firewalld"
1326+
1327+
(* For firewalld, if dynamic control firewalld service. *)
1328+
let dynamic_control_firewalld_service = ref true
1329+
13201330
(* Fingerprint of default patch key *)
13211331
let citrix_patch_key =
13221332
"NERDNTUzMDMwRUMwNDFFNDI4N0M4OEVCRUFEMzlGOTJEOEE5REUyNg=="
@@ -1762,12 +1772,6 @@ let other_options =
17621772
, (fun () -> string_of_bool !validate_reusable_pool_session)
17631773
, "Enable validation of reusable pool sessions before use"
17641774
)
1765-
; ( "ssh-auto-mode"
1766-
, Arg.Bool (fun b -> ssh_auto_mode_default := b)
1767-
, (fun () -> string_of_bool !ssh_auto_mode_default)
1768-
, "Defaults to true; overridden to false via \
1769-
/etc/xapi.conf.d/ssh-auto-mode.conf(e.g., in XenServer 8)"
1770-
)
17711775
; ( "vm-sysprep-enabled"
17721776
, Arg.Set vm_sysprep_enabled
17731777
, (fun () -> string_of_bool !vm_sysprep_enabled)
@@ -1778,6 +1782,17 @@ let other_options =
17781782
, (fun () -> string_of_float !vm_sysprep_wait)
17791783
, "Time in seconds to wait for VM to recognise inserted CD"
17801784
)
1785+
; ( "firewall-backend"
1786+
, Arg.Set_string firewall_backend
1787+
, (fun () -> !firewall_backend)
1788+
, "Firewall backend. iptables (in XS 8) or firewalld (in XS 9 or later XS \
1789+
version)"
1790+
)
1791+
; ( "dynamic-control-firewalld-service"
1792+
, Arg.Bool (fun b -> dynamic_control_firewalld_service := b)
1793+
, (fun () -> string_of_bool !dynamic_control_firewalld_service)
1794+
, "Enable dynamic control firewalld service"
1795+
)
17811796
]
17821797

17831798
(* The options can be set with the variable xapiflags in /etc/sysconfig/xapi.
@@ -1912,10 +1927,14 @@ module Resources = struct
19121927
, "Executed after NBD-related networking changes to configure the \
19131928
firewall for NBD"
19141929
)
1915-
; ( "firewall-port-config"
1916-
, firewall_port_config_script
1917-
, "Executed when starting/stopping xapi-clusterd to configure firewall \
1918-
port"
1930+
; ( "firewall-cmd"
1931+
, firewall_cmd
1932+
, "Executed when enable/disable a service on a firewalld zone"
1933+
)
1934+
; ( "firewall-cmd-wrapper"
1935+
, firewall_cmd_wrapper
1936+
, "Executed when enable/disable a service on a firewalld zone and \
1937+
interface"
19191938
)
19201939
; ( "nbd_client_manager"
19211940
, nbd_client_manager_script

0 commit comments

Comments
 (0)