社区最佳实践:基于PaX/Grsecurity & STIG & Sheild针对es的Docker场景化加固

By: 炼石网络CipherGateway

Hardening es(in docker) with PaX/Grsecurity & STIG & Shield

文档说明

基础平台:此实践文档使用PaX/Grsecurity完成Linux内核级别的加固,并采用美国DISA组织的STIG脚本对Debian GNU/Linux发行版进行安全扫描,以使Debian GNU/Linux发行版安全达到一定的高度。

业务方面:以在Docker下运行的ElasticSearc服务为例,结合ES的Shield插件对ES进行业务级别的加固。

基本步骤如下:

1、最小化安装Debian8 GNU/Linux

2、使用PaX/Grsecurity加固

3、使用STIG验证

4、使用Shield对ElasticSearch进行业务级别的加固

5、完善物理机RBAC系统,达到最小权限要求


1、最小化安装Debian8 GNU/Linux系统

1)在服务器上插入U盘,连接好网线,配置网络:

2)为硬盘分区:

3)软件环境安装:

4)系统安装完成:

加固前准备

1)在root下打开/etc/apt/sources.list,确定是否有以下三个debian的源,若没有自行添加,并且注释或删掉其他的软件源,尽量避免使用非社区源:

nano /etc/apt/sources.list
deb http://ftp.debian.org/debian jessie main contrib
deb http://security.debian.org/jessie/updates main contrib
deb http://ftp.debian.org/debian jessie-updates main contrib

apt-get update

2)安装sudo

apt-get install sudo

修改sudoers文件,添加一句(等效于添加当前用户到sudo用户组,或者直接使用root用户可忽略此步):

 nano /etc/sudoers
 add "user   ALL=(ALL:ALL)ALL"

3)安装make

sudo apt-get install make

2、使用PaX/Grsecurity加固

这次加固主要用到的是一个增强内核安全的工具Grsecurity,和SELinux以及Apparmor一样,是用来控制文件访问权限的安全工具。

1)Grsecurity需要打包到内核,所以需要重新编译内核,由于grsec长期支持的内核版本是3.14.48,而debian8的内核版本是3.16,所以我们要将内核版本降到3.14.48,查看内核版本命令:

cat /proc/version

2)到kernel.org下载相应的目标内核版本源代码:

 wget https://kernel.org/pub/linux/kernel/v3.x/linux-3.14.48.tar.xz

3)到Grsecurity下载相应的patch,注意必须要和内核版本一致(先到http://grsecurity.net/download.php查看“grsecurity - stable kernel patch”和“paxctld - PaX flags maintenance daemon - binary packages”的版本):

 wget http://grsecurity.net/stable/grsecurity-3.1-3.14.48-201507261203.patch
 wget http://grsecurity.net/paxctld/paxctld_1.0-2_amd64.deb

4)编译前安装支持插件的gcc:

 apt-get install libncurses* kernel-package build-essential
 gcc --version
 apt-get install gcc-`gcc --version`-plugin-dev(gcc --version用大版本即可 例如4.9而不是4.9.2)

5)解压缩内核包和补丁包,给内核打patch:

xz -d linux-3.14.48.tar.xz
tar -xvf linux-3.14.48.tar
cd linux-3.14.48/
patch -p1 < ../grsecurity-3.1-3.14.48-201507261203.patch

6)配置内核:

make menuconfig

开始配置Grsecurity选项

Note:该文档的配置选项仅测试在Debian8 GNU/Linux中。(业务:启动docker,并在其中运行ElasticSearch服务)

关于Grsecurity具体的配置选项请参照:https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options

7)开启Grsecurity支持

执行命令后会出现配置窗口:

在配置界面按下键盘选择"security options"

security options --> Grsecurity

按空格选上Grsecurity(NEW)

8)选择automatic后Grsecurity将自动根据通用标准形成一系列配置,但仍可在 Customer Configuration中进行更细致的加固措施的划分,二者效果会叠加。

