VPP/SecurityGroups

From fd.io
< VPP
Revision as of 13:10, 13 October 2016 by Ayourtch (Talk | contribs)

Jump to: navigation, search

VPP Security Groups

Introduction

Features are tracked as they are developed in the following VPP-427.

Requirements

  • Support classifiers/filters on any interface type (bridged / routed)
  • Filter on IP-addresses with address mask or prefix length (IPv4 and IPv6)
  • Filter on source and destination TCP/UDP port ranges
  • Filter on source and destination L2 MAC addresses
  • Support IPv6 with extension headers present
  • Support fragmented packets and unknown transport layer headers
  • Combinations of the above filters (e.g. MAC + IP)
  • Filters on ingress and egress interfaces
  • Stateful firewall. No application layer filtering.

Work list

Task Owner Priority Status Description
API definition Ole 0 WIP
Ingress/Egress support for classifier 0
Support for L2/L3 interfaces 0
"Established" behaviour 1
Stateful firewall 1
Port ip_tables_firewall.py from Neutron as unit test 1

Revised API

/*
 * Access List Rule entry
 *
 * Future considerations:
 * u32 proto_flags;
 * u8 traffic_class;
 * u32 flow_label;
 * u32 extension_header_present;
 * u8 port_range_operator
 */
typeonly define acl_rule
{
 u8 is_permit;
 u8 is_ipv6;
 u8 src_l2_address[6]
 /* src_l2_mask[6] or u8 use_src_l2_address ? */
 u8 dst_l2_address[6]
 /* dst_l2_mask[6] or u8 use_dst_l2_address ? */
 u8 src_ip_addr[16];
 u8 src_ip_prefix_len;
 u8 dst_ip_addr[16];
 u8 dst_ip_prefix_len;
 u8 proto;
 u16 src_min_port;
 u16 src_max_port;
 u16 dst_min_port;
 u16 dst_max_port;
};
define acl_add
{
 u32 client_index;
 u32 context;
 u32 count;
 vl_api_acl_rule r[count];
};
define acl_add_reply
{
 u32 context;
 u32 acl_index
 i32 retval;
};
define acl_del
{
 u32 client_index;
 u32 context;
 u32 acl_index
};
define acl_del_reply
{
 u32 context;
 i32 retval;
};
define acl_interface_add_del
{
 u32 client_index;
 u32 context;
 u8 is_add;
 u8 is_input;
 u32 sw_if_index;
 u32 acl_index;
}
define acl_interface_add_del_reply
{
 u32 context;
 i32 retval;
};
define acl_dump
{
 u32 client_context;
 u32 context;
 u32 sw_if_index; /* ~0 for all tunnels */
}
define acl_details
{
 u32 context;
 u32 sw_if_index;
 u32 acl_index;
 u32 count;
 vl_api_acl_rule_t r[count];
}

API

There is no API to set the default policy - this behavior can be achieved by adding a wildcard (all zero) protocol/ports/address, and may be handled internally as a special case. Nonetheless, there is no explicit API for setting this. Between the overlapping rules with different actions, the more specific rules always match first. This is done to ensure the matching is order-independent, as well as to allow the flexibility in the internal implementation.

/**
  Add or delete egress IP access policy rule. 
  The egress rule (*to* host(s) attached to this particular interface) 
  allows/denies the sessions to be initiated *to* the services running on this host(s).   
  */
 
define ip_apr_add_del_egress
{
       u32 client_index;
       u32 context;
       u32 sw_if_index;
       u8 is_add
       u8 allow;
       u8 is_ipv6;
       u8 src_ip_addr[16];
       u8 src_ip_prefix_len;
       u8 proto;
       u16 dst_min_port;
       u16 dst_max_port;
};
  
   
define ip_apr_add_del_egress_reply
{
       u32 context;
       i32 retval;
};
  
  
  
/**
  Add or delete ingress IP access policy rule. The ingress rule (*from* host(s) attached 
  to this particular interface) allows/denies the sessions to be initiated 
  *from* the host(s) attached to this interface.   
 */
  
