Merge "Add support for unaddressed port"
This commit is contained in:
commit
1f2e04b06e
@ -50,6 +50,13 @@ MAX_CONNTRACK_ZONES = 65535
|
|||||||
comment_rule = iptables_manager.comment_rule
|
comment_rule = iptables_manager.comment_rule
|
||||||
|
|
||||||
|
|
||||||
|
def port_needs_l3_security(port):
|
||||||
|
if port['fixed_ips'] or port.get('allowed_address_pairs'):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class IptablesFirewallDriver(firewall.FirewallDriver):
|
class IptablesFirewallDriver(firewall.FirewallDriver):
|
||||||
"""Driver which enforces security groups through iptables rules."""
|
"""Driver which enforces security groups through iptables rules."""
|
||||||
IPTABLES_DIRECTION = {firewall.INGRESS_DIRECTION: 'physdev-out',
|
IPTABLES_DIRECTION = {firewall.INGRESS_DIRECTION: 'physdev-out',
|
||||||
@ -374,17 +381,20 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
|
|||||||
mac_ipv6_pairs.append((mac, ip_address))
|
mac_ipv6_pairs.append((mac, ip_address))
|
||||||
|
|
||||||
def _spoofing_rule(self, port, ipv4_rules, ipv6_rules):
|
def _spoofing_rule(self, port, ipv4_rules, ipv6_rules):
|
||||||
# Allow dhcp client packets
|
if port_needs_l3_security(port):
|
||||||
ipv4_rules += [comment_rule('-p udp -m udp --sport 68 --dport 67 '
|
# Allow dhcp client packets
|
||||||
'-j RETURN', comment=ic.DHCP_CLIENT)]
|
ipv4_rules += [comment_rule('-p udp -m udp --sport 68 --dport 67 '
|
||||||
# Drop Router Advts from the port.
|
'-j RETURN', comment=ic.DHCP_CLIENT)]
|
||||||
ipv6_rules += [comment_rule('-p icmpv6 --icmpv6-type %s '
|
# Drop Router Advts from the port.
|
||||||
'-j DROP' % constants.ICMPV6_TYPE_RA,
|
ipv6_rules += [comment_rule('-p icmpv6 --icmpv6-type %s '
|
||||||
comment=ic.IPV6_RA_DROP)]
|
'-j DROP' % constants.ICMPV6_TYPE_RA,
|
||||||
ipv6_rules += [comment_rule('-p icmpv6 -j RETURN',
|
comment=ic.IPV6_RA_DROP)]
|
||||||
comment=ic.IPV6_ICMP_ALLOW)]
|
ipv6_rules += [comment_rule('-p icmpv6 -j RETURN',
|
||||||
ipv6_rules += [comment_rule('-p udp -m udp --sport 546 --dport 547 '
|
comment=ic.IPV6_ICMP_ALLOW)]
|
||||||
'-j RETURN', comment=ic.DHCP_CLIENT)]
|
ipv6_rules += [comment_rule('-p udp -m udp --sport 546 --dport '
|
||||||
|
'547 -j RETURN',
|
||||||
|
comment=ic.DHCP_CLIENT)]
|
||||||
|
|
||||||
mac_ipv4_pairs = []
|
mac_ipv4_pairs = []
|
||||||
mac_ipv6_pairs = []
|
mac_ipv6_pairs = []
|
||||||
|
|
||||||
@ -490,11 +500,14 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
|
|||||||
ipv6_iptables_rules)
|
ipv6_iptables_rules)
|
||||||
elif direction == firewall.INGRESS_DIRECTION:
|
elif direction == firewall.INGRESS_DIRECTION:
|
||||||
ipv6_iptables_rules += self._accept_inbound_icmpv6()
|
ipv6_iptables_rules += self._accept_inbound_icmpv6()
|
||||||
# include IPv4 and IPv6 iptable rules from security group
|
|
||||||
ipv4_iptables_rules += self._convert_sgr_to_iptables_rules(
|
if port_needs_l3_security(port):
|
||||||
ipv4_sg_rules)
|
# include IPv4 and IPv6 iptable rules from security group
|
||||||
ipv6_iptables_rules += self._convert_sgr_to_iptables_rules(
|
ipv4_iptables_rules += self._convert_sgr_to_iptables_rules(
|
||||||
ipv6_sg_rules)
|
ipv4_sg_rules)
|
||||||
|
ipv6_iptables_rules += self._convert_sgr_to_iptables_rules(
|
||||||
|
ipv6_sg_rules)
|
||||||
|
|
||||||
# finally add the rules to the port chain for a given direction
|
# finally add the rules to the port chain for a given direction
|
||||||
self._add_rules_to_chain_v4v6(self._port_chain_name(port, direction),
|
self._add_rules_to_chain_v4v6(self._port_chain_name(port, direction),
|
||||||
ipv4_iptables_rules,
|
ipv4_iptables_rules,
|
||||||
@ -505,7 +518,8 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
|
|||||||
self._spoofing_rule(port,
|
self._spoofing_rule(port,
|
||||||
ipv4_iptables_rules,
|
ipv4_iptables_rules,
|
||||||
ipv6_iptables_rules)
|
ipv6_iptables_rules)
|
||||||
self._drop_dhcp_rule(ipv4_iptables_rules, ipv6_iptables_rules)
|
if port_needs_l3_security(port):
|
||||||
|
self._drop_dhcp_rule(ipv4_iptables_rules, ipv6_iptables_rules)
|
||||||
|
|
||||||
def _update_ipset_members(self, security_group_ids):
|
def _update_ipset_members(self, security_group_ids):
|
||||||
for ip_version, sg_ids in security_group_ids.items():
|
for ip_version, sg_ids in security_group_ids.items():
|
||||||
|
@ -33,6 +33,7 @@ from neutron.agent.common import polling
|
|||||||
from neutron.agent.common import utils
|
from neutron.agent.common import utils
|
||||||
from neutron.agent.l2.extensions import manager as ext_manager
|
from neutron.agent.l2.extensions import manager as ext_manager
|
||||||
from neutron.agent.linux import ip_lib
|
from neutron.agent.linux import ip_lib
|
||||||
|
from neutron.agent.linux.iptables_firewall import port_needs_l3_security
|
||||||
from neutron.agent import rpc as agent_rpc
|
from neutron.agent import rpc as agent_rpc
|
||||||
from neutron.agent import securitygroups_rpc as sg_rpc
|
from neutron.agent import securitygroups_rpc as sg_rpc
|
||||||
from neutron.api.rpc.handlers import dvr_rpc
|
from neutron.api.rpc.handlers import dvr_rpc
|
||||||
@ -828,6 +829,9 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
|
|||||||
addresses |= {p['ip_address']
|
addresses |= {p['ip_address']
|
||||||
for p in port_details['allowed_address_pairs']}
|
for p in port_details['allowed_address_pairs']}
|
||||||
|
|
||||||
|
if not port_needs_l3_security(port_details):
|
||||||
|
return
|
||||||
|
|
||||||
addresses = {ip for ip in addresses
|
addresses = {ip for ip in addresses
|
||||||
if netaddr.IPNetwork(ip).version == 4}
|
if netaddr.IPNetwork(ip).version == 4}
|
||||||
if any(netaddr.IPNetwork(ip).prefixlen == 0 for ip in addresses):
|
if any(netaddr.IPNetwork(ip).prefixlen == 0 for ip in addresses):
|
||||||
|
@ -1475,15 +1475,6 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
|
|||||||
'--physdev-is-bridged '
|
'--physdev-is-bridged '
|
||||||
'-j $ifake_dev',
|
'-j $ifake_dev',
|
||||||
comment=ic.SG_TO_VM_SG),
|
comment=ic.SG_TO_VM_SG),
|
||||||
mock.call.add_rule(
|
|
||||||
'ifake_dev',
|
|
||||||
'-m state --state INVALID -j DROP', comment=None),
|
|
||||||
mock.call.add_rule(
|
|
||||||
'ifake_dev',
|
|
||||||
'-m state --state RELATED,ESTABLISHED -j RETURN',
|
|
||||||
comment=None),
|
|
||||||
mock.call.add_rule('ifake_dev', '-j $sg-fallback',
|
|
||||||
comment=None),
|
|
||||||
mock.call.add_chain('ofake_dev'),
|
mock.call.add_chain('ofake_dev'),
|
||||||
mock.call.add_rule('FORWARD',
|
mock.call.add_rule('FORWARD',
|
||||||
'-m physdev --physdev-in tapfake_dev '
|
'-m physdev --physdev-in tapfake_dev '
|
||||||
@ -1505,26 +1496,8 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
|
|||||||
mock.call.add_rule(
|
mock.call.add_rule(
|
||||||
'sfake_dev', '-j DROP',
|
'sfake_dev', '-j DROP',
|
||||||
comment=ic.PAIR_DROP),
|
comment=ic.PAIR_DROP),
|
||||||
mock.call.add_rule(
|
|
||||||
'ofake_dev',
|
|
||||||
'-p udp -m udp --sport 68 --dport 67 -j RETURN',
|
|
||||||
comment=None),
|
|
||||||
mock.call.add_rule('ofake_dev', '-j $sfake_dev',
|
mock.call.add_rule('ofake_dev', '-j $sfake_dev',
|
||||||
comment=None),
|
comment=None),
|
||||||
mock.call.add_rule(
|
|
||||||
'ofake_dev',
|
|
||||||
'-p udp -m udp --sport 67 --dport 68 -j DROP',
|
|
||||||
comment=None),
|
|
||||||
mock.call.add_rule(
|
|
||||||
'ofake_dev',
|
|
||||||
'-m state --state INVALID -j DROP',
|
|
||||||
comment=None),
|
|
||||||
mock.call.add_rule(
|
|
||||||
'ofake_dev',
|
|
||||||
'-m state --state RELATED,ESTABLISHED -j RETURN',
|
|
||||||
comment=None),
|
|
||||||
mock.call.add_rule('ofake_dev', '-j $sg-fallback',
|
|
||||||
comment=None),
|
|
||||||
mock.call.add_rule('sg-chain', '-j ACCEPT')]
|
mock.call.add_rule('sg-chain', '-j ACCEPT')]
|
||||||
self.v4filter_inst.assert_has_calls(calls)
|
self.v4filter_inst.assert_has_calls(calls)
|
||||||
|
|
||||||
|
@ -1289,7 +1289,7 @@ class TestOvsNeutronAgent(object):
|
|||||||
self.assertTrue(int_br.delete_arp_spoofing_protection.called)
|
self.assertTrue(int_br.delete_arp_spoofing_protection.called)
|
||||||
self.assertFalse(int_br.install_arp_spoofing_protection.called)
|
self.assertFalse(int_br.install_arp_spoofing_protection.called)
|
||||||
|
|
||||||
def test_arp_spoofing_basic_rule_setup(self):
|
def test_arp_spoofing_basic_rule_setup_without_ip(self):
|
||||||
vif = FakeVif()
|
vif = FakeVif()
|
||||||
fake_details = {'fixed_ips': []}
|
fake_details = {'fixed_ips': []}
|
||||||
self.agent.prevent_arp_spoofing = True
|
self.agent.prevent_arp_spoofing = True
|
||||||
@ -1298,9 +1298,18 @@ class TestOvsNeutronAgent(object):
|
|||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
[mock.call(port=vif.ofport)],
|
[mock.call(port=vif.ofport)],
|
||||||
int_br.delete_arp_spoofing_protection.mock_calls)
|
int_br.delete_arp_spoofing_protection.mock_calls)
|
||||||
|
self.assertFalse(int_br.install_arp_spoofing_protection.called)
|
||||||
|
|
||||||
|
def test_arp_spoofing_basic_rule_setup_fixed_ip(self):
|
||||||
|
vif = FakeVif()
|
||||||
|
fake_details = {'fixed_ips': [{'ip_address': '192.168.44.100'}]}
|
||||||
|
self.agent.prevent_arp_spoofing = True
|
||||||
|
int_br = mock.create_autospec(self.agent.int_br)
|
||||||
|
self.agent.setup_arp_spoofing_protection(int_br, vif, fake_details)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
[mock.call(ip_addresses=set(), port=vif.ofport)],
|
[mock.call(port=vif.ofport)],
|
||||||
int_br.install_arp_spoofing_protection.mock_calls)
|
int_br.delete_arp_spoofing_protection.mock_calls)
|
||||||
|
self.assertTrue(int_br.install_arp_spoofing_protection.called)
|
||||||
|
|
||||||
def test_arp_spoofing_fixed_and_allowed_addresses(self):
|
def test_arp_spoofing_fixed_and_allowed_addresses(self):
|
||||||
vif = FakeVif()
|
vif = FakeVif()
|
||||||
|
Loading…
Reference in New Issue
Block a user