From fd5faa08cf82c7d5c53f95af08e07147cc40f232 Mon Sep 17 00:00:00 2001 From: Benjamin Reis Date: Mon, 4 Nov 2024 10:11:55 +0100 Subject: [PATCH 1/2] Adapt `firewall-port` to IPv6 Signed-off-by: Benjamin Reis --- scripts/plugins/firewall-port | 45 ++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/scripts/plugins/firewall-port b/scripts/plugins/firewall-port index b06707dbd28..0826d170b0d 100644 --- a/scripts/plugins/firewall-port +++ b/scripts/plugins/firewall-port @@ -9,10 +9,28 @@ set -e # protocol. # # Usage: -# ./firewall-port {open|close} port protocol +# ./firewall-port [-6] {open|close} port protocol # ################################################# +usage() { + echo $"Usage: $0 [-6] {open|close|check} {port} {protocol}" 1>&2 +} + +BINARY=iptables +while getopts ":6" option; do + case $option in + 6) + BINARY=ip6tables + ;; + *) + usage + exit 1 + ;; + esac + shift +done + OP="$1" PORT="$2" PROTOCOL="${3:-tcp}" @@ -29,26 +47,26 @@ esac case "${OP}" in open) - if ! iptables -C $CHAIN $RULE 2>/dev/null + if ! $BINARY -C $CHAIN $RULE 2>/dev/null then # first ensure chain exists - if iptables -N "${CHAIN}" 2>/dev/null + if $BINARY -N "${CHAIN}" 2>/dev/null then #chain did not exist but does now - iptables -A "${CHAIN}" -j RETURN - iptables -I INPUT -j "${CHAIN}" - fi # asuume chain is used if it exists - iptables -I "${CHAIN}" $RULE - /usr/libexec/iptables/iptables.init save + $BINARY -A "${CHAIN}" -j RETURN + $BINARY -I INPUT -j "${CHAIN}" + fi # assume chain is used if it exists + $BINARY -I "${CHAIN}" $RULE + /usr/libexec/iptables/"$BINARY".init save fi ;; close) - if iptables -C $CHAIN $RULE 2>/dev/null + if $BINARY -C $CHAIN $RULE 2>/dev/null then # close port if it was opened - iptables -D $CHAIN $RULE - /usr/libexec/iptables/iptables.init save + $BINARY -D $CHAIN $RULE + /usr/libexec/iptables/"$BINARY".init save fi ;; check) - if [[ -z `iptables -S $CHAIN | grep " $PORT "` ]] + if [[ -z `$BINARY -S $CHAIN | grep " $PORT "` ]] then echo "Port $PORT open: true" else @@ -56,10 +74,9 @@ case "${OP}" in fi ;; *) - echo $"Usage: $0 {open|close|check} {port} {protocol}" 1>&2 + usage exit 1 ;; esac exit 0 - From cc4c324a8411cd7060f23967aebc947a8bde595d Mon Sep 17 00:00:00 2001 From: Benjamin Reis Date: Tue, 5 Nov 2024 09:30:18 +0100 Subject: [PATCH 2/2] Call `firewall-port` in IPv6 when management is in IPv6 Signed-off-by: Benjamin Reis --- ocaml/xapi/dbsync_slave.ml | 9 ++++++++- ocaml/xapi/helpers.ml | 4 ++++ ocaml/xapi/nm.ml | 18 ++++++++++++++++-- ocaml/xapi/xapi_clustering.ml | 20 ++++++++++++++++---- ocaml/xapi/xapi_host.ml | 11 ++++++++--- 5 files changed, 52 insertions(+), 10 deletions(-) diff --git a/ocaml/xapi/dbsync_slave.ml b/ocaml/xapi/dbsync_slave.ml index 942d3081071..8a35f392275 100644 --- a/ocaml/xapi/dbsync_slave.ml +++ b/ocaml/xapi/dbsync_slave.ml @@ -126,8 +126,15 @@ let refresh_localhost_info ~__context info = ) else Db.Host.remove_from_other_config ~__context ~self:host ~key:Xapi_globs.host_no_local_storage ; + let options = + match Helpers.get_management_iface_primary_address_type with + | `IPv4 -> + ["check"; "80"] + | `IPv6 -> + ["-6"; "check"; "80"] + in let script_output = - Helpers.call_script !Xapi_globs.firewall_port_config_script ["check"; "80"] + Helpers.call_script !Xapi_globs.firewall_port_config_script options in try let network_state = Scanf.sscanf script_output "Port 80 open: %B" Fun.id in diff --git a/ocaml/xapi/helpers.ml b/ocaml/xapi/helpers.ml index 30965068f3f..68aa1277ef6 100644 --- a/ocaml/xapi/helpers.ml +++ b/ocaml/xapi/helpers.ml @@ -165,6 +165,10 @@ let get_localhost ~__context = | true -> get_localhost_uncached ~__context +let get_management_iface_primary_address_type = + Record_util.primary_address_type_of_string + (Xapi_inventory.lookup Xapi_inventory._management_address_type) + (* Determine the gateway and DNS PIFs: * If one of the PIFs with IP has other_config:defaultroute=true, then * pick this one as gateway PIF. If there are multiple, pick a random one of these. diff --git a/ocaml/xapi/nm.ml b/ocaml/xapi/nm.ml index 1483106ace5..9819c1b168c 100644 --- a/ocaml/xapi/nm.ml +++ b/ocaml/xapi/nm.ml @@ -796,10 +796,17 @@ let bring_pif_up ~__context ?(management_interface = false) (pif : API.ref_PIF) | `vxlan -> debug "Opening VxLAN UDP port for tunnel with protocol 'vxlan'" ; + let options = + match Helpers.get_management_iface_primary_address_type with + | `IPv4 -> + ["open"; "4789"; "udp"] + | `IPv6 -> + ["-6"; "open"; "4789"; "udp"] + in ignore @@ Helpers.call_script !Xapi_globs.firewall_port_config_script - ["open"; "4789"; "udp"] + options | `gre -> () ) @@ -857,10 +864,17 @@ let bring_pif_down ~__context ?(force = false) (pif : API.ref_PIF) = in if no_more_vxlan then ( debug "Last VxLAN tunnel was closed, closing VxLAN UDP port" ; + let options = + match Helpers.get_management_iface_primary_address_type with + | `IPv4 -> + ["close"; "4789"; "udp"] + | `IPv6 -> + ["-6"; "close"; "4789"; "udp"] + in ignore @@ Helpers.call_script !Xapi_globs.firewall_port_config_script - ["close"; "4789"; "udp"] + options ) | `gre -> () diff --git a/ocaml/xapi/xapi_clustering.ml b/ocaml/xapi/xapi_clustering.ml index d2b61be2f55..cf822645fca 100644 --- a/ocaml/xapi/xapi_clustering.ml +++ b/ocaml/xapi/xapi_clustering.ml @@ -274,9 +274,16 @@ module Daemon = struct raise Api_errors.(Server_error (not_implemented, ["Cluster.create"])) ) ; ( try + let options = + match Helpers.get_management_iface_primary_address_type with + | `IPv4 -> + ["open"; port] + | `IPv6 -> + ["-6"; "open"; port] + in maybe_call_script ~__context !Xapi_globs.firewall_port_config_script - ["open"; port] ; + options ; maybe_call_script ~__context !Xapi_globs.systemctl ["enable"; service] ; maybe_call_script ~__context !Xapi_globs.systemctl ["start"; service] with _ -> @@ -295,9 +302,14 @@ module Daemon = struct Atomic.set enabled false ; maybe_call_script ~__context !Xapi_globs.systemctl ["disable"; service] ; maybe_call_script ~__context !Xapi_globs.systemctl ["stop"; service] ; - maybe_call_script ~__context - !Xapi_globs.firewall_port_config_script - ["close"; port] ; + let options = + match Helpers.get_management_iface_primary_address_type with + | `IPv4 -> + ["close"; port] + | `IPv6 -> + ["-6"; "close"; port] + in + maybe_call_script ~__context !Xapi_globs.firewall_port_config_script options ; debug "Cluster daemon: disabled & stopped" let restart ~__context = diff --git a/ocaml/xapi/xapi_host.ml b/ocaml/xapi/xapi_host.ml index 7958a15a367..d33f5d996d7 100644 --- a/ocaml/xapi/xapi_host.ml +++ b/ocaml/xapi/xapi_host.ml @@ -3045,10 +3045,15 @@ let set_https_only ~__context ~self ~value = let state = match value with true -> "close" | false -> "open" in match cc_prep () with | false -> + let options = + match Helpers.get_management_iface_primary_address_type with + | `IPv4 -> + [state; "80"] + | `IPv6 -> + ["-6"; state; "80"] + in ignore - @@ Helpers.call_script - !Xapi_globs.firewall_port_config_script - [state; "80"] ; + @@ Helpers.call_script !Xapi_globs.firewall_port_config_script options ; Db.Host.set_https_only ~__context ~self ~value | true when value = Db.Host.get_https_only ~__context ~self -> (* the new value is the same as the old value *)