安全组

安全组是应用于所有服务器的 IP 过滤规则集合,用于定义服务器的网络访问权限。组规则是项目特定的;项目成员可以编辑其组的默认规则并添加新的规则集。

所有项目都有一个 default(默认)安全组,该安全组应用于没有定义其他安全组的任何端口。除非您更改默认设置,否则此安全组会拒绝所有传入流量,并仅允许从您的实例发出的传出流量。

重要的是要提前了解,安全组及其配额是 网络服务 Neutron 的资源。它们被建模为端口的属性,而不是服务器的属性。尽管如此,Nova 提供了实用 API,允许用户从连接到服务器的所有端口添加和删除安全组。此外,在创建新服务器时,可以指定要配置的新创建端口的安全组,并检索连接到服务器的所有端口的组合安全组集。

注意

Nova 之前提供了自己的安全组 API。这些是 Neutron API 的代理 API,自 microversion 2.36 起已被弃用。

用法

与安全组相关的操作可以分为三类:安全组和安全组规则本身的操作、端口上的操作以及服务器上的操作。

安全组和安全组规则操作

默认情况下,任何项目成员都可以创建安全组。例如

$ openstack security group create --description <description> ... <name>

提示

在添加新的安全组时,您应该选择一个描述性但简短的名称。此名称显示在描述服务器的简短描述中,而较长的描述字段通常不显示。例如,看到服务器正在使用安全组 http 比看到 bobs_groupsecgrp1 更容易理解。

安全组实际上只是规则的容器。安全组规则定义了将应用的实际 IP 过滤规则。安全组默认拒绝所有内容,因此规则指示允许的内容。通常,安全组规则将配置以下属性:IP 协议(ICMP、TCP 或 UDP 中的一种)、目标端口或端口范围以及远程 IP 范围(以 CIDR 格式)。您可以通过指定这些属性以及应添加规则的安全组来创建安全组规则。例如

$ openstack security group rule create \
    --protocol <protocol> --dst-port <port-range> \
    --remote-ip <ip-address> \
    <group>

注意

<port-range> 参数采用 portfrom-port:to-port 的形式。这指定了连接允许访问的本地端口范围,**而不是**连接的源端口和目标端口。

或者,您可以指定远程安全组,而不是指定远程 IP 范围。远程组将允许来自使用所述端口的任何服务器的指定协议和端口的请求。如果您使用远程组 foo 创建安全组规则,并将安全组应用于服务器 bar,则 bar 将能够接收来自具有安全组 foo 的任何其他服务器的匹配流量。使用远程安全组的安全组规则的创建方式与使用远程 IP 的安全组规则的创建方式大致相同。例如

$ openstack security group rule create \
    --protocol <protocol> --dst-port <port-range> \
    --remote-group <remote-group> \
    <group>

创建后,可以列出安全组和安全组规则。例如

$ openstack security group list
$ openstack security group rule list <group>

同样,您可以检查单个安全组或安全组规则。例如

$ openstack security group show <group>
$ openstack security group rule show <group> <rule>

最后,您可以删除安全组。这将删除安全组和相关的安全组规则。例如

$ openstack security group delete <group>

或者,您可以从现有组中删除单个规则。例如

$ openstack security group rule delete <rule>

端口操作

安全组是端口的属性。默认情况下,Neutron 会将 default(默认)安全组分配给所有新创建的端口。可以禁用此行为。例如

$ openstack port create --no-security-group ... <name>

可以在创建新端口时指定不同的安全组。例如

$ openstack port create --security-group <group> ... <name>

注意

如果您在创建端口时指定了安全组,则 **不会** 将 default(默认)安全组添加到端口。如果您希望添加 default(默认)安全组,则需要也指定它。

还可以将其他安全组添加到现有端口或从现有端口中删除。例如

$ openstack port set --security-group <group> ... <port>
$ openstack port unset --security-group <group> ... <port>

也可以从端口中删除所有安全组。例如

