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.
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. |
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. |
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