Configuration Method -->选择 automatic

9)优先选项选择Security优先

Required Priority-->Security

10)去掉mprotect限制。因为Grsecurity默认禁止mprotect功能,而这会使JVM无法运行

Security Options -->Grsecurity -->customize configuration -->PAX -->Nonexcutable pages-->disable  restrict mprotect

11)为了docker能正常运行,去掉chroot下’chmod+s’和’mknod’的限制

Security Options -->Grsecurity -->customize configuration -->FileSystem Protections-->Deny (f)chmod +s && Deny mknod

12)去除USB限制(看业务需求)

Security Options -->Grsecurity -->customize configuration -->Physical Protections-->Deny new USB connections after toggle

13)其余选项保持默认,Save之后退出内核配置窗口。

14)完成之后执行编译内核命令,这一步需要较长时间

make deb-pkg -j'cpu核心数+1' 

15)编译之后安装:

cd ..
dpkg -i linux*.deb 
dpkg -i paxctld_1.0-2_amd64.deb

16)安装完成重启即可,重启时选择新内核

paxctld -d
sudo reboot

在启动界面选择高级选项

选择已加固的内核

17) 重启之后

su - root
paxctld -d
exit

18)安装gradm工具

这是RBAC系统的管理工具,使用它可以配置/etc/policy规则文件来定义每个用户的权限,也可通过gradm的学习模式来自动生成policy文件。

Note:安装gradm之前必须保证在已有Grsecurity加固的内核上,并且系统有(lex或flex)和(byacc或bison)

下载相应的组件:

apt-get install flex
apt-get install bison

下载gradm:(或者到Grsecurity官网下载最新版)

wget http://grsecurity.net/stable/gradm-3.1-201507191652.tar.gz

开始安装:

tar zxvf gradm-3.1-201507191652.tar.gz
cd gradm
make nopam (无PAM支持)
sudo make install

安装结束后,要求输入gradm的管理密码,注意不要与root密码相同,否则降低了Grsecurity的安全防护。 另外,将会在/sbin下安装gradm和grlearn程序。并在/etc/grsec目录下生成learn_config和policy两个文件。

关于使用gradm对系统权限进行细分将在下面提及。

19) 卸载旧内核(Note:dpkg确定内核版本号,remove掉相应的内核deb包,请替换后再执行命令)

dpkg -l | grep linux-headers(若没有3.16的headers则可略去下面的apt-get remove linux-headers-'')
dpkg -l | grep linux-image
sudo apt-get remove linux-headers-'' linux-image-''(注意:这一步使用前两个命令得到的信息替换''里的内容)

此时再重启计算机会发现现在只有Linux 3.14.48-grsec的内核了。

20) 卸载编译工具链

sudo apt-get remove kernel-package build-essential
sudo apt-get remove libncursesada-dbg  libncursesada3-dev libncursesada-doc libncurses5-dbg libncurses5-dev libncursesw5-dbg  libncurses-gst libncursesw5-dev libncursesada3
sudo apt-get autoremove

至此Grsecurity的第一步加固完成。若以后在系统运行时需要修改某些特性,可在/etc/sysctl.conf中对相应的条目进行修改。具体条目对应的选项请参看https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options


3、使用STIG验证

STIG(安全技术实现指南)是由DISA为了IT安全态势给DoD(美国国防部)提供的一套防御指南。

NOTE:STIG是一组庞大的集合,且针对OS的部分官方只针对RHEL。这里的STIG指的是h4rdenedzer0(http://hardenedlinux.org/about/) 的stig-4-debian项目

1) 将github中STIG的脚本文件克隆到本地:

git clone https://github.com/hardenedlinux/STIG-4-Debian.git
cd STIG-4-Debian

2) 使用方法

usage: check.sh [options]

  -c    Output Log with catable colors
  -s    Perform STIG checking with NORMAL output log
  -v    Show version
  -h    Show this message

3) 执行脚本