define ip_apr_add_del_ingress
{
       u32 client_index;
       u32 context;
       u32 sw_if_index;
       u8 is_add;
       u8 allow;
       u8 is_ipv6;
       u8 dst_ip_addr[16];
       u8 dst_ip_prefix_len;
       u8 proto;
       u16 dst_min_port;
       u16 dst_max_port;
};
  
   
define ip_apr_add_del_ingress_reply
{
       u32 context;
       i32 retval;
};
  
  
/**
  Add or delete MAC / IP ingress filter. 
  These rules restrict the MAC addresses that can send the traffic. 
  If the ip_address is all-zero, any IP address is allowed and only
  the MAC address is used for the ingress filtering.
  There can be many MAC addresses on a given interface,
  a given MAC address may have multiple addresses associated with it 
  (by means of separate ingress rules), and different MAC addresses can also have the same addresses.  
*/
  
  
define ip_apr_macip_add_del_ingress
{
       u32 client_index;
       u32 context;
       u32 sw_if_index;
       u8 is_add;
       u8 is_ipv6;
       u8 mac_address[6];
       u8 ip_address[16];
};
  
/** 
  @param context            - sender context, to match reply w/response
  @param retval             - return code for the request
*/
  
define ip_apr_macip_add_del_ingress_reply
{
       u32 context;
       i32 retval;
};

General approach to the design

This functionality will be implemented using the "fastpath"/"slowpath" concept, with a few twists which are outlined later on.

On ingress, the packet will perform a lookup in a table matching the (MAC, IP) bindings, if they are configured. If there is no match in that table, the packet is dropped.

After that, a lookup will be done in a session table. (NB: whether we use classifier for this or not, is an open question, due to the existence of the IPv6 extension headers). If there is a match in the session table with a regular session entry, then potentially the breadcrumb information in the packet can set about its anticipated egress interface for later verification, and the packet processing continues as normal.

If there is a match in the session table with a drop-session entry, then the packet is dropped and a counter is incremented.

If there is no match in the session table, then the ingress security policy lookup is performed.

We have determined that in the generic case the security policy database may not be a classifier. How to implement it is TBD.

If the policy denies the packet, the packet is dropped, and potentially a drop-session is created.

If there policy permits the packet, then a breadcrumb "first packet" is set in the packet indicating this, and the packet processing continues as normal.

On egress, a check of a breadcrumb in the packet is performed:

breadcrumb is an egress interface -> we can verify the egress interface is as anticipated and either permit+log or drop the packet if it does not match.

breadcrumb is a "first packet" -> we perform a lookup in the egress policy on the interface.

If the policy permits the packet: we create a session in the session table on the ingress interface, noting there the egress interface, and send the packet on.

If the policy denies the packet: we drop the packet and optionally create a drop-session on the ingress interface.

From this description it can be seen that "slow path" and "fast path" are a bit of misnomers - the only "fast" about the fast path is that the packets there skip the policy check. Such an approach allows to minimize the discrepancies in forwarding of the initial and subsequent packets and avoid the creation of a second forwarding path.


Implementation plan

The high-level plan is to first create the stateless slow-path-only functionality and then add the fast-path stateful component. This implies that the slow-path can classify the return packets as well. While this is not precisely the same behavior as with stateful filter, having this was deemed useful both for development purposes to stage the development and as a potentially practical option for later. There will be a knob to allow the additional "mirrored" lookup, where the source and destination of the packets are swapped (and certain other additions will apply, e.g. the return packets for the TCP session can not be pure SYNs)

CLI

set interface input acl intfc <int> [ip4-table <index>] [ip6-table <index>] [l2-table <index>] [del] 
show inacl type [ip4|ip6|l2]
classify table [miss-next|l2-miss_next|acl-miss-next <next_index>] mask <mask-value> buckets <nn> [skip <n>] [match <n>] [del]
show classify tables [index <nn>]
classify session [hit-next|l2-hit-next|acl-hit-next <next_index>|policer-hit-next <policer_name>] table-index <nn> match [hex] [l2] [l3 ip4] [opaque-index <index>]
test classify [src <ip>] [sessions <nn>] [buckets <nn>] [table <nn>] [del]
set ip classify intfc <int> table-index <index>
set interface ip6 table <intfc> <table-id>
set interface l2 input classify intfc <interface-name> [ip4-table <n>] [ip6-table <n>] [other-table <n>]
set interface l2 output classify intfc <<interface-name>> [ip4-table <n>] [ip6-table <n>] [other-table <n>]
set ip source-and-port-range-check
show ip source-and-port-range-check vrf <nn> <ip-addr> <port>

Examples

YANG model

Open Issues

  • Security Group use case specific API. Done in VPP or control plane plugin?

References