Firewall as a Service API 2.0

Launchpad blueprint:

This spec introduces a few enhancements to Firewall as a Service (FWaaS) API including making it more granular by giving the users the ability to apply the firewall rules at the port level rather than at the router level. Support is extended to various types of Neutron ports, including VM ports and SFC ports as well as router ports. It also aims to provide better grouping mechanisms (firewall groups, address groups and service groups) and discuss the use of a common classifier in achieving it. While this spec is proposing the API, the implementation will be carried out in phases subject to availability of people to do the work. And at the end of Mitaka - we will have a working reference implementation but, that may not embody all the enhancements in this spec. The implementation phases will be tracked by an appropriate RFE referencing this as the parent spec.

Problem Description

The Security Group API extension is a well known API for handling network traffic. For basic traffic filtering, the Security Group API is well understood by users, but as cloud infrastructure gains wider acceptance into the enterprise, the security group API, which was built for public cloud infrastructure becomes insufficient for the security and network environments inside the enterprise.

As such, one-off changes to the Security Group API end up occurring in each deployment of OpenStack. One solution is to allow deployers of OpenStack to “extend” an API extension to make it fit in their security and network environment. Ideally, the Firewall as a Service API is the API where usecases more advanced than the basic “let any traffic from X IP into Y port into my group of VMs” should be supported.

But the existing Firewall as a Service API has been deprecated in Liberty because it was fairly limited, requiring substantial enhancements to make it cover all the use cases raised by the community. There are also some overlapping functionalities between FWaaS API and the SG API which need to be rationalized.

Use Cases:

https://trello.com/b/TIWf4dBJ/fwaas-usecase-categorization

Proposed Change

It is proposed to harmonize the FWaaS and Security Group models by converging the implementation of FWaaS and Security Groups but keeping a separate API for each of them while relying on a common backend. This spec proposes an enhanced FWaaS API that incorporates Security Groups functionality such that the FWaaS API becomes a superset of what is exposed by the Security Group API.

Relative to the FWaaS 1.0 API, the FWaaS 2.0 API provides the following enhancements:

  • Applies at the granularity of Neutron ports rather than tenant wide or a set of routers in a tenant.
  • Applies to various types of Neutron ports, including VM ports and SFC ports as well as router ports. By applying FWaaS at VM ports, it will be possible to filter east/west intra-subnet traffic as well as east/west inter-subnet traffic and north/south traffic. This will also allow FWaaS to filter east/west traffic when DVR is used, as opposed to FWaaS 1.0 that only filters north/south traffic in case of DVR [4], [5].
  • Allows for different firewall policies with different firewall rules to be applied to different directions (ingress vs egress).
  • Introduces the Firewall Group construct for Neutron ports. This becomes the association point for binding firewall policies and Neutron ports, as well as a way to specify allowed sources and destinations in firewall rules. This reduces or eliminates the need to specify IP addresses for east/west traffic flows in firewall rules. For example, when Firewall Group A is used as the source firewall group id in a rule within an ingress policy in Firewall Group B, we care only about the ports associated with Firewall Group A. When a packet arrives, it is matched if its source ip address matches an IP address of one the ports in Firewall Group A.
  • Adds indirections through address group and service group that allow groups of addresses and groups of L4 ports to be specified once and reused in multiple rules and multiple firewall policies.
  • Allows multiple firewall group associations for the same Neutron port. For example, one firewall group applied to a tenant’s web servers may specify a firewall policy that restricts traffic to HTTP only (intended for north/south traffic), while another firewall group applied to all the tenant’s instances may specify a firewall policy that allows all traffic types between sources and destinations in that firewall group (east/west traffic).

Relative to the Security Groups API [7], the FWaaS 2.0 API provides the following enhancements:

  • Adds an explicit action attribute to rules so that “deny” and “reject” actions can be specified in addition to the existing “allow” action. This is particularly important for tenant or service provider network admins that specify firewall policies meant to apply to all of a tenant’s or service provider’s instances, regardless of application.
  • Allows filtering based on both source and destination address prefixes, rather than just the remote (source for ingress traffic, destination for egress traffic) address prefixes.
  • Allows filtering based on both source and destination L4 port ranges, rather than just destination L4 port range.
  • By adding indirections through firewall group, address group and service group, allows for operational separation of responsibilities between users and experts such as network admins. Experts can define groups of IP address prefixes in address groups, and define service groups using protocol and source/destination ports. Users can then easily define firewall rules that refer to firewall group and service group, without having to know about IP addresses and L4 ports. For example, a service group named All Web Server Ports could be defined with protocol TCP and destination L4 ports 80, 8080, and 443.
  • Adds a “description” attribute to firewall rules.
  • Adds an “admin status” attribute to firewall rules.
  • Adds a “public” attribute allowing sharing of firewall rules between different projects.
  • Firewall groups reference firewall rules through a firewall policy. In particular, this allows reuse of sharable firewall policies that are referenced by multiple firewall groups.
  • In the future, it is expected that service groups will support deep packet inspection, so that traffic can be matched based on an application ID and L7 fields such as URL strings, instead of or in addition to L4 port ranges.

Relationship Between FWaaS and Security Groups

FWaaS and Security Groups remain as separate features. The Security Group API will be retained in addition to the FWaaS 2.0 API for two reasons.

The first reason to retain the existing Security Group API is for those users who want to leverage existing functionality in a way that aligns as closely as possible with non-OpenStack security group definitions.

