diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 206295bef0..15bfc711f5 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2192,6 +2192,7 @@ iptablesAddForwardRejectIn; iptablesAddForwardRejectOut; iptablesAddOutputFixUdpChecksum; iptablesAddTcpInput; +iptablesAddTcpOutput; iptablesAddUdpInput; iptablesAddUdpOutput; iptablesRemoveDontMasquerade; @@ -2204,6 +2205,7 @@ iptablesRemoveForwardRejectIn; iptablesRemoveForwardRejectOut; iptablesRemoveOutputFixUdpChecksum; iptablesRemoveTcpInput; +iptablesRemoveTcpOutput; iptablesRemoveUdpInput; iptablesRemoveUdpOutput; iptablesSetDeletePrivate; diff --git a/src/network/bridge_driver_linux.c b/src/network/bridge_driver_linux.c index d62fb899b9..9de8e93c60 100644 --- a/src/network/bridge_driver_linux.c +++ b/src/network/bridge_driver_linux.c @@ -553,18 +553,23 @@ networkAddGeneralIPv4FirewallRules(virFirewallPtr fw, break; } - /* allow DHCP requests through to dnsmasq */ + /* allow DHCP requests through to dnsmasq & back out */ iptablesAddTcpInput(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge, 67); iptablesAddUdpInput(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge, 67); + iptablesAddTcpOutput(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge, 68); iptablesAddUdpOutput(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge, 68); - /* allow DNS requests through to dnsmasq */ + /* allow DNS requests through to dnsmasq & back out */ iptablesAddTcpInput(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge, 53); iptablesAddUdpInput(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge, 53); + iptablesAddTcpOutput(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge, 53); + iptablesAddUdpOutput(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge, 53); - /* allow TFTP requests through to dnsmasq if necessary */ - if (ipv4def && ipv4def->tftproot) + /* allow TFTP requests through to dnsmasq if necessary & back out*/ + if (ipv4def && ipv4def->tftproot) { iptablesAddUdpInput(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge, 69); + iptablesAddUdpOutput(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge, 69); + } /* Catch all rules to block forwarding to/from bridges */ iptablesAddForwardRejectOut(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge); @@ -592,13 +597,18 @@ networkRemoveGeneralIPv4FirewallRules(virFirewallPtr fw, iptablesRemoveForwardRejectIn(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge); iptablesRemoveForwardRejectOut(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge); - if (ipv4def && ipv4def->tftproot) + if (ipv4def && ipv4def->tftproot) { iptablesRemoveUdpInput(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge, 69); + iptablesRemoveUdpOutput(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge, 69); + } iptablesRemoveUdpInput(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge, 53); iptablesRemoveTcpInput(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge, 53); + iptablesRemoveUdpOutput(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge, 53); + iptablesRemoveTcpOutput(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge, 53); iptablesRemoveUdpOutput(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge, 68); + iptablesRemoveTcpOutput(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge, 68); iptablesRemoveUdpInput(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge, 67); iptablesRemoveTcpInput(fw, VIR_FIREWALL_LAYER_IPV4, def->bridge, 67); } @@ -626,10 +636,14 @@ networkAddGeneralIPv6FirewallRules(virFirewallPtr fw, iptablesAddForwardAllowCross(fw, VIR_FIREWALL_LAYER_IPV6, def->bridge); if (virNetworkDefGetIPByIndex(def, AF_INET6, 0)) { - /* allow DNS over IPv6 */ + /* allow DNS over IPv6 & back out */ iptablesAddTcpInput(fw, VIR_FIREWALL_LAYER_IPV6, def->bridge, 53); iptablesAddUdpInput(fw, VIR_FIREWALL_LAYER_IPV6, def->bridge, 53); + iptablesAddTcpOutput(fw, VIR_FIREWALL_LAYER_IPV6, def->bridge, 53); + iptablesAddUdpOutput(fw, VIR_FIREWALL_LAYER_IPV6, def->bridge, 53); + /* allow DHCPv6 & back out */ iptablesAddUdpInput(fw, VIR_FIREWALL_LAYER_IPV6, def->bridge, 547); + iptablesAddUdpOutput(fw, VIR_FIREWALL_LAYER_IPV6, def->bridge, 546); } } @@ -643,7 +657,10 @@ networkRemoveGeneralIPv6FirewallRules(virFirewallPtr fw, } if (virNetworkDefGetIPByIndex(def, AF_INET6, 0)) { + iptablesRemoveUdpOutput(fw, VIR_FIREWALL_LAYER_IPV6, def->bridge, 546); iptablesRemoveUdpInput(fw, VIR_FIREWALL_LAYER_IPV6, def->bridge, 547); + iptablesRemoveUdpOutput(fw, VIR_FIREWALL_LAYER_IPV6, def->bridge, 53); + iptablesRemoveTcpOutput(fw, VIR_FIREWALL_LAYER_IPV6, def->bridge, 53); iptablesRemoveUdpInput(fw, VIR_FIREWALL_LAYER_IPV6, def->bridge, 53); iptablesRemoveTcpInput(fw, VIR_FIREWALL_LAYER_IPV6, def->bridge, 53); } diff --git a/src/util/viriptables.c b/src/util/viriptables.c index e240b97d72..e95aaa4773 100644 --- a/src/util/viriptables.c +++ b/src/util/viriptables.c @@ -303,6 +303,42 @@ iptablesRemoveUdpInput(virFirewallPtr fw, iptablesInput(fw, layer, deletePrivate, iface, port, REMOVE, 0); } +/** + * iptablesAddTcpOutput: + * @ctx: pointer to the IP table context + * @iface: the interface name + * @port: the TCP port to add + * + * Add an output to the IP table allowing access to the given @port from + * the given @iface interface for TCP packets + */ +void +iptablesAddTcpOutput(virFirewallPtr fw, + virFirewallLayer layer, + const char *iface, + int port) +{ + iptablesOutput(fw, layer, true, iface, port, ADD, 1); +} + +/** + * iptablesRemoveTcpOutput: + * @ctx: pointer to the IP table context + * @iface: the interface name + * @port: the UDP port to remove + * + * Removes an output from the IP table, hence forbidding access to the given + * @port from the given @iface interface for TCP packets + */ +void +iptablesRemoveTcpOutput(virFirewallPtr fw, + virFirewallLayer layer, + const char *iface, + int port) +{ + iptablesOutput(fw, layer, deletePrivate, iface, port, REMOVE, 1); +} + /** * iptablesAddUdpOutput: * @ctx: pointer to the IP table context diff --git a/src/util/viriptables.h b/src/util/viriptables.h index de26956178..c4c6595a2d 100644 --- a/src/util/viriptables.h +++ b/src/util/viriptables.h @@ -45,6 +45,14 @@ void iptablesRemoveUdpInput (virFirewallPtr fw, const char *iface, int port); +void iptablesAddTcpOutput (virFirewallPtr fw, + virFirewallLayer layer, + const char *iface, + int port); +void iptablesRemoveTcpOutput (virFirewallPtr fw, + virFirewallLayer layer, + const char *iface, + int port); void iptablesAddUdpOutput (virFirewallPtr fw, virFirewallLayer layer, const char *iface, diff --git a/tests/networkxml2firewalldata/nat-default-linux.args b/tests/networkxml2firewalldata/nat-default-linux.args index c9d523d043..ab18f30bd0 100644 --- a/tests/networkxml2firewalldata/nat-default-linux.args +++ b/tests/networkxml2firewalldata/nat-default-linux.args @@ -16,6 +16,13 @@ iptables \ --table filter \ --insert LIBVIRT_OUT \ --out-interface virbr0 \ +--protocol tcp \ +--destination-port 68 \ +--jump ACCEPT +iptables \ +--table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ --protocol udp \ --destination-port 68 \ --jump ACCEPT @@ -35,6 +42,20 @@ iptables \ --jump ACCEPT iptables \ --table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ +--protocol tcp \ +--destination-port 53 \ +--jump ACCEPT +iptables \ +--table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ +--protocol udp \ +--destination-port 53 \ +--jump ACCEPT +iptables \ +--table filter \ --insert LIBVIRT_FWO \ --in-interface virbr0 \ --jump REJECT diff --git a/tests/networkxml2firewalldata/nat-ipv6-linux.args b/tests/networkxml2firewalldata/nat-ipv6-linux.args index a57b9266af..05d9ee33ca 100644 --- a/tests/networkxml2firewalldata/nat-ipv6-linux.args +++ b/tests/networkxml2firewalldata/nat-ipv6-linux.args @@ -16,6 +16,13 @@ iptables \ --table filter \ --insert LIBVIRT_OUT \ --out-interface virbr0 \ +--protocol tcp \ +--destination-port 68 \ +--jump ACCEPT +iptables \ +--table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ --protocol udp \ --destination-port 68 \ --jump ACCEPT @@ -35,6 +42,20 @@ iptables \ --jump ACCEPT iptables \ --table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ +--protocol tcp \ +--destination-port 53 \ +--jump ACCEPT +iptables \ +--table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ +--protocol udp \ +--destination-port 53 \ +--jump ACCEPT +iptables \ +--table filter \ --insert LIBVIRT_FWO \ --in-interface virbr0 \ --jump REJECT @@ -81,11 +102,32 @@ ip6tables \ --jump ACCEPT ip6tables \ --table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ +--protocol tcp \ +--destination-port 53 \ +--jump ACCEPT +ip6tables \ +--table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ +--protocol udp \ +--destination-port 53 \ +--jump ACCEPT +ip6tables \ +--table filter \ --insert LIBVIRT_INP \ --in-interface virbr0 \ --protocol udp \ --destination-port 547 \ --jump ACCEPT +ip6tables \ +--table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ +--protocol udp \ +--destination-port 546 \ +--jump ACCEPT iptables \ --table filter \ --insert LIBVIRT_FWO \ diff --git a/tests/networkxml2firewalldata/nat-many-ips-linux.args b/tests/networkxml2firewalldata/nat-many-ips-linux.args index 1bdc43fd6a..82e1380f51 100644 --- a/tests/networkxml2firewalldata/nat-many-ips-linux.args +++ b/tests/networkxml2firewalldata/nat-many-ips-linux.args @@ -16,6 +16,13 @@ iptables \ --table filter \ --insert LIBVIRT_OUT \ --out-interface virbr0 \ +--protocol tcp \ +--destination-port 68 \ +--jump ACCEPT +iptables \ +--table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ --protocol udp \ --destination-port 68 \ --jump ACCEPT @@ -35,6 +42,20 @@ iptables \ --jump ACCEPT iptables \ --table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ +--protocol tcp \ +--destination-port 53 \ +--jump ACCEPT +iptables \ +--table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ +--protocol udp \ +--destination-port 53 \ +--jump ACCEPT +iptables \ +--table filter \ --insert LIBVIRT_FWO \ --in-interface virbr0 \ --jump REJECT diff --git a/tests/networkxml2firewalldata/nat-no-dhcp-linux.args b/tests/networkxml2firewalldata/nat-no-dhcp-linux.args index 7d359f3824..8954cc5473 100644 --- a/tests/networkxml2firewalldata/nat-no-dhcp-linux.args +++ b/tests/networkxml2firewalldata/nat-no-dhcp-linux.args @@ -16,6 +16,13 @@ iptables \ --table filter \ --insert LIBVIRT_OUT \ --out-interface virbr0 \ +--protocol tcp \ +--destination-port 68 \ +--jump ACCEPT +iptables \ +--table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ --protocol udp \ --destination-port 68 \ --jump ACCEPT @@ -35,6 +42,20 @@ iptables \ --jump ACCEPT iptables \ --table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ +--protocol tcp \ +--destination-port 53 \ +--jump ACCEPT +iptables \ +--table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ +--protocol udp \ +--destination-port 53 \ +--jump ACCEPT +iptables \ +--table filter \ --insert LIBVIRT_FWO \ --in-interface virbr0 \ --jump REJECT @@ -81,11 +102,32 @@ ip6tables \ --jump ACCEPT ip6tables \ --table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ +--protocol tcp \ +--destination-port 53 \ +--jump ACCEPT +ip6tables \ +--table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ +--protocol udp \ +--destination-port 53 \ +--jump ACCEPT +ip6tables \ +--table filter \ --insert LIBVIRT_INP \ --in-interface virbr0 \ --protocol udp \ --destination-port 547 \ --jump ACCEPT +ip6tables \ +--table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ +--protocol udp \ +--destination-port 546 \ +--jump ACCEPT iptables \ --table filter \ --insert LIBVIRT_FWO \ diff --git a/tests/networkxml2firewalldata/nat-tftp-linux.args b/tests/networkxml2firewalldata/nat-tftp-linux.args index b721801b70..88e9929b62 100644 --- a/tests/networkxml2firewalldata/nat-tftp-linux.args +++ b/tests/networkxml2firewalldata/nat-tftp-linux.args @@ -16,6 +16,13 @@ iptables \ --table filter \ --insert LIBVIRT_OUT \ --out-interface virbr0 \ +--protocol tcp \ +--destination-port 68 \ +--jump ACCEPT +iptables \ +--table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ --protocol udp \ --destination-port 68 \ --jump ACCEPT @@ -35,6 +42,20 @@ iptables \ --jump ACCEPT iptables \ --table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ +--protocol tcp \ +--destination-port 53 \ +--jump ACCEPT +iptables \ +--table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ +--protocol udp \ +--destination-port 53 \ +--jump ACCEPT +iptables \ +--table filter \ --insert LIBVIRT_INP \ --in-interface virbr0 \ --protocol udp \ @@ -42,6 +63,13 @@ iptables \ --jump ACCEPT iptables \ --table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ +--protocol udp \ +--destination-port 69 \ +--jump ACCEPT +iptables \ +--table filter \ --insert LIBVIRT_FWO \ --in-interface virbr0 \ --jump REJECT diff --git a/tests/networkxml2firewalldata/route-default-linux.args b/tests/networkxml2firewalldata/route-default-linux.args index ed3c560f74..c427d9602d 100644 --- a/tests/networkxml2firewalldata/route-default-linux.args +++ b/tests/networkxml2firewalldata/route-default-linux.args @@ -16,6 +16,13 @@ iptables \ --table filter \ --insert LIBVIRT_OUT \ --out-interface virbr0 \ +--protocol tcp \ +--destination-port 68 \ +--jump ACCEPT +iptables \ +--table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ --protocol udp \ --destination-port 68 \ --jump ACCEPT @@ -35,6 +42,20 @@ iptables \ --jump ACCEPT iptables \ --table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ +--protocol tcp \ +--destination-port 53 \ +--jump ACCEPT +iptables \ +--table filter \ +--insert LIBVIRT_OUT \ +--out-interface virbr0 \ +--protocol udp \ +--destination-port 53 \ +--jump ACCEPT +iptables \ +--table filter \ --insert LIBVIRT_FWO \ --in-interface virbr0 \ --jump REJECT