sudo ./check.sh -s

4) 脚本对内核执行完毕后我们可以看到在/var/log下生成了一个100K左右名为STIG-Checking-2015-??-??.log的日志,即为STIG对内核进行安全扫描的结果。

其中,日志中为FAIL的条目表示未达到STIG安全标准的项目,PASS的项目为通过STIG验证的项目。我们接下来要做的工作就是通过修改内核选项尽可能地使所有FAIL的条目变成PASS。

5)示例:

在上图中可看到一个FAIL的条目是”The /etc/shadow file must be group-owned by root”,Vulnerability是该条目的漏洞分析,Fix text是解决方法。

为了解决该问题,执行Fix text中提示的命令:

chgrp root /etc/shadow

修改后:

可以看到,按Fix text修改后该条目通过STIG验证。

6)STIG总结

STIG是由DISA为了IT安全态势给美国国防部提供的一套安全指南,据说DoD的应用在上线前都会使用这个指南进行安全强化。在日志内容上看来也的确有不少值得借鉴之处。

综上,尽可能把其余的FAIL条目按照STIG标准进行修改达到PASS,使系统安全到达更高一个层次。


以上即为Linux内核加固的实践内容。接下来是结合ElasticSearch进行业务层面的加固,具体部分包括:

  • 在docker下运行ES,并使用Shield对ES进行加固————安全认证及RBAC系统

  • 在物理机上配置RBAC系统,达到系统最小权限————主要为gradm工具的使用

4、使用Shield对ElasticSearch进行业务级别的加固

介绍Shield

Shield是一个为了使ElasticSearch更安全而产生的一个插件。在Shield的安全加固中包括安全认证机制,RBAC系统,IP过滤和系统审计。

下面的加固将通过配置安全认证机制和RBAC系统来演示加固流程。

### 配置ElasticSearch

1) 安装docker

    apt-get install curl
    curl -sSL https://get.docker.com | sh

验证docker是否安装成功:`$ docker`

2)启动docker

    sudo service docker start

安装Shield

1) 安装需求:

  • 安装了Java7或更新版本
  • Shield plugin必须在集群的每个节点都安装,并且每个节点安装完后都要重启。

2) 启动ES的每个节点:(oaDataNode1等是自定义的节点名称)

sudo service docker start
sudo weave launch
sudo weave start 10.0.0.1/24 oaDataNode1
sudo weave start 10.0.0.2/24 oaDataNode2
sudo weave start 10.0.0.3/24 oaDataNode3
sudo weave start 10.0.0.4/24 oaDataNode4
sudo weave expose 10.0.0.254/24

3) 首先进入Docker:

sudo docker exec -it oaDataNode1 /bin/bash

4) 进入ES的安装目录下:

cd /usr/es/elasticsearch-1.7.0/bin

5) 安装ElasticSearch许可插件和Shield插件::

./plugin -i elasticsearch/license/latest
./plugin -i elasticsearch/shield/latest

6)重启ElasticSearch服务

sudo weave stop
sudo docker stop oaDataNode2 oaDataNode1 oaDataNode3 oaDataNode4
sudo weave launch
sudo weave start 10.0.0.1/24 oaDataNode1
sudo weave start 10.0.0.2/24 oaDataNode2
sudo weave start 10.0.0.3/24 oaDataNode3
sudo weave start 10.0.0.4/24 oaDataNode4
sudo weave expose 10.0.0.254/24

安全认证模块

1) 新建一个ElasticSearch管理员账户

./esusers useradd es_admin -r admin(新建一个名为es_admin的用户,角色为admin)

现在可以尝试着用RESTFUL API来访问ElasticSearch,会发现访问被拒绝

curl -XGET 'http://localhost:9200/'

在请求上加上用户名和密码即可:

curl -u es_admin -XGET 'http://localhost:9200/'

由此可知,使用Shield新建ES账户后,可以为ES添加严格个安全认证机制。

RBAC模块

知识准备