The second reason has to do with “defense in depth”, where multiple layers of data plane access control are defined and applied. With existing FWaaS 1.0 and Security Groups, the perimeter firewall functionality is defined in FWaaS and enforced at OpenStack routers, while application firewall functionality is defined through Security Groups and enforced at VM ports. Both north/south and inter-subnet traffic must be allowed by both FWaaS and Security Groups in order to pass end-to-end from the source to the destination.

With FWaaS 2.0, it is important to retain “defense in depth” even when FWaaS is enforced at VM ports. When both FWaaS and Security Groups are associated with the same Neutron port, a packet must be allowed by both features, i.e. “deny” wins between FWaaS and Security Groups. This behavior is adopted to address typical use cases where a tenant network admin uses FWaaS to specify tenant wide rules that are to be applied regardless of the application, while an application deployer uses Security Groups to narrow down allowed traffic to only what is needed for a specific application.

For example, a network admin creates a firewall rule that denies port 25 traffic. Even if the application deployer creates a security group rule that allows port 25 traffic, the port 25 traffic will be denied.

Note that as with the existing FWaaS 1.0 API and Security Groups, by default OpenStack policy does not distinguish between different roles within a project. Default OpenStack policy will not prevent different users from the same project (e.g. application deployers vs tenant network admins) from accessing the FWaaS API. This may be investigated in future phases.

In future phases, the FWaaS 2.0 API will be enhanced so that multiple layers of “defense in depth” can be defined using only the FWaaS 2.0 API. This will allow application deployers to take advantage of the enhancements of FWaaS 2.0 relative to Security Groups, while retaining “defense in depth”. This will also allow for more than 2 layers of “defense in depth”, for example tenant application deployers, tenant network admins, and service provider network admins.

REST API Impact

Firewall Address Groups

Attribute Type Req CRUD Description
id uuid-str N/A R Unique identifier for the address_group object.
name String No CRU Human readable name for the address group (255 characters limit). Does not have to be unique.
description String No CRU Human readable description for the address group (255 characters limit).
project_id uuid-str Yes CR Owner of the address group. Only admin users can specify a project identifier other than their own.
cidrs List Yes CRU Array of key-value pairs of cidr and ip version.


Firewall Rules

Note that as with FWaaS 1.0, in FWaaS 2.0 firewall rules always use stateful connection tracking.

Attribute Type Req CRUD Description
id uuid-str N/A R Unique identifier for the firewall rule object.
project_id uuid-str Yes CR Owner of the firewall rule. Only admin users can specify a project identifier other than their own.
name String No CRU Human readable name for the firewall rule (255 characters limit). Does not have to be unique.
description String No CRU Human readable description for the firewall Rule (255 characters limit).
public Bool No CRU When set to True makes this firewall rule visible to projects other than its owner, and can be used in firewall policies not owned by its project.
protocol String No CRU IP Protocol.
source_port port-range No CRU Source port number or a range (an int in [1, 65535] or range in a:b).
destination_port port-range No CRU Destination port number or a range ( an int in [1, 65535] or range in a:b).
service_group_id uuid-str No CRU UUID of the service group [6].
ip_version Integer No CRU IP Protocol Version.
source_ip_address String No CRU Source IP address or CIDR.
destination_ip_address String No CRU Destination IP address or CIDR.
source_address _group_id uuid-str No CRU When a source_address_group is specified, it is matched when the source IP address in the packet matches one of the IP addresses in the address group.
destination_address _group_id uuid-str No CRU When a destination_address_group is specified, it is matched when the destination IP address in the packet matches one of the IP addresses in the address group.
source_firewall_group _id uuid-str No CRU When a source_firewall_group is specified, it is matched when the source IP address in the packet matches an IP address of one of the ports in the firewall group. Note: This holds true when firewall group contains a list of vm ports.
destination_firewall _group_id uuid-str No CRU When a destination_firewall_group is specified, it is matched when the destination IP address in the packet matches an IP address of one of the ports in the firewall group. Note: This holds true when firewall group contains a list of vm ports.
action String No CRU Action to be performed on the traffic matching the rule (ALLOW, DENY, REJECT). Default: DENY.
enabled Bool No CRU When set to False will disable this rule in the firewall policy. Facilitates selectively turning off rules without having to disassociate the rule from the firewall policy. Default: True.

Note: At most one of source_ip_address, source_address_group_id and source_firewall_group_id can be specified. The rule is matched when the source IP address in the packet matches any one of: source_ip_address, one of the IP addresses in the address group, or an IP address of one of the ports in the firewall group. If you want it to match any packet, set the source or destination to 0.0.0.0/0 or ::/0. The same applies to destination_ip_address, destination_address_group_id, and destination _firewall_group_id, with respect to the destination IP address in the packet.

Note: A rule may specify non-null values for either service_group_id, or any combination of protocol, source_port, and destination_port. |

Firewall policies

Attribute Type Req CRUD Description
id uuid-str N/A R Unique identifier for the firewall policy object.
project_id uuid-str Yes CR Owner of the firewall policy. Only admin users can specify a project identifier other than their own.
name String No CRU Human readable name for the firewall policy (255 characters limit). Does not have to be unique.
description String No CRU Human readable description for the firewall Policy (255 characters limit).
firewall_rules List No CRU This is an ordered list of firewall rule uuids. The firewall applies the rules in the order in which they appear.
audited Bool No CRU When set to True by the policy owner indicates that the firewall policy has been audited. Each time the firewall policy or the associated firewall rules are changed, this attribute will be set to False and will have to be explicitly set to True through an update operation.
public Bool No CRU When set to True makes this firewall policy visible to projects other than its owner.