$ openstack port set --no-security-group <port>

服务器操作

可以以服务器范围的方式操作和配置安全组。当您创建新服务器时,网络可以自动分配(一种称为“为我获取网络”的功能),也可以手动配置。在两种情况下,将网络附加到服务器都会导致创建端口。可以指定一个或多个要分配给这些端口的安全组。例如

$ openstack server create --security-group <group> ... <name>

重要提示

这些安全组仅适用于自动创建的端口。它们不适用于在启动时附加到服务器的任何预创建端口。如果未指定安全组,则将使用当前项目的 default(默认)安全组。不可能指定不应将任何安全组应用于自动创建的端口。如果您希望从服务器的端口中删除 default(默认)安全组,则需要使用预创建的端口或在服务器创建后删除安全组。

服务器创建后,可以从连接到服务器的所有端口添加或删除安全组。例如

$ openstack server add security group <server> <group>
$ openstack server remove security group <server> <group>

注意

除非自定义,否则 default(默认)安全组允许服务器发出的传出流量。如果您删除此组并且不通过另一个安全组允许传出流量,您的服务器将不再能够与 元数据服务 通信。

也可以查看与服务器关联的安全组。例如

$ openstack server show -f value -c security_groups

重要提示

由于安全组是端口的属性而不是服务器的属性,因此该值是分配给所有端口的组合安全组集。不同的端口可能具有不同的安全组集。您可以使用 openstack port show 检查端口,以查看分配给单个端口的确切安全组。

示例

让我们来看一个创建用于部署 3 个 Web 服务器主机和 2 个数据库主机的安全组的示例。首先,我们将配置允许 HTTP 流量到 Web 服务器主机的安全组。

$ openstack security group create \
    --description "Allows Web traffic anywhere on the Internet." \
    web
+-----------------+--------------------------------------------------------------------------------------------------------------------------+
| Field           | Value                                                                                                                    |
+-----------------+--------------------------------------------------------------------------------------------------------------------------+
| created_at      | 2016-11-03T13:50:53Z                                                                                                     |
| description     | Allows Web traffic anywhere on the Internet.                                                                             |
| headers         |                                                                                                                          |
| id              | c0b92b20-4575-432a-b4a9-eaf2ad53f696                                                                                     |
| name            | web                                                                                                              |
| project_id      | 5669caad86a04256994cdf755df4d3c1                                                                                         |
| project_id      | 5669caad86a04256994cdf755df4d3c1                                                                                         |
| revision_number | 1                                                                                                                        |
| rules           | created_at='2016-11-03T13:50:53Z', direction='egress', ethertype='IPv4', id='4d8cec94-e0ee-4c20-9f56-8fb67c21e4df',      |
|                 | project_id='5669caad86a04256994cdf755df4d3c1', revision_number='1', updated_at='2016-11-03T13:50:53Z'                    |
|                 | created_at='2016-11-03T13:50:53Z', direction='egress', ethertype='IPv6', id='31be2ad1-be14-4aef-9492-ecebede2cf12',      |
|                 | project_id='5669caad86a04256994cdf755df4d3c1', revision_number='1', updated_at='2016-11-03T13:50:53Z'                    |
| updated_at      | 2016-11-03T13:50:53Z                                                                                                     |
+-----------------+--------------------------------------------------------------------------------------------------------------------------+

创建后,我们可以添加一个新的组规则以允许传入的 HTTP 流量到 80 端口

$ openstack security group rule create \
    --protocol tcp --dst-port 80:80 --remote-ip 0.0.0.0/0 \
    web
