libvirt/src/util/viriptables.h

153 lines
8.3 KiB
C
Raw Normal View History

/*
* viriptables.h: helper APIs for managing iptables
*
* Copyright (C) 2007, 2008 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef LIBVIRT_VIRIPTABLES_H
# define LIBVIRT_VIRIPTABLES_H
# include "virsocketaddr.h"
# include "virfirewall.h"
int iptablesSetupPrivateChains (virFirewallLayer layer);
util: create private chains for virtual network firewall rules Historically firewall rules for virtual networks were added straight into the base chains. This works but has a number of bugs and design limitations: - It is inflexible for admins wanting to add extra rules ahead of libvirt's rules, via hook scripts. - It is not clear to the admin that the rules were created by libvirt - Each rule must be deleted by libvirt individually since they are all directly in the builtin chains - The ordering of rules in the forward chain is incorrect when multiple networks are created, allowing traffic to mistakenly flow between networks in one direction. To address all of these problems, libvirt needs to move to creating rules in its own private chains. In the top level builtin chains, libvirt will add links to its own private top level chains. Addressing the traffic ordering bug requires some extra steps. With everything going into the FORWARD chain there was interleaving of rules for outbound traffic and inbound traffic for each network: -A FORWARD -d 192.168.3.0/24 -o virbr1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A FORWARD -s 192.168.3.0/24 -i virbr1 -j ACCEPT -A FORWARD -i virbr1 -o virbr1 -j ACCEPT -A FORWARD -o virbr1 -j REJECT --reject-with icmp-port-unreachable -A FORWARD -i virbr1 -j REJECT --reject-with icmp-port-unreachable -A FORWARD -d 192.168.2.0/24 -o virbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A FORWARD -s 192.168.2.0/24 -i virbr0 -j ACCEPT -A FORWARD -i virbr0 -o virbr0 -j ACCEPT -A FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable -A FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable The rule allowing outbound traffic from virbr1 would mistakenly allow packets from virbr1 to virbr0, before the rule denying input to virbr0 gets a chance to run. What we really need todo is group the forwarding rules into three distinct sets: * Cross rules - LIBVIRT_FWX -A FORWARD -i virbr1 -o virbr1 -j ACCEPT -A FORWARD -i virbr0 -o virbr0 -j ACCEPT * Incoming rules - LIBVIRT_FWI -A FORWARD -d 192.168.3.0/24 -o virbr1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A FORWARD -o virbr1 -j REJECT --reject-with icmp-port-unreachable -A FORWARD -d 192.168.2.0/24 -o virbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable * Outgoing rules - LIBVIRT_FWO -A FORWARD -s 192.168.3.0/24 -i virbr1 -j ACCEPT -A FORWARD -i virbr1 -j REJECT --reject-with icmp-port-unreachable -A FORWARD -s 192.168.2.0/24 -i virbr0 -j ACCEPT -A FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable There is thus no risk of outgoing rules for one network mistakenly allowing incoming traffic for another network, as all incoming rules are evalated first. With this in mind, we'll thus need three distinct chains linked from the FORWARD chain, so we end up with: INPUT --> LIBVIRT_INP (filter) OUTPUT --> LIBVIRT_OUT (filter) FORWARD +-> LIBVIRT_FWX (filter) +-> LIBVIRT_FWO \-> LIBVIRT_FWI POSTROUTING --> LIBVIRT_PRT (nat & mangle) Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-10-31 19:33:21 +00:00
util: move virtual network firwall rules into private chains The previous commit created new chains to hold the firewall rules. This commit changes the code that creates rules to place them in the new private chains instead of the builtin top level chains. With two networks running, the rules in the filter table now look like -N LIBVIRT_FWI -N LIBVIRT_FWO -N LIBVIRT_FWX -N LIBVIRT_INP -N LIBVIRT_OUT -A INPUT -j LIBVIRT_INP -A FORWARD -j LIBVIRT_FWX -A FORWARD -j LIBVIRT_FWI -A FORWARD -j LIBVIRT_FWO -A OUTPUT -j LIBVIRT_OUT -A LIBVIRT_FWI -d 192.168.0.0/24 -o virbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A LIBVIRT_FWI -o virbr0 -j REJECT --reject-with icmp-port-unreachable -A LIBVIRT_FWI -d 192.168.1.0/24 -o virbr1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A LIBVIRT_FWI -o virbr1 -j REJECT --reject-with icmp-port-unreachable -A LIBVIRT_FWO -s 192.168.0.0/24 -i virbr0 -j ACCEPT -A LIBVIRT_FWO -i virbr0 -j REJECT --reject-with icmp-port-unreachable -A LIBVIRT_FWO -s 192.168.1.0/24 -i virbr1 -j ACCEPT -A LIBVIRT_FWO -i virbr1 -j REJECT --reject-with icmp-port-unreachable -A LIBVIRT_FWX -i virbr0 -o virbr0 -j ACCEPT -A LIBVIRT_FWX -i virbr1 -o virbr1 -j ACCEPT -A LIBVIRT_INP -i virbr0 -p udp -m udp --dport 53 -j ACCEPT -A LIBVIRT_INP -i virbr0 -p tcp -m tcp --dport 53 -j ACCEPT -A LIBVIRT_INP -i virbr0 -p udp -m udp --dport 67 -j ACCEPT -A LIBVIRT_INP -i virbr0 -p tcp -m tcp --dport 67 -j ACCEPT -A LIBVIRT_INP -i virbr1 -p udp -m udp --dport 53 -j ACCEPT -A LIBVIRT_INP -i virbr1 -p tcp -m tcp --dport 53 -j ACCEPT -A LIBVIRT_INP -i virbr1 -p udp -m udp --dport 67 -j ACCEPT -A LIBVIRT_INP -i virbr1 -p tcp -m tcp --dport 67 -j ACCEPT -A LIBVIRT_OUT -o virbr0 -p udp -m udp --dport 68 -j ACCEPT -A LIBVIRT_OUT -o virbr1 -p udp -m udp --dport 68 -j ACCEPT While in the nat table: -N LIBVIRT_PRT -A POSTROUTING -j LIBVIRT_PRT -A LIBVIRT_PRT -s 192.168.0.0/24 -d 224.0.0.0/24 -j RETURN -A LIBVIRT_PRT -s 192.168.0.0/24 -d 255.255.255.255/32 -j RETURN -A LIBVIRT_PRT -s 192.168.0.0/24 ! -d 192.168.0.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535 -A LIBVIRT_PRT -s 192.168.0.0/24 ! -d 192.168.0.0/24 -p udp -j MASQUERADE --to-ports 1024-65535 -A LIBVIRT_PRT -s 192.168.0.0/24 ! -d 192.168.0.0/24 -j MASQUERADE -A LIBVIRT_PRT -s 192.168.1.0/24 -d 224.0.0.0/24 -j RETURN -A LIBVIRT_PRT -s 192.168.1.0/24 -d 255.255.255.255/32 -j RETURN -A LIBVIRT_PRT -s 192.168.1.0/24 ! -d 192.168.1.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535 -A LIBVIRT_PRT -s 192.168.1.0/24 ! -d 192.168.1.0/24 -p udp -j MASQUERADE --to-ports 1024-65535 -A LIBVIRT_PRT -s 192.168.1.0/24 ! -d 192.168.1.0/24 -j MASQUERADE And finally the mangle table: -N LIBVIRT_PRT -A POSTROUTING -j LIBVIRT_PRT -A LIBVIRT_PRT -o virbr0 -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill -A LIBVIRT_PRT -o virbr1 -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-12-05 15:53:55 +00:00
void iptablesSetDeletePrivate (bool pvt);
void iptablesAddTcpInput (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface,
int port);
void iptablesRemoveTcpInput (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface,
int port);
void iptablesAddUdpInput (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface,
int port);
void iptablesRemoveUdpInput (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface,
int port);
void iptablesAddUdpOutput (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface,
int port);
void iptablesRemoveUdpOutput (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface,
int port);
int iptablesAddForwardAllowOut (virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix,
2007-03-13 22:43:22 +00:00
const char *iface,
const char *physdev)
ATTRIBUTE_RETURN_CHECK;
int iptablesRemoveForwardAllowOut (virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix,
2007-03-13 22:43:22 +00:00
const char *iface,
const char *physdev)
ATTRIBUTE_RETURN_CHECK;
int iptablesAddForwardAllowRelatedIn(virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix,
const char *iface,
const char *physdev)
ATTRIBUTE_RETURN_CHECK;
int iptablesRemoveForwardAllowRelatedIn(virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix,
const char *iface,
const char *physdev)
ATTRIBUTE_RETURN_CHECK;
int iptablesAddForwardAllowIn (virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix,
2007-03-13 22:43:22 +00:00
const char *iface,
const char *physdev)
ATTRIBUTE_RETURN_CHECK;
int iptablesRemoveForwardAllowIn (virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix,
2007-03-13 22:43:22 +00:00
const char *iface,
const char *physdev)
ATTRIBUTE_RETURN_CHECK;
void iptablesAddForwardAllowCross (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface);
void iptablesRemoveForwardAllowCross (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface);
void iptablesAddForwardRejectOut (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface);
void iptablesRemoveForwardRejectOut (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface);
void iptablesAddForwardRejectIn (virFirewallPtr fw,
virFirewallLayer layer,
const char *iface);
void iptablesRemoveForwardRejectIn (virFirewallPtr fw,
virFirewallLayer layery,
const char *iface);
int iptablesAddForwardMasquerade (virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix,
const char *physdev,
virSocketAddrRangePtr addr,
virPortRangePtr port,
const char *protocol)
ATTRIBUTE_RETURN_CHECK;
int iptablesRemoveForwardMasquerade (virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix,
const char *physdev,
virSocketAddrRangePtr addr,
virPortRangePtr port,
const char *protocol)
ATTRIBUTE_RETURN_CHECK;
int iptablesAddDontMasquerade (virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix,
const char *physdev,
const char *destaddr)
ATTRIBUTE_RETURN_CHECK;
int iptablesRemoveDontMasquerade (virFirewallPtr fw,
virSocketAddr *netaddr,
unsigned int prefix,
const char *physdev,
const char *destaddr)
ATTRIBUTE_RETURN_CHECK;
void iptablesAddOutputFixUdpChecksum (virFirewallPtr fw,
const char *iface,
int port);
void iptablesRemoveOutputFixUdpChecksum (virFirewallPtr fw,
const char *iface,
int port);
#endif /* LIBVIRT_VIRIPTABLES_H */