Firewall groups

Firewall Groups (similar to Security Groups) are the central construct of the FWaaS 2.0 API. They serve two purposes:

  1. Through firewall group / port associations, they specify the the Neutron ports that are the points of enforcement of firewall policies.

  2. Through the source_firewall_group_id and destination_firewall _group_id in firewall rules, they allow for filtering based on source and destination identities, while minimizing the need to specify long lists of IP addresses.

    For each source_firewall_group and destination_firewall_group, the OpenStack controller will tell OpenStack FWaaS agents the set of IP addresses for all VM ports associated with firewall group. The list of router ports associated with the firewall group will be passed as is.

Similar to Security Groups, for each project, one Firewall Group named “default” will be created automatically. This default Firewall Group will be associate with all new VM ports within that project, unless it is explicitly disassociated from the new VM port. This provides a way for a tenant network admin to define a tenant wide firewall policy that applies to all VM ports, except when explicitly provisioned otherwise. The default firewall rules for the default Firewall Group are allow all, i.e. the tenant network admin will have to explicitly define firewall policies and rules in order for the default Firewall Group to take effect. For example, the tenant network admin may want to deny connectivity to certain IP addresses known to be harmful, or deny use of particular L4 ports. This behavior is chosen assuming that typical deployments will use “defense in depth”, with application deployers specifying default Security Groups, while tenant network admins specify default Firewall Groups.


Attribute Type Req CRUD Description
id uuid-str N/A R Unique identifier for the firewall group object.
name string No CRU Human readable name for the firewall group (255 characters limit). Does not have to be unique.
description string No CRU Human readable description for the firewall group (255 characters limit).
project_id uuid-str Yes CR Owner of the firewall group. Only admin users can specify a project identifier other than their own. Default: derived from authentication token.
ingress_firewall _policy_id uuid-str No CRU ‘null’ if not associated with any firewall policy.
egress_firewall _policy_id uuid-str No CRU ‘null’ if not associated with any firewall policy.
ports List No CRU List of port_ids that will be associated to this firewall_group.
List address groups

Lists address groups.

Request Type GET
Endpoint /fw/address_groups
Response Codes Success 200
Error Unauthorized(401)

Example List address groups: JSON request

GET /v2.0/fw/address_groups.json
User-Agent: python-neutronclient
Accept: application/json

Example List address groups: JSON response

{
    "address_groups": [
        {
            "description": "",
            "id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0",
            "name": "ADDR_GP_1",
            "project_id": "45977fa2dbd7482098dd68d0d8970117",
            "cidrs": [
               {"cidr": "132.168.4.12/24", "ip_version": 4},
               {"cidr": "2001::db8::f00/64", "ip_version": 6}
            ]
        }
    ]
}
Show address group details

Shows address group details.

Request Type GET
Endpoint /fw/address_groups/<address_group_id>
Response Codes Success 200
Error Unauthorized(401), Forbidden(403), Not Found (404)

Example Show address group: JSON request

GET /v2.0/fw/address_groups/9faaf49f-dd89-4e39-a8c6-101839aa49bc.json
User-Agent: python-neutronclient
Accept: application/json

Example Show address group: JSON response

{
   "address_group": {
        "description": "",
        "id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0",
        "name": "ADDR_GP_1",
        "project_id": "45977fa2dbd7482098dd68d0d8970117",
        "cidrs": [
           {"cidr": "132.168.4.12/24", "ip_version": 4},
           {"cidr": "2001::db8::f00/64", "ip_version": 6}
        ]
    }
}
Create address group

Creates an address group.

Request Type POST
Endpoint /fw/address_groups/
Response Codes Success 201
Error Unauthorized(401), Bad Request(400)

Example Create address group: JSON request

POST /v2.0/fw/address_groups.json
User-Agent: python-neutronclient
Accept: application/json
{
    "address_group": {
        "name": "ADDR_GP_1",
        "cidrs": [
           {"cidr": "132.168.4.12/24", "ip_version": 4},
           {"cidr": "2001::db8::f00/64", "ip_version": 6}
        ]
    }
}

Example Create address group: JSON response

HTTP/1.1 201 Created
Content-Type: application/json; charset=UTF-8
{
   "address_group": {
        "description": "",
        "id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0",
        "name": "ADDR_GP_1",
        "project_id": "45977fa2dbd7482098dd68d0d8970117",
        "cidrs": [
           {"cidr": "132.168.4.12/24", "ip_version": 4},
           {"cidr": "2001::db8::f00/64", "ip_version": 6}
        ]
    }
}
Update address group

Updates an address group.

Request Type PUT
Endpoint /fw/address_groups/<address_group_id>
Response Codes Success 200
Error Unauthorized(401), Bad Request(400) Not Found(404)

Example Update address group: JSON request

PUT /v2.0/fw/address_groups/41bfef97-af4e-4f6b-a5d3-4678859d2485.json
User-Agent: python-neutronclient
Accept: application/json
{
    "address_group": {
        "cidrs": [
           {"cidr": "132.168.4.12/24", "ip_version": 4},
           {"cidr": "2001::db8::f00/64", "ip_version": 6}
        ]
    }
}

