neutron-specs/specs/victoria/address-groups-support-in-security-group-rule.rst
Hang Yang 35fe0e3b0d Support address groups in security group rules
This specification describes how to support address groups in
security group rules.

Change-Id: Ib58afde9ed58092ffbc94f7d522d5f5d034b832b
Related-Bug: #1592028
2020-06-23 10:03:22 -05:00

23 KiB

Address Groups Support in Security Group Rules

https://bugs.launchpad.net/neutron/+bug/1592028

This specification describes how to support address groups (groups of IP address blocks) in Neutron security group rules. The concept of address groups was introduced in FWaaS v2.0 but not implemented [1].

Problem Description

Neutron security group rules currently support using an IP address block or a security group as the remote end of the network access rule. In actual usage, an OpenStack cloud may require connectivity between instances and external services which are not provisioned by OpenStack. And each service may also have multiple endpoint addresses which are not contiguous. To allow the connectivity, one rule per external address needs to be created which can be very cumbersome and difficult to maintain as the number of external addresses may be substantial.

Proposed Change

Add an API to aggregate IP address blocks into an address group object which could be later referenced when creating a security group rule. Thus the number of security group rules can be effectively reduced when there is the need to allow connectivity to a number of external service addresses. When IP addresses are updated in the address group, changes will also be reflected in the associated security group rules.

REST API Impact

New address groups API

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 No CR Owner of the address group. Only admin users can specify a project identifier other than their own.
addresses List Yes CRU Array of address. It supports both CIDR and IP range objects. An example of addresses: ["132.168.4.12/24", "132.168.5.12-132.168.5.24", "2001::db8::f00/64"]
List address groups

Lists address groups.

Request Type GET
Endpoint /v2.0/address-groups
Response Codes +

Success | 200

---------+--------------------------------------+

Error | Unauthorized(401)

Example List address groups: JSON request

GET /v2.0/address-groups
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",
            "addresses": [
               "132.168.4.12/24",
               "132.168.5.12-132.168.5.24",
               "2001::db8::f00/64"
            ]
        }
    ]
}
Show address group details

Shows address group details.

Request Type GET
Endpoint /v2.0/address-groups/<address_group_id>
Response Codes +

Success | 200

---------+------------------------------------------+

Error | Unauthorized(401), Not Found (404)

Example Show address group: JSON request

GET /v2.0/address-groups/8722e0e0-9cc9-4490-9660-8c9a5732fbb0
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",
        "addresses": [
           "132.168.4.12/24",
           "132.168.5.12-132.168.5.24",
           "2001::db8::f00/64"
        ]
    }
}
Create address group

Creates an address group.

Request Type POST
Endpoint /v2.0/address-groups/
Response Codes +

Success | 201

---------+--------------------------------------+

Error | Unauthorized(401), Bad Request(400)

Example Create address group: JSON request

POST /v2.0/address-groups
User-Agent: python-neutronclient
Accept: application/json
{
    "address_group": {
        "name": "ADDR_GP_1",
        "addresses": [
           "132.168.4.12/24",
           "132.168.5.12-132.168.5.24",
           "2001::db8::f00/64"
        ]
    }
}

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",
        "addresses": [
           "132.168.4.12/24",
           "132.168.5.12-132.168.5.24",
           "2001::db8::f00/64"
        ]
    }
}
Update address group

Updates an address group. To update addresses, use the add addresses and remove addresses operations.

Request Type PUT
Endpoint /v2.0/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/address-groups/8722e0e0-9cc9-4490-9660-8c9a5732fbb0
User-Agent: python-neutronclient
Accept: application/json
{
    "address_group": {
        "description": "new description",
        "name": "new name"
    }
}

Example Update address group: JSON response

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
{
   "address_group": {
        "description": "new description",
        "id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0",
        "name": "new name",
        "project_id": "45977fa2dbd7482098dd68d0d8970117",
        "addresses": [
           "132.168.4.12/24",
           "132.168.5.12-132.168.5.24",
           "2001::db8::f00/64"
        ]
    }
}
Add addresses to address group

Add addresses to an existing address group.

Request Type PUT
Endpoint /v2.0/address-groups/<address_group_id>/add_addresses
Response Codes +

Success | 200

---------+--------------------------------------------------------+

Error | Unauthorized(401), Bad Request(400), Not Found(404)

Example Update addresses: JSON request

PUT /v2.0/address-groups/8722e0e0-9cc9-4490-9660-8c9a5732fbb0/add_addresses
User-Agent: python-neutronclient
Accept: application/json
{
    "addresses": [
       "10.0.0.1/32",
       "2001:3889:120:fe42::/64"
    ]
}

Example Update addresses: 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",
        "addresses": [
           "132.168.4.12/24",
           "132.168.5.12-132.168.5.24",
           "10.0.0.1/32",
           "2001::db8::f00/64",
           "2001:3889:120:fe42::/64"
        ]
    }
}
Remove addresses from address group

Remove addresses from an existing address group.

Request Type PUT
Endpoint /v2.0/address-groups/<address_group_id>/remove_addresses
Response Codes +

Success | 200

---------+--------------------------------------------------------+

Error | Unauthorized(401), Bad Request(400), Not Found(404)

Example Remove addresses: JSON request

