

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 将 AWS IoT Greengrass V2 核心设备设置为非 root
<a name="setup-greengrass-non-root"></a>

本页介绍了以非 root 用户身份运行 AWS IoT Greengrass 核心软件的四种解决方案。查看比较表，了解每种解决方案的特点和权衡取舍，然后使用决策流程图来确定哪种解决方案符合您的要求。

**注意**  
本页上的非 root 解决方案仅适用于 Linux 设备上的 AWS IoT Greengrass nucleus。不包括 Windows，因为 AWS IoT Greengrass V2 必须作为系统服务在 Windows 上运行。有关在 Linux 上安装标准根目录的信息，请参阅[安装具有自动资源配置功能的 AWS IoT Greengrass Core 软件](quick-installation.md)。  
要以非 root 用户身份运行 n AWS IoT Greengrass ucleus lite，请参阅在 n AWS IoT Greengrass ucleus 精简版[存储库中使用 Podman](https://github.com/aws-greengrass/aws-greengrass-lite/blob/main/docs/BUILD.md#optional-using-podman)。 GitHub 

**Topics**
+ [选择非根解决方案](#non-root-choose-solution)
+ [解决方案 1：在没有 root 访问权限 AWS IoT Greengrass V2 的情况下进行设置](#non-root-solution-1)
+ [解决方案 2：在不分离组件用户的情况下设置 AWS IoT Greengrass V2 为非 root](#non-root-solution-2)
+ [解决方案 3：设置 AWS IoT Greengrass V2 为非 root 用户且组件用户分离](#non-root-solution-3)
+ [解决方案 4：设置 AWS IoT Greengrass V2 为权限有限的 root 用户](#non-root-solution-4)
+ [所需的 Linux 功能 AWS IoT Greengrass V2](#linux-capabilities-reference)

## 选择非根解决方案
<a name="non-root-choose-solution"></a>

使用下表比较非 root 解决方案并了解它们的权衡取舍。根据您的安全要求和设备限制，每种解决方案都提供不同的功能。


**非根解决方案**  

| 解决方案 | 需要根访问权限 | 可以以不同的用户身份运行组件 | 将 Greengrass 作为系统服务运行 | 适用于 | 
| --- | --- | --- | --- | --- | 
| [解决方案 1：没有根访问权限](#non-root-solution-1) | 否 | 否 | 否（用户服务可选） | 你没有 root 访问权限的设备 | 
| [解决方案 2：非 root 用户，单用户](#non-root-solution-2) | 是（仅限安装） | 否 | 是 | 以非 root 用户身份运行 Greengrass，所有组件都以同一个用户身份运行 | 
| [解决方案 3：非 root 用户、多用户](#non-root-solution-3) | 是（仅限安装） | 支持 | 是 | 以非 root 用户身份运行 Greengrass，同时以不同的用户身份运行组件 | 
| [解决方案 4：功能有限的 Root](#non-root-solution-4) | 支持 | 是 | 是 | 以 root 用户身份运行 Greengrass，Linux 功能有限 | 

以下流程图将指导您根据设备限制和要求选择合适的解决方案。

![\[流程图显示了选择非根解决方案的决策过程。首先询问您的核心设备上是否有 root 用户访问权限。如果不是，请使用解决方案 1。如果是，请询问您是否需要以不同的 Linux 用户身份运行组件。如果不是，请使用解决方案 2。如果是，请询问您是否希望 Greengrass 以权限有限的 root 用户身份运行。如果是，请使用解决方案 4。如果不是，请使用解决方案 3。\]](http://docs.aws.amazon.com/zh_cn/greengrass/v2/developerguide/images/non-root-solution-decision-flow.png)


## 解决方案 1：在没有 root 访问权限 AWS IoT Greengrass V2 的情况下进行设置
<a name="non-root-solution-1"></a>

如果您在设备上没有 root 访问权限，请使用此解决方案。在此配置中， AWS IoT Greengrass Core 软件完全以非 root 用户身份运行，无需提升权限。

**权衡**  
此解决方案有以下限制：
+ **没有组件用户分离** — 所有组件都以运行 C AWS IoT Greengrass ore 软件的同一个用户身份运行。您不能使用该`posixUser`配置以不同的用户身份运行组件。
+ RequiresPrivilege 已@@ **忽略** — AWS IoT Greengrass Core 软件会忽略组件配方中的`RequiresPrivilege`选项。组件无法请求提升权限。
+ **没有系统服务**-您不能将 AWS IoT Greengrass Core 软件作为系统服务进行安装。您可以选择配置为 AWS IoT Greengrass V2 作为 systemd 用户服务运行。

**先决条件**  
此解决方案需要：
+ 设备上的非 root 用户帐户
+ 写入要安装 C AWS IoT Greengrass ore 软件的目录的访问权限

**在 AWS IoT Greengrass V2 没有 root 访问权限的情况下安装和运行**

1. 完成以下步骤[安装具有自动资源配置功能的 AWS IoT Greengrass Core 软件](quick-installation.md)：设置您的设备环境、提供凭据并下载 AWS IoT Greengrass 核心软件。

1. 创建安装目录并确保您的用户拥有该目录。

   ```
   mkdir -p $HOME/greengrass/v2
   ```

1. 在没有的情况下运行安装程序`sudo`。设置`--component-default-user`为您当前的用户。

   ```
   java -Droot="$HOME/greengrass/v2" -Dlog.store=FILE \
     -jar ./GreengrassInstaller/lib/Greengrass.jar \
     --aws-region region \
     --thing-name MyGreengrassCore \
     --thing-group-name MyGreengrassCoreGroup \
     --thing-policy-name GreengrassV2IoTThingPolicy \
     --tes-role-name GreengrassV2TokenExchangeRole \
     --tes-role-alias-name GreengrassCoreTokenExchangeRoleAlias \
     --component-default-user $USER \
     --provision true
   ```

   请勿使用，`--setup-system-service true`因为您没有 root 权限来创建系统服务。

**（可选）设置 systemd 用户服务**  
您可以配置 systemd 用户服务来管理 AWS IoT Greengrass 核心软件。这允许软件在您登录时自动启动。

**设置 systemd 用户服务**

1. 如果 AWS IoT Greengrass Core 软件当前正在运行，请将其停止。

   ```
   kill $(cat $HOME/greengrass/v2/alts/loader.pid)
   ```

1. 创建 systemd 用户服务目录。

   ```
   mkdir -p $HOME/.config/systemd/user
   ```

1. 在创建包含以下内容`$HOME/.config/systemd/user/greengrass.service`的服务文件。

   ```
   [Unit]
   Description=Greengrass Core
   
   [Service]
   Type=simple
   PIDFile=%h/greengrass/v2/alts/loader.pid
   RemainAfterExit=no
   Restart=on-failure
   RestartSec=10
   ExecStart=/bin/sh %h/greengrass/v2/alts/current/distro/bin/loader
   Environment="JAVA_HOME=/path/to/java"
   
   [Install]
   WantedBy=default.target
   ```

   在 systemd 用户单元文件中，`%h`是一个解析到运行服务的用户主目录的说明符。

   */path/to/java*替换为 Java 安装路径。

1. 启用并启动该服务。

   ```
   systemctl --user daemon-reload
   systemctl --user enable greengrass.service
   systemctl --user start greengrass.service
   ```

**重启和 OTA 更新行为**  
行为取决于您是否配置了 systemd 用户服务。

使用用户服务  
+ **设备重启** — AWS IoT Greengrass Core 软件在用户登录时自动启动。
+ **OTA 更新** — OTA 更新成功且软件会自动重启。

没有用户服务  
+ **设备重启** — AWS IoT Greengrass Core 软件不会自动重启。您必须手动启动它。
+ **OTA 更新** — OTA 更新成功，但之后必须手动启动 AWS IoT Greengrass 核心软件。

**系统资源限制**  
使用 cgroup 的每个组件的资源限制在此解决方案中不起作用，因为非 root 用户无法在中创建 cgroup 目录。`/sys/fs/cgroup/`如果您部署配置了资源限制的组件，则 AWS IoT Greengrass Core 软件将忽略配置的限制。

您可以使用以下替代方法来管理资源使用情况：
+ **Systemd 用户服务限制** — 如果您将 AWS IoT Greengrass 核心软件作为 systemd 用户服务运行，则可以在上向服务文件添加资源限制。`$HOME/.config/systemd/user/greengrass.service`这些限制适用于整个服务，包括 Greengrass 核心和所有组件。

  ```
  MemoryMax=2G
  CPUQuota=100%
  ```
+ **Greengrass nucleus JVM 限制 — 你可以通过配置 JVM 选项来限制** Greengrass nucleus 进程内存。有关更多信息，请参阅 [配置 AWS IoT Greengrass 核心软件](configure-greengrass-core-v2.md)。

## 解决方案 2：在不分离组件用户的情况下设置 AWS IoT Greengrass V2 为非 root
<a name="non-root-solution-2"></a>

如果您拥有初始设置的根访问权限，并且希望 AWS IoT Greengrass 核心软件作为非根系统服务运行，但不需要以不同的用户身份运行组件，请使用此解决方案。这与解决方案 1 类似，但该软件作为系统服务运行，在启动时自动启动。

**权衡**  
此解决方案有以下限制：
+ **没有组件用户分离** — 所有组件都以运行 C AWS IoT Greengrass ore 软件的同一个用户身份运行。您不能使用该`posixUser`配置以不同的用户身份运行组件。
+ RequiresPrivilege 已@@ **忽略** — AWS IoT Greengrass Core 软件会忽略组件配方中的`RequiresPrivilege`选项。组件无法请求提升权限。

**先决条件**  
此解决方案需要：
+ 初始设置的根访问权限
+ 您的设备上有 systemd

**在不分离组件用户的情况下以非 root 用户 AWS IoT Greengrass V2 身份安装和运行**

1. 完成以下步骤[安装具有自动资源配置功能的 AWS IoT Greengrass Core 软件](quick-installation.md)：设置您的设备环境、提供凭据并下载 AWS IoT Greengrass 核心软件。

1. 创建一个将运行 C AWS IoT Greengrass ore 软件和所有组件的非 root 用户。

   ```
   sudo useradd --create-home gg_non_root
   ```

1. 以非 root 用户身份登录并运行安装程序。设置`--component-default-user`为同一个用户。请勿使用`sudo`也不要设置系统服务。

   ```
   java -Droot="/home/gg_non_root/greengrass/v2" -Dlog.store=FILE \
     -jar ./GreengrassInstaller/lib/Greengrass.jar \
     --aws-region region \
     --thing-name MyGreengrassCore \
     --thing-group-name MyGreengrassCoreGroup \
     --thing-policy-name GreengrassV2IoTThingPolicy \
     --tes-role-name GreengrassV2TokenExchangeRole \
     --tes-role-alias-name GreengrassCoreTokenExchangeRoleAlias \
     --component-default-user gg_non_root \
     --provision true \
     --setup-system-service false
   ```

1. 以 root 用户身份在创建包含以下内容`/etc/systemd/system/greengrass.service`的系统服务文件。

   ```
   [Unit]
   Description=Greengrass Core
   After=network.target
   
   [Service]
   Type=simple
   User=gg_non_root
   PIDFile=/home/gg_non_root/greengrass/v2/alts/loader.pid
   RemainAfterExit=no
   Restart=on-failure
   RestartSec=10
   ExecStart=/bin/sh -c "exec /home/gg_non_root/greengrass/v2/alts/current/distro/bin/loader >> /home/gg_non_root/greengrass/v2/logs/loader.log 2>&1"
   KillMode=mixed
   NoNewPrivileges=true
   ProtectSystem=strict
   ReadWritePaths=/home/gg_non_root/greengrass /tmp
   
   [Install]
   WantedBy=multi-user.target
   ```

1. 停止正在运行的 AWS IoT Greengrass Core 实例，然后启用并启动系统服务。

   ```
   sudo systemctl daemon-reload
   sudo systemctl enable greengrass.service
   sudo systemctl start greengrass.service
   ```

**重启和 OTA 更新行为**  
在这个解决方案中：
+  AWS IoT Greengrass Core 软件作为系统服务运行，并在出现故障或设备重启时自动重启。
+  AWS IoT Greengrass Core 软件的 OTA 更新可以正常工作。该服务将以配置的非 root 用户身份自动重启。

**系统资源限制**  
在此解决方案中，使用 cgroup 的每个组件的资源限制不起作用，因为没有 Linux 功能的非 root 用户无法在中创建 cgroup 目录。`/sys/fs/cgroup/`如果您部署配置了资源限制的组件，则 AWS IoT Greengrass Core 软件将忽略配置的限制。

您可以使用以下替代方法来管理资源使用情况：
+ **Systemd 服务限制** — 您可以在以下位置向系统服务文件添加资源限制。`/etc/systemd/system/greengrass.service`这些限制适用于整个服务，包括 Greengrass 核心和所有组件。

  ```
  MemoryMax=2G
  CPUQuota=100%
  ```
+ **Greengrass nucleus JVM 限制 — 你可以通过配置 JVM 选项来限制** Greengrass nucleus 进程内存。有关更多信息，请参阅 [配置 AWS IoT Greengrass 核心软件](configure-greengrass-core-v2.md)。

## 解决方案 3：设置 AWS IoT Greengrass V2 为非 root 用户且组件用户分离
<a name="non-root-solution-3"></a>

如果您拥有初始设置的 root 访问权限，但希望 AWS IoT Greengrass 核心软件以非 root 用户身份运行，同时保持以不同用户身份运行组件的能力，请使用此解决方案。此配置使用 Linux 功能和 sudoers 来允许非 root 用户在运行组件时切换到其他用户。

**权衡**  
此解决方案有以下限制：
+ **需要 sudoers 配置** — 您必须配置 sudoers 以允许 AWS IoT Greengrass V2 用户像其他用户一样运行命令。

**先决条件**  
此解决方案需要：
+ 初始设置的根访问权限
+ systemd 版本 229 或更高版本，它支持。`AmbientCapabilities`要检查版本，请运行 `systemctl --version`。

**以非 root 用户 AWS IoT Greengrass V2 身份安装和运行，且组件用户分离**

1. 完成以下步骤[安装具有自动资源配置功能的 AWS IoT Greengrass Core 软件](quick-installation.md)：设置您的设备环境、提供凭据并下载 AWS IoT Greengrass 核心软件。

1. 创建一个将运行 C AWS IoT Greengrass ore 软件的非 root 用户。

   ```
   sudo useradd --create-home gg_non_root
   ```

1. 将非 root 用户添加到 sudoers 中，这样它就可以以组件用户的身份运行命令。在创建文件`/etc/sudoers.d/gg_non_root`。

   ```
   gg_non_root ALL=(ggc_user:ggc_group) NOPASSWD: SETENV: /bin/sh, /bin/bash
   ```

   如果您将组件配置为以其他用户身份运行`posixUser`，请为每个用户添加一个 sudoers 条目。例如：

   ```
   gg_non_root ALL=(ggc_user:ggc_group) NOPASSWD: SETENV: /bin/sh, /bin/bash
   gg_non_root ALL=(another_user:another_group) NOPASSWD: SETENV: /bin/sh, /bin/bash
   ```

1. 以非 root 用户身份登录并运行安装程序。请勿使用`sudo`也不要设置系统服务。

   ```
   java -Droot="/home/gg_non_root/greengrass/v2" -Dlog.store=FILE \
     -jar ./GreengrassInstaller/lib/Greengrass.jar \
     --aws-region region \
     --thing-name MyGreengrassCore \
     --thing-group-name MyGreengrassCoreGroup \
     --thing-policy-name GreengrassV2IoTThingPolicy \
     --tes-role-name GreengrassV2TokenExchangeRole \
     --tes-role-alias-name GreengrassCoreTokenExchangeRoleAlias \
     --component-default-user ggc_user:ggc_group \
     --provision true \
     --setup-system-service false
   ```

1. 以 root 用户身份在创建包含以下内容`/etc/systemd/system/greengrass.service`的系统服务文件。

   ```
   [Unit]
   Description=Greengrass Core
   After=network.target
   
   [Service]
   Type=simple
   User=gg_non_root
   PIDFile=/home/gg_non_root/greengrass/v2/alts/loader.pid
   RemainAfterExit=no
   Restart=on-failure
   RestartSec=10
   ExecStart=/bin/sh -c "exec /home/gg_non_root/greengrass/v2/alts/current/distro/bin/loader >> /home/gg_non_root/greengrass/v2/logs/loader.log 2>&1"
   KillMode=mixed
   AmbientCapabilities=CAP_CHOWN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_FOWNER CAP_SETUID CAP_SETGID CAP_SYS_RESOURCE CAP_AUDIT_WRITE
   CapabilityBoundingSet=CAP_CHOWN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_FOWNER CAP_SETUID CAP_SETGID CAP_SYS_RESOURCE CAP_AUDIT_WRITE
   ProtectSystem=strict
   ReadWritePaths=/home/gg_non_root/greengrass /tmp
   
   [Install]
   WantedBy=multi-user.target
   ```

   有关所需功能的信息，请参阅[所需的 Linux 功能 AWS IoT Greengrass V2](#linux-capabilities-reference)。
   + `AmbientCapabilities`向运行该服务的非 root 用户授予指定的 Linux 功能。这允许 AWS IoT Greengrass 核心软件执行特权操作，例如在运行组件时切换用户，而无需以 root 身份运行。
   + `CapabilityBoundingSet`限制了服务及其子进程可以使用的最大功能集。此套装中没有的能力将被永久丢弃。
   + `ProtectSystem=strict`使整个文件系统成为该服务的只读状态，从而防止修改操作系统。
   + `ReadWritePaths`指定服务可以写入的唯一目录。

1. 停止正在运行的 AWS IoT Greengrass Core 实例，然后启用并启动系统服务。

   ```
   sudo systemctl daemon-reload
   sudo systemctl enable greengrass.service
   sudo systemctl start greengrass.service
   ```

**重启和 OTA 更新行为**  
在这个解决方案中：
+  AWS IoT Greengrass Core 软件作为系统服务运行，并在出现故障或设备重启时自动重启。
+  AWS IoT Greengrass Core 软件的 OTA 更新可以正常工作。该服务将以配置的非 root 用户身份自动重启。

**系统资源限制**  
在此解决方案中，内存和 CPU 的每个组件的资源限制与以 root 身份运行 AWS IoT Greengrass 核心软件时的方式相同。

## 解决方案 4：设置 AWS IoT Greengrass V2 为权限有限的 root 用户
<a name="non-root-solution-4"></a>

如果您想让 AWS IoT Greengrass Core 软件以 root 用户身份运行，但只有 Linux 功能较少，请使用此解决方案。此配置提供了以 root 用户身份运行的全部功能，同时通过限制软件及其组件的可用功能来限制攻击面。

**权衡**  
此解决方案有以下注意事项：
+ ** RequiresPrivilege 具有有限功能**的组件 — 使用的组件使用与 C AWS IoT Greengrass ore 软件相同的有限功能集`RequiresPrivilege`运行，而不是完全的 root 权限。

**先决条件**  
此解决方案需要：
+ 根访问权限
+ 您的设备上有 systemd

**在功能有限的情况下以 root 用户 AWS IoT Greengrass V2 身份安装和运行**

1. 完成以下步骤[安装具有自动资源配置功能的 AWS IoT Greengrass Core 软件](quick-installation.md)：设置您的设备环境、提供凭据并下载 AWS IoT Greengrass 核心软件。

1. 在`GreengrassInstaller/bin/greengrass.service.template`您下载 AWS IoT Greengrass 核心软件的目录中修改服务模板文件。在运行安装程序之前，请将以下几行添加到该`[Service]`部分：

   ```
   CapabilityBoundingSet=CAP_CHOWN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_FOWNER CAP_SETUID CAP_SETGID CAP_SYS_RESOURCE CAP_AUDIT_WRITE
   ProtectSystem=strict
   ReadWritePaths=/greengrass /tmp
   ```
   + `CapabilityBoundingSet`是一项 systemd 安全功能，它限制了 AWS IoT Greengrass Core 软件及其所有子进程可用的 Linux 功能。通过配置边界集，您可以限制 Greengrass nucleus 进程和组件可以做什么，即使以 root 身份运行也是如此。有关每项功能的信息，请参见[所需的 Linux 功能 AWS IoT Greengrass V2](#linux-capabilities-reference)。
   + `ProtectSystem=strict`使整个文件系统成为该服务的只读状态，从而防止修改操作系统。这提供了 systemd 沙箱，即使恶意组件以提升的权限运行，也可以保护系统文件。
   + `ReadWritePaths`指定服务可以写入的唯一目录。同时`ProtectSystem=strict`，这限制了服务只能写入 AWS IoT Greengrass V2 根目录和`/tmp`。

1. 使用运行安装程序`--setup-system-service true`。

   ```
   sudo -E java -Droot="/greengrass/v2" -Dlog.store=FILE \
     -jar ./GreengrassInstaller/lib/Greengrass.jar \
     --aws-region region \
     --thing-name MyGreengrassCore \
     --thing-group-name MyGreengrassCoreGroup \
     --thing-policy-name GreengrassV2IoTThingPolicy \
     --tes-role-name GreengrassV2TokenExchangeRole \
     --tes-role-alias-name GreengrassCoreTokenExchangeRoleAlias \
     --component-default-user ggc_user:ggc_group \
     --provision true \
     --setup-system-service true
   ```

**重启和 OTA 更新行为**  
在这个解决方案中：
+  AWS IoT Greengrass Core 软件作为系统服务运行，并在出现故障或设备重启时自动重启。
+  AWS IoT Greengrass Core 软件的 OTA 更新可以正常工作。软件会自动更新和重启。

**系统资源限制**  
在此解决方案中，内存和 CPU 的每个组件的资源限制与以 root 身份运行 AWS IoT Greengrass 核心软件时的方式相同。

## 所需的 Linux 功能 AWS IoT Greengrass V2
<a name="linux-capabilities-reference"></a>

下表描述了 AWS IoT Greengrass 核心软件在非 root 配置下运行时所需的 Linux 功能。解决方案 3 和 4 中使用了这些功能。


**所需的 Linux 功能**  

| 能力 | 说明 | 必填项 | 
| --- | --- | --- | 
| `CAP_CHOWN` | 对文件进行任意更改 UIDs 和 GIDs | 根据执行组件的用户更改文件所有权 | 
| `CAP_DAC_OVERRIDE` | 绕过文件读取、写入和执行权限检查 | 允许 Greengrass nucleus 用户在使用以下脚本时执行文件 `RequiresPrivilege` | 
| `CAP_DAC_READ_SEARCH` | 绕过文件读取权限检查和目录读取并执行权限检查 | 即使是文件夹，Greengrass nucleus 用户也没有读取权限，也可以在文件夹层次结构中移动 | 
| `CAP_FOWNER` | 绕过对通常要求进程的文件系统 UID 与文件的 UID 匹配的操作的权限检查 | 绕过文件所有权检查 | 
| `CAP_SETUID` | 对流程进行任意操纵 UIDs | `sudo`在以与运行 Greengrass 核心的用户不同的用户身份执行脚本时使用 | 
| `CAP_SETGID` | 对流程进行任意操纵 GIDs | `sudo`在以与运行 Greengrass 核心的组不同的组执行脚本时使用 | 
| `CAP_SYS_RESOURCE` | 覆盖资源限制 | 即使在部署中未指定资源限制，也要为组件进程设置资源限制 | 
| `CAP_AUDIT_WRITE` | 将记录写入内核审计日志 | `sudo`允许写入内核审核日志 | 