Shield实现了RBAC权限管理系统。在RBAC系统下,所有的行为都会被默认限制,所有用户的权限都与“角色”联系在一起,而每个“角色”代表了一组允许的行为。

1)Roles, Permissions and Privileges的概念
  • Privileges:代表一组用户在ElasticSearch中允许执行的行为。例如:是否能运行query就是一种Privileges。

  • Permissions:一组结合一个或多个“安全对象(Secured Object)”的Privileges。

在ElasticSearch中有两种Secured Object:

Cluster:Cluster permissions提供了集群范围内的管理、侦听权限。

Index:Index permissions提供了数据通道,包括在集群中特定索引的管理和侦听。

  • roles:一组命名的Permission的组合。例如:你可以定义一个“日志管理员”的role,他允许对名字为“logs-*”的索引做任何操作,但对其他文件却没有任何权限。

Note:作为ES的管理员,你需要定义一些角色,并将每个用户分配到这些角色上。

2) 定义roles

Roles在ES_HOME/config/shield中的roles.yml文件中定义,其中的每个条目都定义了唯一一个role和相应的permission。

Note:roles.yml文件在每个节点中独立管理。所以在拥有多个节点的集群中,所有节点的该文件都需要修改。

roles.yml文件的格式如下:

# All cluster rights
# All operations on all indices
admin:
  cluster: all
  indices:
    '*': all

# Monitoring cluster privileges
# All operations on all indices
power_user:
  cluster: monitor
  indices:
    '*': all

# Only read operations on indices named events_*
events_user:
  indices:
    'events_*': read

具体的Privileges请参见:https://www.elastic.co/guide/en/shield/current/reference.html#ref-actions-list

3) 使用esusers工具管理用户

esusers工具主要控制在ES_HOME/config/shield/的两个文件————users和users_roles。这两个文件存储着所有esuser域的信息,并且会在ES启动时被shield读取。

Note:roles.yml文件在每个节点中独立管理。所以在拥有多个节点的集群中,所有节点的该文件都需要修改。

  • users文件:

users文件储存着所有用户和他们的密码。每个条目是每个用户的名字和密码的hash值。

  • users_roles文件:

users_roles存储的是每个用户相联系的roles

A、添加用户
esusers useradd <username>
esusers useradd <username> -r <comma-separated list of role names> 使用-r参数定义用户的roles,roles间用逗号隔开

ES在启动时会读取用户和角色信息,应该使用开启ES的用户使用useradd添加用户。

B、打印用户信息
esusers list
esusers list <username> 这个命令打印指定用户信息
C、修改用户密码
esusers passwd <username>
D、分配用户角色
esusers roles <username> -a <roles> -r <roles>
-a指定添加,-r指定移除
E、删除用户
esusers userdel <username>

RBAC加固实践

1) 修改roles.yml文件

cd /usr/es/elasticsearch-1.7.0/config/shield
vim roles.yml

在文件的末尾加入如下内容:

Data_user: #Data_user 角色定义
  indices:  #index部分
    '*': crub  #指定Data_user可以读写所有indices

Server_user:  #Serve_user 角色定义
  cluster: cluster:admin/nodes/restart, cluster:admin/nodes/shutdown

2) 添加两个用户user_Data和user_Server

esusers useradd user_data -r Data_user
esusers useradd user_server -r Server_user

这时,用不同的用户登陆ES将可以进行不同的操作:

  • user_data:读写ES的所有文件

  • user_server:启动或关闭ES服务

5、完善物理机RBAC系统,达到最小权限要求

知识准备

之前讲解了ElasticSearch上的RBAC系统的配置。在Grsecurity中也提供了RBAC权限控制系统,而且比ES中的划分更细致更严格。

管理物理机中的系统主要依靠gradm工具。使用gradm --help获得gradm的用法:

# gradm --help
gradm 3.1
grsecurity RBAC administration and policy analysis utility

Usage: gradm [option] ... 