Example Update address group: JSON response

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
{
   "address_group": {
        "description": "",
        "id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0",
        "name": "ADDR_GP_1",
        "project_id": "45977fa2dbd7482098dd68d0d8970117",
        "cidrs": [
           {"cidr": "132.168.4.12/24", "ip_version": 4},
           {"cidr": "2001::db8::f00/64", "ip_version": 6}
        ]

    }
}
Delete address group

Deletes an address group.

This operation does not return a response body.

Request Type DELETE
Endpoint /fw/address_groups/<address_group_id>
Response Codes Success 204
Error Unauthorized(401), Not Found(404) Conflict(409) The Conflict error response is returned when an operation is performed while address group is in use.

Example Delete address group: JSON request

DELETE /v2.0/fw/address_groups/1be5e5f7-c45e-49ba-85da-156575b60d50.json
User-Agent: python-neutronclient
Accept: application/json

Example Delete address group: JSON response

HTTP/1.1 204 No Content
Content-Length: 0
List firewall rules

Lists firewall rules.

Request Type GET
Endpoint /fw/firewall_rules
Response Codes Success 200
Error Unauthorized(401)

Example List firewall rules: JSON request

GET /v2.0/fw/firewall_rules.json
User-Agent: python-neutronclient
Accept: application/json

Example List firewall rules: JSON response

{
    "firewall_rules": [
        {
            "action": "ALLOW",
            "description": "",
            "service_group_id":"fe99d33c1-b472-44f9-8226-30dc4ffd45332",
            "enabled": true,
            "firewall_policy_id": "asd435dg3-b472-44f9-8226-30dc4ffd45332",
            "id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0",
            "name": "ALLOW_HTTP",
            "position": 1,
            "public": false,
            "protocol": "tcp",
            "source_port": null,
            "destination_port": null,
            "ip_version": 4,
            "source_ip_address": null,
            "destination_ip_address": null
            "source_address_group_id": null,
            "destination_address_group_id": null,
            "source_firewall_group_id": "ds876h5t1-b472-44f9-8226-3087j9u953gh2",
            "destination_firewall_group_id": "f98o6h5t1-b472-44f9-8226-3087j9u953gh2",
            "project_id": "45977fa2dbd7482098dd68d0d8970117"
        }
    ]
}
Show firewall rule details

Shows firewall rule details.

Request Type GET
Endpoint /fw/firewall_rules/<firewall_rule_id>
Response Codes Success 200
Error Unauthorized(401), Forbidden(403), Not Found (404)

Example Show firewall rule: JSON request

GET /v2.0/fw/firewall_rules/9faaf49f-dd89-4e39-a8c6-101839aa49bc.json
User-Agent: python-neutronclient
Accept: application/json

Example Show firewall rule: JSON response

{
    "firewall_rule": {
        "action": "ALLOW",
        "description": "",
        "service_group_id":"fe99d33c1-b472-44f9-8226-30dc4ffd45332",
        "enabled": true,
        "firewall_policy_id": "asd435dg3-b472-44f9-8226-30dc4ffd45332",
        "id": "9faaf49f-dd89-4e39-a8c6-101839aa49bc",
        "name": "ALLOW_HTTP",
        "position": 1,
        "public": false,
        "protocol": "tcp",
        "source_port": null,
        "destination_port": null,
        "ip_version": 4,
        "source_ip_address": null,
        "destination_ip_address": null,
        "source_address_group_id": null,
        "destination_address_group_id": "f9876h5t1-b472-44f9-8226-3087j9u953gh2",
        "source_firewall_group_id": "ds876h5t1-b472-44f9-8226-3087j9u953gh2",
        "destination_firewall_group_id": null,
        "project_id": "45977fa2dbd7482098dd68d0d8970117"
    }
}
Create firewall rule

Creates a firewall rule.

Request Type POST
Endpoint /fw/firewall_rules/
Response Codes Success 201
Error Unauthorized(401), Bad Request(400)

Example Create firewall rule: JSON request

POST /v2.0/fw/firewall_rules.json
User-Agent: python-neutronclient
Accept: application/json
{
    "firewall_rule": {
        "action": "ALLOW",
        "destination_address_group_id": "f9876h5t1-b472-44f9-8226-3087j9u953gh2"
        "service_group_id": "d2876h5t1-b472-44f9-8245-308dr4u953gh2"
        "enabled": true,
        "name": "ALLOW_HTTP"
    }
}

Example Create firewall rule: JSON response

HTTP/1.1 201 Created
Content-Type: application/json; charset=UTF-8
{
    "firewall_rule": {
        "action": "ALLOW",
        "description": "",
        "service_group_id": "d2876h5t1-b472-44f9-8245-308dr4u953gh2"
        "enabled": true,
        "firewall_policy_id": null,
        "id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0",
        "name": "ALLOW_HTTP",
        "position": 1,
        "public": false,
        "protocol": "tcp",
        "source_port": null,
        "destination_port": null,
        "ip_version": 4,
        "source_ip_address": null,
        "destination_ip_address": null,
        "source_address_group_id": null,
        "destination_address_group_id": "f9876h5t1-b472-44f9-8226-3087j9u953gh2",
        "source_firewall_group_id": "ds876h5t1-b472-44f9-8226-3087j9u953gh2",
        "destination_firewall_group_id": null,
        "project_id": "45977fa2dbd7482098dd68d0d8970117"
    }
}
Update firewall rule

