# 安全特性
- [安全特性](#安全特性.md)
    - [seccomp安全配置场景](#seccomp安全配置场景)
    - [capabilities安全配置场景](#capabilities安全配置场景)
    - [SELinux安全配置场景](#selinux安全配置场景)

## seccomp安全配置场景

### 场景说明

seccomp（**secure computing** **mode**）是linux kernel从2.6.23版本开始引入的一种简洁的sandboxing机制。在一些特定场景下，用户需要在容器中执行一些“特权”操作，但又不想启动特权容器，用户经常会在run时添加--cap-add来获得一些“小范围”的权限。对于安全要求比较严格的容器实例，上述的CAP粒度不一定能够满足安全需要，可使用一些办法精细化控制权限范围。

-   举例

    普通容器场景中，用户使用-v将宿主机某目录（包含某普通用户无法执行的二进制），映射到容器中。

    在容器中，可以将二进制修改权限chmod 4777加入S标志位。这样在宿主机上，原先不能运行二进制的普通用户（或者运行此二进制受限），可以在S标志位的添加动作后，在运行此二进制的时候，获取到二进制自身的权限（比如root），从而提权运行或者访问其他文件。

    这个场景，如果在严格安全要求下，需要使用seccomp裁剪chmod、fchmod、fchmodat系统调用。


### 使用限制

-   seccomp可能会影响性能，设置seccomp之前需要对场景进行评估，确定必要时加入seccomp配置。

### 使用指导

通过--security-opt将配置文件传给要过滤系统调用的容器。

```
isula run -itd --security-opt seccomp=/path/to/seccomp/profile.json rnd-dockerhub.huawei.com/official/busybox
```

>![](public_sys-resources/icon-note.gif) **说明：**   
>1.  创建容器时通过--security-opt将配置文件传给容器时，采用默认配置文件（/etc/isulad/seccomp\_default.json）。  
>2.  创建容器时--security-opt设置为unconfined时，对容器不过滤系统调用。  
>3.  “/path/to/seccomp/profile.json”需要是绝对路径。  

#### 获取普通容器的默认seccomp配置<a name="zh-cn_topic_0183112366_section16304185318140"></a>

-   启动一个普通容器（或者是带--cap-add的容器），并查看默认权限配置：

    ```
    cat /etc/isulad/seccomp_default.json | python -m json.tool > profile.json
    ```

    可以看到"seccomp"字段中，有很多的"syscalls"，在此基础上，仅提取syscalls的部分，参考定制seccomp配置文件，进行定制化操作。

    ```
    "defaultAction": "SCMP_ACT_ERRNO",
    "syscalls": [
    {
    "action": "SCMP_ACT_ALLOW",
    "name": "accept"
    },
    {
    "action": "SCMP_ACT_ALLOW",
    "name": "accept4"
    },
    {
    "action": "SCMP_ACT_ALLOW",
    "name": "access"
    },
    {
    "action": "SCMP_ACT_ALLOW",
    "name": "alarm"
    },
    {
    "action": "SCMP_ACT_ALLOW",
    "name": "bind"
    },
    ]...
    ```


-   查看转换为lxc可识别的seccomp配置

    ```
    cat /var/lib/isulad/engines/lcr/74353e38021c29314188e29ba8c1830a4677ffe5c4decda77a1e0853ec8197cd/seccomp
    ```

    ```
    ...
    waitpid allow
    write allow
    writev allow
    ptrace allow
    personality allow [0,0,SCMP_CMP_EQ,0]
    personality allow [0,8,SCMP_CMP_EQ,0]
    personality allow [0,131072,SCMP_CMP_EQ,0]
    personality allow [0,131080,SCMP_CMP_EQ,0]
    personality allow [0,4294967295,SCMP_CMP_EQ,0]
    ...
    ```


#### 定制seccomp配置文件<a name="zh-cn_topic_0183112366_section1684042215"></a>

在启动容器的时候使用--security-opt引入seccomp配置文件，容器实例会按照配置文件规则进行限制系统API的运行。首先获取普通容器的默认seccomp，得到完整模板，然后按照本节定制配置文件，启动容器：

```
isula run --rm -it --security-opt seccomp:/path/to/seccomp/profile.json rnd-dockerhub.huawei.com/official/busybox
```

配置文件模板：

```
{
"defaultAction": "SCMP_ACT_ALLOW",
"syscalls": [
{
"name": "syscall-name",
"action": "SCMP_ACT_ERRNO",
"args": null
}
]
}
```

>![](public_sys-resources/icon-notice.gif) **须知：**   
>-   defaultAction、syscalls：对应的action的类型是一样的，但其值是不能一样的，目的就是让所有的syscal都有一个默认的action，并且如果syscalls数组中有明确的定义，就以syscalls中的为准，由于defaultAction、action的值不一样，就能保证action不会有冲突。当前支持的action有：  
>    "SCMP\_ACT\_ERRNO"：禁止，并打印错误信息。  
>    "SCMP\_ACT\_ALLOW"：允许。  
>-   syscalls： 数组，可以只有一个syscall，也可以有多个，可以带args，也可以不带。  
>-   name：要过滤的syscall。  
>-   args：数组，里面的每个object的定义如下：  
>    ```  
>    type Arg struct {  
>    Index    uint     `json:"index"`     //参数的序号，如open(fd, buf, len),fd 对应的就是0，buf为1  
>    Value    uint64   `json:"value"`     //跟参数进行比较的值  
>    ValueTwo uint64   `json:"value_two"` //仅当Op=MaskEqualTo时起作用，用户传入值跟Value按位与操作后，跟ValueTwo进行比较，若相等则执行action。  
>    Op       Operator `json:"op"`  
>    }  
>    ```  
>    args中的Op，其取值可以下页面的任意一种：  
>    "SCMP\_CMP\_NE":  NotEqualTo  
>    "SCMP\_CMP\_LT":  LessThan  
>    "SCMP\_CMP\_LE":  LessThanOrEqualTo  
>    "SCMP\_CMP\_EQ":  EqualTo  
>    "SCMP\_CMP\_GE":  GreaterThanOrEqualTo  
>    "SCMP\_CMP\_GT":  GreaterThan  
>    "SCMP\_CMP\_MASKED\_EQ": MaskEqualTo  

## capabilities安全配置场景

### 场景说明

capabilities机制是linux kernel 2.2之后引入的安全特性，用更小的粒度控制超级管理员权限,可以避免使用 root 权限，将root用户的权限细分为不同的领域，可以分别启用或禁用。capabilities详细信息可通过Linux Programmer's Manual进行查看（[capabilities\(7\) - Linux man page](http://man7.org/linux/man-pages/man7/capabilities.7.html)）：

```
man capabilities
```

### 使用限制

-   isulad默认Capabilities（白名单）配置如下，普通容器进程将默认携带：

    ```
    "CAP_CHOWN",
    "CAP_DAC_OVERRIDE",
    "CAP_FSETID",
    "CAP_FOWNER",
    "CAP_MKNOD",
    "CAP_NET_RAW",
    "CAP_SETGID",
    "CAP_SETUID",
    "CAP_SETFCAP",
    "CAP_SETPCAP",
    "CAP_NET_BIND_SERVICE",
    "CAP_SYS_CHROOT",
    "CAP_KILL",
    "CAP_AUDIT_WRITE"
    ```

-   默认的权能配置，包含了CAP\_SETUID和CAP\_FSETID，如host和容器共享目录，容器可对共享目录的二进制文件进行文件权限设置，host上的普通用户可能使用该特性进行提权攻击。CAP\_AUDIT\_WRITE，容器可以对host写入，存在一定的风险，如果使用场景不需要，推荐在启动容器的时候使用--cap-drop将其删除。
-   增加Capabilities意味着容器进程具备更大的能力，同时也会开放更多的系统调用接口。

### 使用指导

iSulad使用--cap-add/--cap-drop给容器增加/删去特定的权限，在非必要情况下，不要给容器增加额外的权限，推荐将容器默认但非必要的权限也去掉。

```
isula run --rm -it --cap-add all --cap-drop SYS_ADMIN rnd-dockerhub.huawei.com/official/busybox
```

## SELinux安全配置场景

### 场景说明

SELinux\(Security-Enhanced Linux\)是一个Linux内核的安全模块，提供了访问控制安全策略机制，iSulad将采用MCS（多级分类安全）实现对容器内进程打上标签限制容器访问资源的方式，减少提权攻击的风险，防止造成更为重要的危害。

### 使用限制

-   确保宿主机已使能SELinux，且daemon端已打开SELinux使能开发（/etc/isulad/daemon.json中“selinux-enabled”字段为true, 或者命令行参数添加--selinux-enabled）
-   确保宿主机上已配置合适的selinux策略，推荐使用container-selinux进行配置
-   引入SELinux会影响性能，设置SELinux之前需要对场景进行评估，确定必要时打开daemon端SELinux开关并设置容器SELinux配置
-   对挂载卷进行标签配置时，源目录不允许为/、/usr、/etc、/tmp、/home、/run、/var、/root以及/usr的子目录。

>![](public_sys-resources/icon-note.gif) **说明：**   
>-   目前iSulad不支持对容器的文件系统打标签，确保容器文件系统及配置目录打上容器可访问标签，需使用chcon命令对其打上标签。  
>-   若iSulad启用SELinux访问控制，建议daemon启动前对/var/lib/isulad目录打上标签，容器容器创建时目录下生产的文件及文件夹将默认继承其标签，例如：  
>    ```  
>    chcon -R system_u:object_r:container_file_t:s0 /var/lib/isulad  
>    ```  

### 使用指导

-   daemon端使能selinux：

    ```
    isulad --selinux-enabled
    ```


  

-   启动容器时配置selinux标签安全上下文

    --security-opt="label=user:USER" 配置安全上下文用户

    --security-opt="label=role:ROLE" 配置安全上下文角色

    --security-opt="label=type:TYPE" 配置安全上下文类型

    --security-opt="label=level:LEVEL" 配置安全上下文域

    --security-opt="label=disable" 容器禁用SELinux配置

    ```
    $ isula run -itd --security-opt label=type:container_t --security-opt label=level:s0:c1,c2 rnd-dockerhub.huawei.com/official/centos
    9be82878a67e36c826b67f5c7261c881ff926a352f92998b654bc8e1c6eec370
    ```


  

-   为挂载卷打selinux标签\('z'为共享模式\)

    ```
    $ isula run -itd -v /test:/test:z rnd-dockerhub.huawei.com/official/centos
    9be82878a67e36c826b67f5c7261c881ff926a352f92998b654bc8e1c6eec370
    
    $ls -Z /test
    system_u:object_r:container_file_t:s0 file
    ```

      