Examples:
        gradm -P
        gradm -F -L /etc/grsec/learning.logs -O /etc/grsec/policy
Options:
        -E, --enable    Enable the grsecurity RBAC system
        -D, --disable   Disable the grsecurity RBAC system
        ...

/etc/grsec/policy文件是RBAC系统的核心。在RBAC启动后,它会根据该文件中所写定的策略对系统进行严格的访问控制。

policy中的三个概念role, subject, object

同Shield的RBAC相似,Grsecurity的RBAC也具有三个关于角色和权限的概念。

  • role(角色):如“role admin sA“,“role default ”,”role root uG“,表明有三个角色,分别是admin , default, root

Roles: Users and groups on the system 在policy中声明即可以定义角色,语法为”role < role name> < parameter>

grsecurity中的角色分为用户角色,组角色,缺省角色(default),还有个管理员角色。定义不同角色需要有不同的参数。

NOTE:grsecurity的角色与用户是一对一的。假设有tester用户,属于test组,那么tester用户登录后,会先在policy文件中匹配名为tester用户角色,如果没有,就会去匹配叫test的组角色,如果还没有,那么tester用户进入系统后的角色会是default(default角色在配置文件里面定义)。

也就是说,tester用户登录后,不是tester用户角色,就是test组角色,要么就是default缺省角色,不可能进入其他policy中定义的角色。

  • subject(程序),每个subject中首先定义了一个可执行程序(注意,一个subject中只定义一个可执行程序,要对多个可执行程序进行定义的话,就需要多个subject),或者更准确一点,定义了一个运行在系统中的进程。然后后面跟着一系列的object,用来规定当前这个进程的权限。每个角色定义的后面都可以跟一个或多个subject

Subjects: Processes and directories 参数:

h 这个进程是隐藏的,只能够被具有v模式的进程看到; v 具有这个模式的进程拥有察看隐藏进程的能力; p 进程是受保护的,这种模式的进程只能被具有k模式的进程杀死; k 具有这个模式的进程可以杀死处于保护模式(p)的进程; l 为这个进程打开学习模式; o 撤销ACL继承

  • object(对象):每个subject中都会有若干的object,表示每个进程都有若干个操作对象,这些操作对象一般来说都是一些目录,文件等等,用来规定当前这个subject中的进程对这些文件拥有哪些权限

Objects: Files and PaX flags 参数:

r 这个对象可以打开阅读; w 这个对象可以打开写或者添加; o 这个对象可以打开添加; h 这个对象是隐藏的; i 这个模式只用于二进制可执行文件。当这个对象被执行时,它继承所在主体进程的访问控制列表; x: 这个模式代表文件可执行

NOTE:配置文件中关于subject和object的所有路径都必须是绝对路径

例:

role root uG
subject /
subject /usr/bin/ssh
/etc/ssh/ssh_config r
表示/usr/bin/ssh这个进程对/etc/ssh/ssh_config这个文件有读权限(r)。更进一步讲,这个subject位于角色root后面,所以这两行策略的含义就是以root角色运行ssh时,ssh进程对/etc/ssh/ssh_config有读权限。该策略只定义在了root角色中,对于其他角色不起作用。

缺省ACL

注意:在每一个角色中,都必须有一个subject /,表示一个缺省的ACL,如果没有这个缺省的ACL,grsecurity启动时会报错同时启动失败。当以一个角色登录系统后,如果要执行的可执行程序没有被某个subject定义,那么,该程序就会采用subject /中的缺省定义。例如root角色,没有对cat命令进行定义,所以以root角色执行cat命令时,ACL系统就会参照subject /中的定义来控制cat进程对文件的访问。

部署RBAC系统

Grsecurity的policy文件极其繁大复杂,通过手工几乎不可能完成一个具有安全效力的规则文件。所幸Grsecurity为RBAC系统提供了学习机制,即可以通过你在学习机制下进行的操作自动配置policy文件。

