This specification describes how to support address groups in security group rules. Change-Id: Ib58afde9ed58092ffbc94f7d522d5f5d034b832b Related-Bug: #1592028
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
[2] https://docs.openstack.org/api-ref/network/v2/#security-group-rules-security-group-rules