Updates a firewall rule.

Request Type PUT
Endpoint /fw/firewall_rules/<firewall_rule_id>
Response Codes Success 200
Error Unauthorized(401), Bad Request(400) Not Found(404)

Example Update firewall rule: JSON request

PUT /v2.0/fw/firewall_rules/41bfef97-af4e-4f6b-a5d3-4678859d2485.json
User-Agent: python-neutronclient
Accept: application/json
{
    "firewall_rule": {
        "public": "true"
    }
}

Example Update firewall rule: JSON response

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
{
    "firewall_rule": {
        "action": "ALLOW",
        "description": "",
        "service_group_id": "d2876h5t1-b472-44f9-8245-308dr4u953gh2"
        "enabled": true,
        "firewall_policy_id": null,
        "id": "41bfef97-af4e-4f6b-a5d3-4678859d2485",
        "name": "ALLOW_HTTP",
        "position": 1,
        "public": true,
        "protocol": "tcp",
        "source_port": null,
        "destination_port": null,
        "ip_version": 4,
        "source_ip_address": null,
        "destination_ip_address": null,
        "source_address_group_id": null,
        "destination_address_group_id": "f9876h5t1-b472-44f9-8226-3087j9u953gh2",
        "source_firewall_group_id": "ds876h5t1-b472-44f9-8226-3087j9u953gh2",
        "destination_firewall_group_id": null,
        "project_id": "45977fa2dbd7482098dd68d0d8970117"
    }
}

Delete firewall rule

Deletes a firewall rule.

This operation does not return a response body.

Request Type DELETE
Endpoint /fw/firewall_rules/<firewall_rule_id>
Response Codes Success 204
Error Unauthorized(401), Not Found(404) Conflict(409) The Conflict error response is returned when an operation is performed while firewall rule is in use.

Example Delete firewall rule: JSON request

DELETE /v2.0/fw/firewall_rules/1be5e5f7-c45e-49ba-85da-156575b60d50.json
User-Agent: python-neutronclient
Accept: application/json

Example Delete firewall rule: JSON response

HTTP/1.1 204 No Content
Content-Length: 0
List firewall policies

Lists firewall policies.

Request Type GET
Endpoint /fw/firewall_policies
Response Codes Success 200
Error Unauthorized(401), Forbidden(403)

Example List firewall policies: JSON request

GET /v2.0/fw/firewall_policies.json
User-Agent: python-neutronclient
Accept: application/json

Example List firewall policies: JSON response

{
    "firewall_policies": [
        {
            "audited": false,
            "description": "",
            "firewall_rules": [
                "8722e0e0-9cc9-4490-9660-8c9a5732fbb0"
            ],
            "id": "c69933c1-b472-44f9-8226-30dc4ffd454c",
            "name": "test-policy",
            "public": false,
            "project_id": "45977fa2dbd7482098dd68d0d8970117"
        }
    ]
}
Show firewall policy details

Shows firewall policy details.

Request Type GET
Endpoint /fw/firewall_policies/<firewall_policy_id>
Response Codes Success 200
Error Unauthorized(401), Not Found(404)

Example Show firewall policy: JSON request

GET /v2.0/fw/firewall_policies/9faaf49f-dd89-4e39-a8c6-101839aa49bc.json
User-Agent: python-neutronclient
Accept: application/json

Example Show firewall policy: JSON response

{
    "firewall_policy": {
        "audited": false,
        "description": "",
        "firewall_rules": [
            "8722e0e0-9cc9-4490-9660-8c9a5732fbb0"
        ],
        "id": "c69933c1-b472-44f9-8226-30dc4ffd454c",
        "name": "test-policy",
        "public": false,
        "project_id": "45977fa2dbd7482098dd68d0d8970117"
    }
}
Create firewall policy

Creates a firewall policy.

Request Type POST
Endpoint /fw/firewall_policies
Response Codes Success 201
Error Unauthorized(401)

Example Create firewall policy: JSON request

POST /v2.0/fw/firewall_policies.json
User-Agent: python-neutronclient
Accept: application/json
{
    "firewall_policy": {
        "firewall_rules": [
            "8722e0e0-9cc9-4490-9660-8c9a5732fbb0"
        ],
        "name": "test-policy"
    }
}

Example Create firewall policy: JSON response

HTTP/1.1 201 Created
Content-Type: application/json; charset=UTF-8
{
    "firewall_policy": {
        "audited": false,
        "description": "",
        "firewall_rules": [
            "8722e0e0-9cc9-4490-9660-8c9a5732fbb0"
        ],
        "id": "c69933c1-b472-44f9-8226-30dc4ffd454c",
        "name": "test-policy",
        "public": false,
        "project_id": "45977fa2dbd7482098dd68d0d8970117"
    }
}
Update firewall policy

Updates a firewall policy.

Request Type PUT
Endpoint /fw/firewall_policies/<firewall_policy_id>
Response Codes Success 200
Error Unauthorized(401), Not Found (404)

Example Update firewall policy: JSON request

PUT /v2.0/fw/firewall_policies/41bfef97-af4e-4f6b-a5d3-4678859d2485.json
User-Agent: python-neutronclient
Accept: application/json
{
    "firewall_policy": {
        "firewall_rules": [
            "a08ef905-0ff6-4784-8374-175fffe7dade",
            "8722e0e0-9cc9-4490-9660-8c9a5732fbb0"
        ]
    }
}

