安全组规则中地址组支持¶
https://bugs.launchpad.net/neutron/+bug/1592028
本规范描述了如何在 Neutron 安全组规则中支持地址组(IP 地址块的组)。地址组的概念是在 FWaaS v2.0 中引入的,但尚未实现 [1]。
问题描述¶
Neutron 安全组规则当前支持使用 IP 地址块或安全组作为网络访问规则的远程端。在实际使用中,OpenStack 云可能需要实例与未由 OpenStack 配置的服务之间的连接。并且每个服务也可能有多个不连续的端点地址。为了允许连接,需要为每个外部地址创建一个规则,这可能非常繁琐且难以维护,因为外部地址的数量可能很大。
提议的变更¶
添加一个 API 来聚合 IP 地址块到地址组对象中,该对象稍后可以在创建安全组规则时引用。因此,当需要允许连接到多个外部服务地址时,可以有效地减少安全组规则的数量。当地址组中的 IP 地址更新时,更改也会反映在关联的安全组规则中。
REST API 影响¶
新的地址组 API¶
属性 |
类型 |
必需 |
CRUD |
描述 |
|---|---|---|---|---|
id |
uuid-str |
N/A |
R |
地址组对象的唯一标识符。 |
name |
字符串 |
否 |
CRU |
地址组的人性化名称(限制为 255 个字符)。 不必唯一。 |
description |
字符串 |
否 |
CRU |
地址组的人性化描述(限制为 255 个字符)。 |
project_id |
uuid-str |
否 |
CR |
地址组的所有者。 只有管理员用户才能指定与其自身不同的项目标识符。 |
addresses |
列表 |
是 |
CRU |
地址数组。它支持 CIDR 和 IP 范围对象。地址示例:[“132.168.4.12/24”, “132.168.5.12-132.168.5.24”, “2001::db8::f00/64”] |
列出地址组¶
列出地址组。
请求类型
GET端点
/v2.0/address-groups响应代码
成功
200
Error
Unauthorized(401)
示例列出地址组:JSON 请求
GET /v2.0/address-groups
User-Agent: python-neutronclient
Accept: application/json
示例列出地址组:JSON 响应
{
"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"
]
}
]
}
显示地址组详细信息¶
显示地址组详细信息。
请求类型
GET端点
/v2.0/address-groups/<address_group_id>响应代码
成功
200
Error
Unauthorized(401), Not Found (404)
示例显示地址组:JSON 请求
GET /v2.0/address-groups/8722e0e0-9cc9-4490-9660-8c9a5732fbb0
User-Agent: python-neutronclient
Accept: application/json
示例显示地址组:JSON 响应
{
"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"
]
}
}
创建地址组¶
创建地址组。
请求类型
POST端点
/v2.0/address-groups/响应代码
成功
201
Error
Unauthorized(401), Bad Request(400)
示例创建地址组:JSON 请求
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"
]
}
}
示例创建地址组:JSON 响应
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"
]
}
}
更新地址组¶
更新地址组。要更新地址,请使用添加地址和删除地址操作。
请求类型
PUT端点
/v2.0/address-groups/<address_group_id>响应代码
成功
200
Error
Unauthorized(401), Bad Request(400) Not Found(404)
示例更新地址组:JSON 请求
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"
}
}
示例更新地址组:JSON 响应
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"
]
}
}
向地址组添加地址¶
向现有的地址组添加地址。
请求类型
PUT端点
/v2.0/address-groups/<address_group_id>/add_addresses响应代码
成功
200
Error
未授权(401),错误请求(400),未找到(404)
示例 更新地址: JSON 请求
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"
]
}
示例 更新地址: JSON 响应
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"
]
}
}
从地址组删除地址¶
从现有的地址组删除地址。
请求类型
PUT端点
/v2.0/address-groups/<address_group_id>/remove_addresses响应代码
成功
200
Error
未授权(401),错误请求(400),未找到(404)
示例 删除地址: JSON 请求
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"
]
}
示例 删除地址: JSON 响应
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端点
/v2.0/address-groups/<address_group_id>响应代码
成功
204
Error
Unauthorized(401), Not Found(404) Conflict(409) 当在地址组使用时执行操作时,将返回 Conflict 错误响应。
示例删除地址组:JSON 请求
DELETE /v2.0/address-groups/8722e0e0-9cc9-4490-9660-8c9a5732fbb0
User-Agent: python-neutronclient
Accept: application/json
示例删除地址组:JSON 响应
HTTP/1.1 204 No Content
Content-Length: 0
对现有安全组规则 API 的更改¶
列出安全组规则¶
列出安全组规则。
将在响应中添加远程地址组 ID 字段。
GET /v2.0/security-group-rules
User-Agent: python-neutronclient
Accept: application/json
示例 列出安全组规则: JSON 响应
{
"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": ""
}
]
}
显示安全组规则详细信息¶
显示安全组规则详细信息。
将在响应中添加远程地址组 ID 字段。
示例 显示安全组规则: JSON 请求
GET /v2.0/security-group-rules/f7d45c89-008e-4bab-88ad-d6811724c51c
User-Agent: python-neutronclient
Accept: application/json
示例 显示安全组规则: JSON 响应
{
"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": ""
}
}
创建安全组规则¶
使用远程地址组创建一个安全组规则。
注意:remote-group、remote-ip 和 remote-address-group 中最多只能指定一个。当数据包中的远程 IP 地址与以下任一匹配时,规则匹配:remote_ip_address、地址组中的一个 IP 地址,或远程安全组中的一个端口的 IP 地址。
示例 创建安全组规则: JSON 请求
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"
}
}
示例 创建安全组规则: JSON 响应
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": ""
}
}
数据模型影响¶
以下是上述 REST API 的后端数据库表。
属性 |
类型 |
必需 |
CRUD |
描述 |
|---|---|---|---|---|
id |
uuid-str |
N/A |
R |
地址组对象的唯一标识符。 |
name |
字符串 |
否 |
CRU |
地址组的人性化名称(限制为 255 个字符)。 不必唯一。 |
description |
字符串 |
否 |
CRU |
地址组的人性化描述(限制为 255 个字符)。 |
project_id |
uuid-str |
是 |
CR |
地址组的所有者。 只有管理员用户才能指定与其自身不同的项目标识符。 |
属性 |
类型 |
必需 |
CRUD |
描述 |
|---|---|---|---|---|
address_group_id |
uuid-str |
否 |
CRU |
地址组的 UUID。 |
address |
字符串 |
否 |
CRU |
必须与地址组关联的地址。 |
remote_address_group_id 属性将添加到安全组规则表
属性 |
类型 |
必需 |
CRUD |
描述 |
|---|---|---|---|---|
remote_address _group_id |
字符串 |
否 |
CRU |
当指定 remote_address_group 时,如果数据包中的远程 IP 地址与地址组中的一个 IP 地址匹配,则匹配。这与 remote_ip_prefix 和 remote_group_id 互斥。 |
实现¶
负责人¶
杨航
工作项¶
REST API 更新
数据库模式更新
CLI 更新
Open vSwitch 和 iptables 防火墙驱动程序更新
地址组的 RBAC 支持
文档更新
测试¶
Tempest 测试¶
DB mixin 和模式测试
Tempest 测试
CLI 测试
功能测试¶
需要编写新的测试
API 测试¶
REST API 和属性验证测试
文档影响¶
用户文档¶
需要修改 Neutron CLI 和 API 文档。
开发人员文档¶
需要更新 Neutron API devref 和文档。
参考资料¶
[2] https://docs.openstack.org/api-ref/network/v2/#security-group-rules-security-group-rules