Grsecurity的学习模式分为全系统学习模式跟基于角色的学习模式,在这里我们使用全系统学习模式:

1) 开启全系统学习模式

sudo gradm -F -L /etc/grsec/learning.logs

如图所示,RBAC学习模式开启成功。

从现在开始,gradm将记录下你的一切操作。

NOTE:初次启动时RBAC可能会报出一些ERROR,原因是默认的policy文件没有配置完全:如图,该ERROR为未给shutdown用户设置密码。按照提示执行gradm -P shutdown并设置密码即可。

2) 进行一些系统运行时正常的必要的操作,并重复至少4遍,以使gradm将操作记录下来

NOTE:不要在学习模式下进行进行管理员操作,如果需要此类操作,先切换到RBAC管理员角色:

gradm -a admin

在高危操作结束后,记得从管理员角色退出:gradm -u

3) 以针对ElasticSearch业务的加固为例,对RBAC进行配置:

业务分析:

  • 在docker中的ES内设置两个用户,一个只允许对其中数据进行读写操作,一个只允许在docker内部重启ES服务;这一步已在前文Shield的加固中实现。

  • 在docker外设置一个本地用户,其除了拥有对本地系统的管理权限之外,还应对运行着ES业务的docker拥有启停等操作的权限;但不应拥有进入docker内部的权限。

在全系统学习模式下,对普通用户执行如下命令:

启动docker:
sudo service docker start
sudo weave launch
sudo weave start 10.0.0.1/24 oaDataNode1
sudo weave start 10.0.0.2/24 oaDataNode2
sudo weave start 10.0.0.3/24 oaDataNode3
sudo weave start 10.0.0.4/24 oaDataNode4
sudo weave expose 10.0.0.254/24

关闭docker:
sudo weave stop
sudo docker stop oaDataNode2 oaDataNode1 oaDataNode3 oaDataNode4

重复执行至少4遍。

4)关闭RBAC

gradm -D

这一步是必要的,因为它强制将学习模式的缓存写入磁盘。如果没有关闭gradm就生成policy,可能会导致学习记录的丢失。

此时查看learning.logs会看见里面有很多命令。

4) 生成policy文件

gradm -F -L /etc/grsec/learning.logs -O /etc/grsec/policy

NOTE:执行该命令前应该确保学习模式已经记录了足够多安全的操作,否则再次启动RBAC时将导致无法管理系统。

结语

该文档通过使用Grsecurity和Shield对系统及ES进行了一系列的加固,虽然所做的所有措施只针对与ES有关的业务,但也能大体描绘出一个最小权限系统加固的轮廓。在其他不同的环境下依然能够按照这个思路对系统进行安全加固。

Grsecurity和Shield都是无比强大的加固武器,通过STIG检测的系统更是拥有更高的安全性。文档只是粗勒地描绘出一套加固思路,更多安全措施请参考Grsecurity和Shield的官方文档。

TODO

  • 内核调参数,主要针对TCP/IP性能(针对DoS)和安全的一系列参数需要调整,场景化的情况下根据一款具体的硬件配置来进行调参。

  • Iptables/netfilter规则,这个可以根据具体的业务场景来定制。

  • (重点)安装部署的一个STIG-compliance的系统,效果是在安装步骤完成后,stig-4-debian自动扫描出的结果应该全部或者大部分通过。

  • PaX/Grsec的config可以细化,这个未来我们会把针对不同场景的config归档。

  • Grsec的RBAC规则使用learning mode只是把规则抓出来,和AppArmor的aa-genprof/aa-logprof类似,加固的原则是针对的RBAC/MAC规则都必须经过review,这一步工作也需要加强。

Reference

1) Grsecurity官方文档:https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options#Address_Space_Layout_Randomization

2) gradm官方文档:https://en.wikibooks.org/wiki/Grsecurity/The_Administration_Utility

3) Shield官方文档:https://www.elastic.co/guide/en/shield/current/index.html

4) hardenedlinux社区:http://hardenedlinux.org/