PUT /v2.0/address-groups/8722e0e0-9cc9-4490-9660-8c9a5732fbb0/remove_addresses
User-Agent: python-neutronclient
Accept: application/json
{
    "addresses": [
       "132.168.4.12/24",
       "2001::db8::f00/64"
    ]
}

Example Remove addresses: 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",
        "addresses": [
           "132.168.5.12-132.168.5.24"
        ]
    }
}
Delete address group

Deletes an address group.

This operation does not return a response body.

Request Type DELETE
Endpoint /v2.0/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/address-groups/8722e0e0-9cc9-4490-9660-8c9a5732fbb0
User-Agent: python-neutronclient
Accept: application/json

Example Delete address group: JSON response

HTTP/1.1 204 No Content
Content-Length: 0

Changes to the existing security group rules API

List security group rules

Lists security group rules.

Remote address group id field will be added to response.

GET /v2.0/security-group-rules
User-Agent: python-neutronclient
Accept: application/json

Example List security group rules: JSON response

{
    "security_group_rules": [
        {
            "direction": "ingress",
            "ethertype": "IPv4",
            "id": "f7d45c89-008e-4bab-88ad-d6811724c51c",
            "port_range_max": null,
            "port_range_min": null,
            "protocol": null,
            "remote_group_id": null,
            "remote_ip_prefix": null,
            "remote_address_group_id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0",
            "security_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5",
            "project_id": "e4f50856753b4dc6afee5fa6b9b6c550",
            "revision_number": 1,
            "created_at": "2018-03-19T19:16:56Z",
            "updated_at": "2018-03-19T19:16:56Z",
            "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550",
            "description": ""
        }
    ]
}
Show security group rule details

Shows security group rule details.

Remote address group id field will be added to response.

Example Show security group rule: JSON request

GET /v2.0/security-group-rules/f7d45c89-008e-4bab-88ad-d6811724c51c
User-Agent: python-neutronclient
Accept: application/json

Example Show security group rule: JSON response

{
    "security_group_rule": {
        "direction": "ingress",
        "ethertype": "IPv4",
        "id": "f7d45c89-008e-4bab-88ad-d6811724c51c",
        "port_range_max": null,
        "port_range_min": null,
        "protocol": null,
        "remote_group_id": null,
        "remote_ip_prefix": null,
        "remote_address_group_id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0",
        "security_group_id": "85cc3048-abc3-43cc-89b3-377341426ac5",
        "project_id": "e4f50856753b4dc6afee5fa6b9b6c550",
        "revision_number": 1,
        "created_at": "2018-03-19T19:16:56Z",
        "updated_at": "2018-03-19T19:16:56Z",
        "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550",
        "description": ""
    }
}
Create security group rule

Creates a security group rule with a remote address group.

Note: At most one of remote-group, remote-ip and remote-address-group can be specified. The rule is matched when the remote IP address in the packet matches any one of: remote_ip_address, one of the IP addresses in the address group, or an IP address of one of the ports in the remote security group.

Example Create security group rule: JSON request

POST /v2.0/security-group-rules
User-Agent: python-neutronclient
Accept: application/json
{
    "security_group_rule": {
        "direction": "ingress",
        "port_range_min": "80",
        "ethertype": "IPv4",
        "port_range_max": "80",
        "protocol": "tcp",
        "remote_address_group_id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0",
        "security_group_id": "a7734e61-b545-452d-a3cd-0189cbd9747a"
    }
}

Example Create security group rule: JSON response

HTTP/1.1 201 Created
Content-Type: application/json; charset=UTF-8
{
    "security_group_rule": {
        "direction": "ingress",
        "ethertype": "IPv4",
        "id": "2bc0accf-312e-429a-956e-e4407625eb62",
        "port_range_max": 80,
        "port_range_min": 80,
        "protocol": "tcp",
        "remote_ip_prefix": null,
        "remote_group_id": null,
        "remote_address_group_id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0",
        "security_group_id": "a7734e61-b545-452d-a3cd-0189cbd9747a",
        "project_id": "e4f50856753b4dc6afee5fa6b9b6c550",
        "revision_number": 1,
        "tenant_id": "e4f50856753b4dc6afee5fa6b9b6c550",
        "created_at": "2018-03-19T19:16:56Z",
        "updated_at": "2018-03-19T19:16:56Z",
        "description": ""
    }
}

Data Model Impact

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


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.

Address Group Address Associations
Attribute Type Req CRUD Description
address_group_id uuid-str No CRU UUID of address group.
address String No CRU Address that has to be associated to the address group.

Security Group Rules

Attribute remote_address_group_id will be added to security group rules table

Attribute Type Req CRUD Description
remote_address _group_id String No CRU When a remote_address_group is specified, it is matched when the remote IP address in the packet matches one of the IP addresses in the address group. This is exclusive with remote_ip_prefix and remote_group_id.

Implementation

Assignee(s)

  • Hang Yang

Work Items

  • REST API update
  • DB schema update
  • CLI update
  • Open vSwitch and iptables firewall drivers update
  • RBAC support for address groups
  • Documentation update

Testing

Tempest Tests

  • DB mixin and schema 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 API documentation have to be modified.

Developer Documentation

  • Neutron API devref and documentation need to be updated.

References

[1] https://specs.openstack.org/openstack/neutron-specs/specs/rocky/fwaas-2.0-address-groups-support.html

[2] https://docs.openstack.org/api-ref/network/v2/#security-group-rules-security-group-rules