Example Update firewall policy: JSON response

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
{
    "firewall_policy": {
        "audited": false,
        "description": "",
        "firewall_rules": [
            "a08ef905-0ff6-4784-8374-175fffe7dade",
            "8722e0e0-9cc9-4490-9660-8c9a5732fbb0"
        ],
        "id": "c69933c1-b472-44f9-8226-30dc4ffd454c",
        "name": "test-policy",
        "public": false,
        "project_id": "45977fa2dbd7482098dd68d0d8970117"
    }
}
Delete firewall policy

Deletes a firewall policy.

Request Type DELETE
Endpoint /fw/firewall_policies/<firewall_policy_id>
Response Codes Success 204
Error Unauthorized(401), Not Found(404) Conflict(409) The Conflict error response is returned when an operation is performed while the firewall policy is in use.

Example Delete firewall policy: JSON request

DELETE /v2.0/fw/firewall_policies/1be5e5f7-c45e-49ba-85da-156575b60d50.json
User-Agent: python-neutronclient
Accept: application/json

Example Delete firewall policy: JSON response

HTTP/1.1 204 No Content
Content-Length: 0
Insert firewall rule in firewall policy

Inserts a firewall rule in a firewall policy relative to the position of other rules.

Request Type PUT
Endpoint /fw/firewall_policies/<firewall_policy_id>\ /insert_rule
Response Codes Success 200
Error Unauthorized(401), Not Found(404) Bad Request(400) Bad Request error response is returned when the rule information is missing, Conflict(409)

Example Insert firewall rule in firewall policy: JSON request

PUT /v2.0/fw/firewall_policies/41bfef97-af4e-4f6b-a5d3-4678859d2485/insert_rule.json
User-Agent: python-neutronclient
Accept: application/json
{
    "firewall_rule_id": "7bc34b8c-8d3b-4ada-a9c8-1f4c11c65692",
    "insert_after": "a08ef905-0ff6-4784-8374-175fffe7dade",
    "insert_before": ""
}

Example Insert firewall rule in firewall policy: Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
{
    "audited": false,
    "description": "",
    "firewall_rules": [
        "a08ef905-0ff6-4784-8374-175fffe7dade",
        "7bc34b8c-8d3b-4ada-a9c8-1f4c11c65692",
        "8722e0e0-9cc9-4490-9660-8c9a5732fbb0"
    ],
    "id": "c69933c1-b472-44f9-8226-30dc4ffd454c",
    "name": "test-policy",
    "public": False,
    "project_id": "45977fa2dbd7482098dd68d0d8970117"
}

Note:

insert_before and insert_after parameters refer to firewall rule uuids already associated with the firewall policy. firewall_rule_id refers to uuid of the rule being inserted. When using “insert_after”, if there are any rules after the specified rule, they get shifted down by one to later position. When using “insert_before”, all rules from the specified rule on get shifted down by one to a later position. Only one of insert_after or insert_before can be non-null and if neither is specified, firewall_rule_is inserted at the first position.

Remove firewall rule from firewall policy

Removes a firewall rule from a firewall policy.

Request Type PUT
Endpoint /fw/firewall_policies/<firewall_policy_id>\ /remove_rule
Response Codes Success 200
Error Unauthorized(401), Not Found(404) Bad Request(400) Bad Request error response is returned when the rule information is missing or when a firewall rule is tried to be removed from a firewall policy to which it is not associated.

Example Remove firewall rule from firewall policy: JSON request

PUT /v2.0/fw/firewall_policies/41bfef97-af4e-4f6b-a5d3-4678859d2485/remove_rule.json
User-Agent: python-neutronclient
Accept: application/json
{
    "firewall_rule_id": "7bc34b8c-8d3b-4ada-a9c8-1f4c11c65692"
}

Example Remove firewall rule from firewall policy: JSON response

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
{
    "audited": false,
    "description": "",
    "firewall_rules": [
        "a08ef905-0ff6-4784-8374-175fffe7dade",
        "8722e0e0-9cc9-4490-9660-8c9a5732fbb0"
    ],
    "id": "c69933c1-b472-44f9-8226-30dc4ffd454c",
    "name": "test-policy",
    "public": false,
    "project_id": "45977fa2dbd7482098dd68d0d8970117"
}
List firewall groups

Lists firewall groups.

Request Type GET
Endpoint /fw/firewall_groups
Response Codes Success 200
Error Unauthorized(401)

Example List firewall groups: JSON request

GET /v2.0/fw/firewall_groups.json
User-Agent: python-neutronclient
Accept: application/json

Example List firewall groups: JSON response

{
    "firewall_groups": [
        {
            "description": "",
            "ingress_firewall_policy_id": null,
            "egress_firewall_policy_id": null,
            "id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0",
            "name": "FW_GROUP_1",
            "project_id": "45977fa2dbd7482098dd68d0d8970117",
            "ports":[
                 "8722e0e0-9cc9-4490-9660-8c9a5732fbb0"
             ],
        }
    ]
}
Show firewall group details

Shows firewall group details.

Request Type GET
Endpoint /fw/firewall_groups/<firewall_group_id>
Response Codes Success 200
Error Unauthorized(401), Forbidden(403), Not Found (404)

Example Show firewall group: JSON request

GET /v2.0/fw/firewall_groups/9faaf49f-dd89-4e39-a8c6-101839aa49bc.json
User-Agent: python-neutronclient
Accept: application/json

