Jump to: navigation, search

Spec-provider-firewall

Revision as of 23:31, 17 February 2013 by Ryan Lane (talk | contribs) (Text replace - "__NOTOC__" to "")
  • Launchpad Entry: NovaSpec:provider-firewall
  • Created:
  • Contributors:

Summary

Allow service providers to apply firewall rules at a level above security group rules.

Release Note

Add hook in Admin API to allow cloud admins to block traffic from specific network addresses by CIDR.

Rationale

Some people are just bad internet citizens. Stop bad traffic from reaching ANY instance in the DC, without relying on cooperation from instance owners.

User stories

Alice is a blackhat who is trying to bruteforce ssh connections on many instances in the cloud and is probing for open SMTP servers. Bob from DC-ops notices the bad traffic and blocks Alice from reaching any instances.

Design & Implementation

API

The admin api should take an admin request to block a CIDR network block. This method is nova/api/ec2/admin.py AdminController.block_external_addresses. It it accessible through nova/adminclient.py AdminClient.block_ips so it can easily be integrated into the dashboard or other clients.

When a message to block a network comes from an admin, the rules are written to the database with db.provider_fw_rule_create and a cast is made to compute to refresh the firewall.

Database

A function named 'provider_fw_rule_create' exists in db/api.py and db/sqlalchemy/api.py. There is also a model in db/sqlalchemy/models.py named ProviderFirewallRule that is used to write to the database. A migration for sqlalchemy exists as well. The rules can be listed with

Compute

Compute api responds to 'trigger_provider_fw_rules_refresh' which is used by the api server to let the compute workers know there are new rules to load. This casts to EVERY compute service with the message 'trigger_provider_fw_rules' (no arguments). The receiving compute manager forwards the call to the underlying virtualization driver (FLAGS.compute_driver which in turn probably forwards based on FLAGS.connection_type).

Libvirt

The bulk of the work is done in nova/virt/libvirt_connection.py. The class LibvirtConnection implements the 'refresh_provider_fw_rules' method, which is defined in FakeConnection in nova/virt/fake.py to raise NotImplemented (it exists in FakeConnection so implementors of other virtualization drivers know they need to define it). LibvirtConnection simply forwards the call to the firewall driver (FLAGS.firewall_driver). The FirewallDriver base class raises a NotImplementedError, whereas both IptablesFirewallDriver and NWFilterFirewall both alter the firewall to behave as expected.

NWFilterFirewall

During the creation of the instance firewall rules, immediately after the the reference to nova-base there is now a reference to nova-provider filter. This filter is rebuilt each time 'refresh_provider_fw_rules' is called. During setup of base rules, there is call to 'refresh_provider_fw_rules' to initially populate the filter. After processing the provider rules the traffic continues through the remaining filters for security group rules and project traffic.

IptablesFirewallDriver

A jump from the FORWARD chain to nova-provider is established. The nova-provider chain drops connections based on the state of the database, and is rebuilt during calls to 'refresh_provider_fw_rules'. After DROPping any blocked IP, it then JUMPs to nova-local where it continues the filtering process for security groups and project traffic.

Dashboard

This functionality isn't currently exposed to dashboard, but could be very easily, given its inclusion in NovaAdminClient.

Migration

NWFilterFirewall users will need to update their instance filters' xml to include the reference to the nova-provider filter. As the IptablesFirewallFilter regenerates the entire table at once for practically any call, any update to the firewall state should add provider-level filtering to the firewall rules (casting refresh_provider_fw_rules would work).

Test/Demo Plan

You should be able to call 'virsh nwfilter-list nova-instance-instance-ID' and see the filterref to nova-provider if using NWFilterFirewall. You should be able to 'iptables -L' and see the jump from FORWARD to nova-provider, and from nova-provider to nova-local.

Unresolved issues

It looks like not all connection_types implement the refresh_* calls. This is an issue with the security group calls as well as provider firewall rules.

BoF agenda and discussion

TBD