# 命名空间

从 EMQX 5.9.0 开始，命名空间功能允许用户在单个 EMQX 集群中逻辑地分组 MQTT 客户端，并对其应用流量限制。该功能使得多个客户端组（如业务单元、应用程序或客户）能够共享相同的基础设施，同时保持逻辑上的隔离，从而支持可扩展的部署。

EMQX 中的命名空间功能由两部分组成：

- **MQTT 客户端命名空间**：基于用户名、SNI 或其他连接元数据对 MQTT 客户端进行逻辑分组，可按命名空间设置配额、速率限制，以及客户端 ID 和主题层面的隔离策略。
- **管理员用户命名空间**：Dashboard、CLI 与 API 用户可通过[命名空间角色](../dashboard/system.md#命名空间角色)绑定到特定命名空间，使委派管理员仅能查看与操作其所属命名空间内的资源。自 EMQX 6.0 起可用。

::: warning 仅适用于受信任部署

**管理员用户命名空间**仅适用于受信任的内部部署场景，例如在同一组织内隔离不同团队或业务单元，以降低误修改其他配置的风险。它**不**提供强隔离保障，**不**适合作为面向公共环境或非受信任用户的多租户安全边界。如果您计划将管理员用户命名空间用于公共多租户部署，请联系 EMQ 销售团队，目前该场景尚未提供开箱即用的支持。

对于 **MQTT 客户端命名空间**，跨命名空间客户端之间的隔离需要显式配置才会生效。当不同命名空间下的客户端互不信任时，请参见[隔离机制](#隔离机制)了解必须配置的客户端 ID 覆盖与主题挂载点。

:::

从 EMQX 6.1 起，命名空间相关能力在保持原有语义不变的基础上进行了增强，进一步简化了多租户隔离配置，并统一了主题隔离相关的行为。

## 什么是命名空间

命名空间是 EMQX 企业版中用于对 MQTT 客户端进行逻辑隔离和资源管理的一种机制。它允许用户在共享一个 EMQX 集群的前提下，将不同业务或租户的客户端划分到不同的命名空间中，实现连接、消息、配额等方面的隔离控制。

命名空间通过特殊的客户端属性 `tns`（租户命名空间）来标识。该属性并非自动存在，而是需要通过配置从客户端连接的元数据中提取，例如用户名或服务器名称指示符（SNI）。

命名空间在被创建后即开始生效，无论该命名空间是通过 Dashboard 或 REST API 显式创建，还是基于命名空间来源在客户端连接时自动创建。

> **典型应用场景包括**：企业内部多个业务共用集群、租户级资源隔离管理、集中化接入控制等。

### 命名空间可以用于实现以下目标：

- **客户端与消息的逻辑隔离**

  命名空间可作为区分不同租户的依据，用于实现客户端 ID 和消息主题的命名隔离。但请注意，启用命名空间后**不会自动**获得客户端 ID 覆盖、主题前缀等隔离效果，用户需根据实际需要手动配置，详见[隔离机制](#隔离机制)。

- **租户级配额与连接控制**

  可以限制每个命名空间下的客户端连接数和消息发布速率，防止单一租户过度占用资源。

- **日志增强与运维追踪**

  日志中将自动添加命名空间标识字段，便于识别和定位某个租户下的客户端行为。

- **按命名空间进行资源使用监控**

  支持基于命名空间统计连接数量、发布速率等指标，为运维和容量规划提供支持。

- **管理员用户隔离**

  从 EMQX 6.0 起，命名空间机制也扩展到了 Dashboard、CLI 与 API 层面的用户管理，通过[命名空间角色](../dashboard/system.md#命名空间角色) 实现租户级权限控制。请参阅本页顶部的[仅适用于受信任部署](#命名空间)说明，了解信任模型与所需的防护措施。

  - 管理员用户可被指定为仅限访问特定命名空间的角色，例如：`ns:team_a::administrator`。
  - 命名空间用户仅能查看与操作其所属命名空间内的资源。
  - 尚未支持命名空间隔离的集群级配置项对命名空间用户为只读，仅全局管理员具备修改权限。
  - 从 EMQX 6.0.4 开始，命名空间管理员可以[管理自己命名空间中的 API 密钥](../api.md#命名空间管理员管理-api-密钥)。全局密钥和其他命名空间中的密钥仍不可访问。
  - 这一机制在实现数据隔离的同时，也确保了管理权限的安全分离。

- **多租户统一管理**

  系统管理员可以在同一个集群中统一管理多个命名空间，而每个租户在其独立的环境中进行操作，资源与权限完全隔离，互不影响。

## 管理员命名空间的运维安全

委派的命名空间管理员可以配置连接器、数据桥接和动作等出站目标。如果缺乏访问控制，可能导致 EMQX 向内部或敏感网络发起非预期请求。

在可用版本中启用 `rule_engine.ssrf`，以在测试、创建或更新 HTTP、MQTT 连接器配置时校验目标地址。从 EMQX 6.0.4 开始，该策略不覆盖其他连接器类型或运行时连接。请在 EMQX 所在主机上增加出站访问控制，为所有连接器类型建立出站网络边界：

- 仅允许访问已批准的目标地址，例如身份提供商（IdP）、Webhook 接收端或连接器后端。
- 默认拒绝访问实例元数据服务、回环地址、链路本地地址以及内部管理网络，除非明确需要。典型需要显式阻止的元数据端点包括 `100.100.100.200`、`169.254.169.253`、`169.254.169.254` 和 `fd00:ec2::254`。
- 每次新增会发起出站 HTTP 或 TCP 连接的集成功能或管理能力时，都同步审查防火墙规则。

详情参见[结合规则引擎策略与防火墙规则防御 SSRF](../cluster/security.md#结合规则引擎策略与防火墙规则防御-ssrf)。

## 隔离机制

EMQX 拥有极高的灵活性，在命名空间功能实现之前，就已支持多种隔离方式，命名空间功能提供了统一的租户标识字段（`client_attrs.tns`），使客户端 ID、主题挂载点等配置能够围绕统一的租户信息组织和管理。

客户端 ID 与主题隔离不会自动启用，需要根据业务需求和信任模型手动配置。

### 客户端 ID 覆盖

::: warning 非受信任多租户部署必须配置

当不同命名空间下的客户端之间互不信任时（例如每个命名空间对应一个外部客户或独立组织），**必须**根据 EMQX 确定命名空间的时机配置相应的客户端 ID 覆盖机制。

如果未配置覆盖机制，一个命名空间中的客户端可以复用其他租户的客户端 ID。这可能导致该租户的客户端断开连接、持久会话被劫持，或该租户遭受拒绝服务。仅配置身份认证无法阻止此类攻击，因为 EMQX 在全局范围内使用有效客户端 ID 标识会话。

请同时配置[使用挂载点进行主题隔离](#使用挂载点进行主题隔离)，确保主题层访问也无法跨越命名空间边界。

:::

如果 EMQX 能够在认证开始前根据用户名、客户端 ID 或客户端证书等连接信息确定命名空间，请配置 `mqtt.clientid_override`。例如：

```hocon
mqtt.clientid_override = "concat([client_attrs.tns, '-', clientid])"
```

此规则会将命名空间作为前缀添加到客户端 ID 中，避免冲突。如果命名空间或生成替代客户端 ID 所需的其他值由认证后端确定，请改为让认证后端返回 `clientid_override`。不要同时配置两种机制。详情请参见[客户端 ID 隔离](./namespace-global-settings.md#客户端-id-隔离)。

### 使用挂载点进行主题隔离

若不同命名空间的客户端需要发布或订阅相同的主题名称，而又不希望互相影响，可使用挂载点自动添加命名空间前缀。

在 EMQX 6.0 及之前版本中，通常需要在监听器（Listener）级别配置挂载点，例如：

```hocon
listener.{TYPE}.{NAME}.mountpoint = "${client_attrs.tns}/"
```

在存在多个监听器的场景下，该方式需要在多个位置重复配置。

从 EMQX 6.1 开始，支持将命名空间作为统一的主题挂载点。在成功识别命名空间后，EMQX 会在内部使用 `{namespace}/` 作为主题前缀，实现与监听器挂载点等价的主题隔离效果，而无需在每个监听器上单独配置。

为保持向后兼容性，默认情况下授权（ACL）检查不会包含挂载点前缀。从 EMQX 6.1 开始，你可以通过设置以下配置，让授权后端能够接收到带有挂载点前缀的主题：

```hocon
authorization.include_mountpoint = true
```

### 规则命名空间隔离

启用 `rule_engine.limit_selects_in_namespace`（默认启用）后，该配置可防止其他命名空间中的消息和客户端相关事件触发命名空间规则。EMQX 通过客户端属性 `client_attrs.tns` 判断客户端所属的命名空间。从 EMQX 6.1.5 开始，该配置还会将规则的消息重新发布动作输出主题限制在规则所属的命名空间内。

渲染主题模板后，如果生成的主题尚未以 `<namespace>/` 开头，EMQX 会添加 `<namespace>/` 前缀。已包含 `<namespace>/` 前缀的主题保持不变。全局规则以及设置了 `rule_engine.limit_selects_in_namespace = false` 的部署仍会直接发布到渲染后的主题，不添加规则所属的命名空间。

消息重新发布动作的这一行为不依赖 `mqtt.namespace_as_mountpoint`。该配置不会限制客户端跨命名空间发布或订阅主题。如需隔离客户端的主题访问，还需要配置挂载点进行主题隔离和授权规则。

## 多租户能力支持情况

命名空间是 EMQX 多租户能力的核心组成部分。自 EMQX 5.9 引入以来，命名空间支持已逐步扩展到多个子系统。EMQX 支持以下多租户能力：

- **管理命名空间与 MQTT 命名空间统一**（6.0）

  管理平面（Dashboard、CLI、API）与 MQTT 数据平面共享同一命名空间模型。

- **规则和数据集成隔离**（6.0）

  规则、动作、Source 和连接器支持命名空间隔离。

- **内置数据库身份认证的隔离**（6.1）

  支持基于命名空间对内置数据库中的认证数据进行隔离。

- **内置数据库权限认证的隔离**（6.1）

  授权规则可限定在指定命名空间范围内生效。

- **Prometheus 指标隔离**（6.1 引入，6.3 扩展）

  从 EMQX 6.1 开始，支持按命名空间暴露和聚合指标。从 EMQX 6.3 开始，命名空间隔离也适用于规则、动作和连接器的数据集成指标。有关抓取和过滤行为，参见[按命名空间抓取数据集成指标](../observability/prometheus.md#按命名空间抓取数据集成指标)。

- **主题指标集合隔离**（6.3）

  命名空间管理员创建的主题指标集合只统计同一命名空间中客户端发布的消息。命名空间管理员只能管理归属于本命名空间的集合，全局管理员可以列出所有命名空间中的集合。更多信息，参见[主题监控](../observability/topic-metrics.md#命名空间隔离)。

- **保留消息配额隔离**

  支持基于命名空间限制保留消息相关资源的使用。

## 下一步

现在您已了解命名空间的基本概念及其功能，可以继续以下几个步骤，开始在 EMQX 中使用命名空间功能：

- **[创建命名空间](./create-namespace.md)**: 了解如何通过 Dashboard 或 REST API 显式创建命名空间，或基于客户端元数据自动创建命名空间。
- **[配置与管理命名空间](./configure-manage-namespace.md)**: 了解如何通过 Dashboard 或 REST API 设置速率限制、会话配额等命名空间相关配置。
- **[命名空间全局设置](./namespace-global-settings.md)**：配置集群级别的命名空间行为，包括命名空间的解析方式、隔离机制、主题挂载点以及授权处理方式。
- **[快速体验命名空间功能](./namespace-quick-start.md)**：通过 MQTTX 实践操作，快速体验命名空间在客户端隔离、主题隔离等场景中的应用效果。