Example Show firewall group: JSON response

{
    "firewall_group": {
        "description": "",
        "ingress_firewall_policy_id": null,
        "egress_firewall_policy_id": null,
        "id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0",
        "name": "FW_GROUP_1",
        "project_id": "45977fa2dbd7482098dd68d0d8970117",
        "ports":[
             "8722e0e0-9cc9-4490-9660-8c9a5732fbb0"
         ],
    }
}
Create firewall group

Creates a firewall group.

Request Type POST
Endpoint /fw/firewall_groups/
Response Codes Success 201
Error Unauthorized(401), Bad Request(400)

Example Create firewall group: JSON request

POST /v2.0/fw/firewall_groups.json
User-Agent: python-neutronclient
Accept: application/json
{
    "firewall_rule": {
        "ports":[
             "8722e0e0-9cc9-4490-9660-8c9a5732fbb0"
         ],
        "name": "FW_GROUP_1"
    }
}

Example Create firewall group: JSON response

HTTP/1.1 201 Created
Content-Type: application/json; charset=UTF-8
{
    "firewall_group": {
        "description": "",
        "ingress_firewall_policy_id": null,
        "egress_firewall_policy_id": null,
        "id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0",
        "name": "FW_GROUP_1",
        "project_id": "45977fa2dbd7482098dd68d0d8970117",
        "ports":[
             "8722e0e0-9cc9-4490-9660-8c9a5732fbb0"
         ],
    }
}
Update firewall group

Updates a firewall group.

Request Type PUT
Endpoint /fw/firewall_groups/<firewall_group_id>
Response Codes Success 200
Error Unauthorized(401), Bad Request(400) Not Found(404)

Example Update firewall group: JSON request

PUT /v2.0/fw/firewall_groups/41bfef97-af4e-4f6b-a5d3-4678859d2485.json
User-Agent: python-neutronclient
Accept: application/json
{
    "firewall_group": {
        "ingress_firewall_policy_id": "f5876h5t1-b472-44f9-8245-308dr4u953gh2",
        "egress_firewall_policy_id": "dg476h5t1-b472-44f9-8245-308dr4u953gh2"
    }
}

Example Update firewall group: JSON response

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
{
    "firewall_group": {
        "description": "",
        "ingress_firewall_policy_id": "f5876h5t1-b472-44f9-8245-308dr4u953gh2",
        "egress_firewall_policy_id": "dg476h5t1-b472-44f9-8245-308dr4u953gh2",
        "id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0",
        "name": "FW_GROUP_1",
        "project_id": "45977fa2dbd7482098dd68d0d8970117",
        "ports":[
             "8722e0e0-9cc9-4490-9660-8c9a5732fbb0"
         ],
    }
}
Delete firewall group

Deletes a firewall group.

This operation does not return a response body.

Request Type DELETE
Endpoint /fw/firewall_groups/<firewall_group_id>
Response Codes Success 204
Error Unauthorized(401), Not Found(404)

Example Delete firewall group: JSON request

DELETE /v2.0/fw/firewall_groups/1be5e5f7-c45e-49ba-85da-156575b60d50.json
User-Agent: python-neutronclient
Accept: application/json

Example Delete firewall group: JSON response

HTTP/1.1 204 No Content
Content-Length: 0

Data Model Impact

The following are the backend database tables for the REST API proposed above.


Firewall Address Groups
Attribute Type Req CRUD Description
id uuid-str N/A R Unique identifier for the address_group object.
name String No CRU Human readable name for the address group (255 characters limit). Does not have to be unique.
description String No CRU Human readable description for the address group (255 characters limit).
project_id uuid-str Yes CR Owner of the address group. Only admin users can specify a project identifier other than their own.

Firewall Address Group CIDR associations
Attribute Type Req CRUD Description
id uuid-str N/A R Unique identifier for the address_group object.
firewall_address _group_id uuid-str No CRU UUID of firewall address group.
cidr String No CRU CIDR that has to be associated to the firewall address group.
ip_version Integer No CRU IP Protocol Version of the cidr.

Firewall Rules
Attribute Type Req CRUD Description
id uuid-str N/A R Unique identifier for the firewall rule object.
project_id uuid-str Yes CR Owner of the firewall rule. Only admin users can specify a project identifier other than their own.
name String No CRU Human readable name for the firewall rule (255 characters limit). Does not have to be unique.
description String No CRU Human readable description for the firewall Rule (255 characters limit).
public Bool No CRU When set to True makes this firewall rule visible to projects other than its owner, and can be used in firewall policies not owned by its project.
protocol String No CRU IP Protocol.
source_port port-range No CRU Source port number or a range (an int in [1, 65535] or range in a:b).
destination_port port-range No CRU Destination port number or a range ( an int in [1, 65535] or range in a:b).
service_group_id uuid-str No CRU UUID of the service group [6].
ip_version Integer No CRU IP Protocol Version.
source_ip_address String No CRU Source IP address or CIDR.
destination_ip_address String No CRU Destination IP address or CIDR.
source_address _group_id uuid-str No CRU When a source_address_group is specified, it is matched when the source IP address in the packet matches one of the IP addresses in the address group.
destination_address _group_id uuid-str No CRU When a destination_address_group is specified, it is matched when the destination IP address in the packet matches one of the IP addresses in the address group.
source_firewall_group _id uuid-str No CRU When a source_firewall_group is specified, it is matched when the source IP address in the packet matches an IP address of one of the ports in the firewall group.
destination_firewall _group_id uuid-str No CRU When a destination_firewall_group is specified, it is matched when the destination IP address in the packet matches an IP address of one of the ports in the firewall group.
action String No CRU Action to be performed on the traffic matching the rule (ALLOW, DENY, REJECT). Default: DENY.
enabled Bool No CRU When set to False will disable this rule in the firewall policy. Facilitates selectively turning off rules without having to disassociate the rule from the firewall policy. Default: True.

