network: allow DHCP/DNS/TFTP explicitly in OUTPUT rules

While the default iptables setup used by Fedora/RHEL distros
only restricts traffic on the INPUT and/or FORWARD rules,
some users might have custom firewalls that restrict the
OUTPUT rules too.

These can prevent DHCP/DNS/TFTP responses from dnsmasq
from reaching the guest VMs. We should thus whitelist
these protocols in the OUTPUT chain, as well as the
INPUT chain.

Signed-off-by: Malina Salina <malina.salina@protonmail.com>

Initial patch then modified to add unit tests and IPv6
support

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Malina Salina 2019-09-27 17:10:34 +01:00 committed by Daniel P. Berrangé
parent 80f45e65c0
commit 313a71ee7b
10 changed files with 244 additions and 6 deletions

View File

@ -2192,6 +2192,7 @@ iptablesAddForwardRejectIn;
iptablesAddForwardRejectOut;
iptablesAddOutputFixUdpChecksum;
iptablesAddTcpInput;
iptablesAddTcpOutput;
iptablesAddUdpInput;
iptablesAddUdpOutput;
iptablesRemoveDontMasquerade;
@ -2204,6 +2205,7 @@ iptablesRemoveForwardRejectIn;
iptablesRemoveForwardRejectOut;
iptablesRemoveOutputFixUdpChecksum;
iptablesRemoveTcpInput;
iptablesRemoveTcpOutput;
iptablesRemoveUdpInput;
iptablesRemoveUdpOutput;
iptablesSetDeletePrivate;

View File

@ -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);
}

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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 \

View File

@ -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

View File

@ -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 \

View File

@ -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

View File

@ -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