+-------------------+--------------------------------------+
| Field             | Value                                |
+-------------------+--------------------------------------+
| created_at        | 2016-11-06T14:02:00Z                 |
| description       |                                      |
| direction         | ingress                              |
| ethertype         | IPv4                                 |
| headers           |                                      |
| id                | 2ba06233-d5c8-43eb-93a9-8eaa94bc9eb5 |
| port_range_max    | 80                                   |
| port_range_min    | 80                                   |
| project_id        | 5669caad86a04256994cdf755df4d3c1     |
| project_id        | 5669caad86a04256994cdf755df4d3c1     |
| protocol          | tcp                                  |
| remote_group_id   | None                                 |
| remote_ip_prefix  | 0.0.0.0/0                            |
| revision_number   | 1                                    |
| security_group_id | c0b92b20-4575-432a-b4a9-eaf2ad53f696 |
| updated_at        | 2016-11-06T14:02:00Z                 |
+-------------------+--------------------------------------+

您可以通过创建其他规则来创建复杂的规则集。在此实例中,我们希望传递 HTTP 和 HTTPS 流量,因此我们将添加另一个规则

$ openstack security group rule create \
    --protocol tcp --dst-port 443:443 --remote-ip 0.0.0.0/0 \
    web
+-------------------+--------------------------------------+
| Field             | Value                                |
+-------------------+--------------------------------------+
| created_at        | 2016-11-06T14:09:20Z                 |
| description       |                                      |
| direction         | ingress                              |
| ethertype         | IPv4                                 |
| headers           |                                      |
| id                | 821c3ef6-9b21-426b-be5b-c8a94c2a839c |
| port_range_max    | 443                                  |
| port_range_min    | 443                                  |
| project_id        | 5669caad86a04256994cdf755df4d3c1     |
| project_id        | 5669caad86a04256994cdf755df4d3c1     |
| protocol          | tcp                                  |
| remote_group_id   | None                                 |
| remote_ip_prefix  | 0.0.0.0/0                            |
| revision_number   | 1                                    |
| security_group_id | c0b92b20-4575-432a-b4a9-eaf2ad53f696 |
| updated_at        | 2016-11-06T14:09:20Z                 |
+-------------------+--------------------------------------+

注意

尽管仅输出新添加的规则,但此操作是累加的(创建并强制执行两个规则)。

一个安全组就完成了。接下来是数据库主机。这些主机正在运行 MySQL,我们希望限制到相关端口(在本例中为 3306)的流量,**并且**限制来自 Web 服务器主机的传入流量。虽然我们可以为 Web 服务器的 IP 地址指定 CIDR,但首选解决方案是配置源组。这将允许我们在应用 web 安全组的情况下动态添加和删除 Web 服务器主机,而无需修改数据库主机的安全组。让我们创建安全组和必要的规则

$ openstack security group create database
$ openstack security group rule create \
    --protocol tcp --dst-port 3306 --remote-group web \
    database

database 规则现在允许来自使用 web 组的任何服务器访问 MySQL 的默认端口。

现在我们已经创建了安全组和规则,让我们列出它们以验证一切

$ openstack security group list
+--------------------------------------+----------+-------------+
| Id                                   | Name     | Description |
+--------------------------------------+----------+-------------+
| 73580272-d8fa-4927-bd55-c85e43bc4877 | default  | default     |
| c0b92b20-4575-432a-b4a9-eaf2ad53f696 | web      | web server  |
| 40e1e336-e207-494f-a3ec-a3c222336b22 | database | database    |
+--------------------------------------+----------+-------------+

我们还可以检查安全组的规则。让我们查看 web 安全组

$ openstack security group rule list web
+--------------------------------------+-------------+-----------+-----------------+-----------------------+
| ID                                   | IP Protocol | IP Range  | Port Range      | Remote Security Group |
+--------------------------------------+-------------+-----------+-----------------+-----------------------+
| 2ba06233-d5c8-43eb-93a9-8eaa94bc9eb5 | tcp         | 0.0.0.0/0 | 80:80           | None                  |
| 821c3ef6-9b21-426b-be5b-c8a94c2a839c | tcp         | 0.0.0.0/0 | 443:443         | None                  |
+--------------------------------------+-------------+-----------+-----------------+-----------------------+

假设一切看起来都正确,您现在可以使用这些安全组来创建新的服务器。