Firewall Policies
Attribute Type Req CRUD Description
id uuid-str N/A R Unique identifier for the firewall policy object.
project_id uuid-str Yes CR Owner of the firewall policy. Only admin users can specify a project identifier other than their own.
name String No CRU Human readable name for the firewall policy (255 characters limit). Does not have to be unique.
description String No CRU Human readable description for the firewall Policy (255 characters limit).
audited Bool No CRU When set to True by the policy owner indicates that the firewall policy has been audited. Each time the firewall policy or the associated firewall rules are changed, this attribute will be set to False and will have to be explicitly set to True through an update operation.
public Bool No CRU When set to True makes this firewall policy visible to projects other than its owner.

Firewall Policy Rule associations
Attribute Type Req CRUD Description
id uuid-str N/A R Unique identifier for the firewall_policy_rules object.
firewall_policy_id uuid-str No CRU UUID of the firewall policy.
firewall_rule_id uuid-str No CRU UUID of the firewall rule.
position Integer No CRU This is an attribute that gets assigned to this rule when the rule is associated with a firewall policy. It indicates the position of this rule in that firewall policy.

Firewall Groups
Attribute Type Req CRUD Description
id uuid-str N/A R Unique identifier for the firewall group object.
name string No CRU Human readable name for the firewall group (255 characters limit). Does not have to be unique.
description string No CRU Human readable description for the firewall group (255 characters limit).
project_id uuid-str Yes CR Owner of the firewall group. Only admin users can specify a project identifier other than their own. Default: derived from authentication token.
ingress_firewall _policy_id uuid-str No CRU ‘null’ if not associated with any firewall policy.
egress_firewall _policy_id uuid-str No CRU ‘null’ if not associated with any firewall policy.

Firewall Group Port associations
Attribute Type Req CRUD Description
id uuid N/A R Unique identifier for the firewall_group_port object.
firewall_group_id uuid No CRU UUID of the firewall group.
port_id uuid No CRU UUID of the port that will be associated to this firewall_group. It can be any Neutron port (VM ports, router ports, SFC ports).


Multiple Firewall Policies

When only one firewall group is associated with a specific Neutron port, the firewall rules are evaluated in order according to their position. Both “allow” and “deny” rules can be interspersed in any order, with the first match determining the action to be taken.

The FWaaS 2.0 API allows for multiple firewall group associations for the same Neutron port. For example, one firewall group applied to a tenant’s web servers may specify a firewall policy that restricts traffic to HTTP only (intended for north/south traffic), while another firewall group applied to all the tenant’s instances may specify a firewall policy that allows all traffic types between sources and destinations in that firewall group (east/west traffic).

When there are multiple firewall groups associated with a specific Neutron port, there is no position or priority between the different firewall groups. Some deterministic behavior must be defined in order to resolve the action to be taken when some firewall groups determine an “allow” action while other firewall groups determine a “deny” action.

This spec defines that packets will be allowed if any one of the firewall groups associated with that Neutron port allows the packet. This behavior is similar to the case of multiple Security Groups associated with the same VM port.

In future phases, new constructs will be proposed that will allow for for a “deny” action determined by one firewall group to override an “allow” action determined by a different firewall group in some cases, depending on how the firewall groups are associated with the Neutron port. Refer “Stratum” section in [3] for further details.

Security Impact

TBD.

Notifications Impact

None.

Other End User Impact

In case of DVR, router ports other than north-facing router ports will not be supported. The asymmetric design of the DVR data plane for east/west traffic prevents the use of connection tracking, which is essential for proper FWaaS operation. The workaround in order to apply FWaaS to east/west traffic is to enforce FWaaS at VM ports rather than router ports. Enforcement of FWaaS at VM ports seems to be better aligned with the distributed architecture of DVR, regardless of this restriction.

Performance Impact

TBD.

IPv6 Impact

None

Other Deployer Impact

  • We will need new Heat models.

Developer Impact

None.

Community Impact

None.

Alternatives

None.

Implementation

Assignee(s)

  • Aishwarya Thangappa
  • Chandan Dutta Chowdhury
  • German Eichberger
  • James Ardent
  • Mickey Spiegel
  • Nate Johnston
  • Sarath Chandra Mekala
  • Shweta Padubidri
  • Sridhar Kandaswamy

Work Items

  • REST API
  • DB Schema
  • CLI update

Dependencies

  • Depends on the Service Groups [6]

Testing

Tempest Tests

  • DB mixin and schema tests
  • FWaaS Plugin with mocked driver end-to-end tests
  • Tempest tests
  • CLI tests

Functional Tests

  • New tests need to be written

API Tests

  • REST API and attributes validation tests

Documentation Impact

User Documentation

  • Neutron CLI and FWaaS API documentation have to be modified.

Developer Documentation

  • neutron-fwaas repo will have a devref and documentation will be written.