到 2025 年,全球将存储大约 200 泽字节的数据。这些数据将存储在公共、私有、本地或云存储、PC、笔记本电脑、智能手机以及物联网 (IoT) 设备中。预计到 2025 年,联网设备的数量也将增加到近 750 亿。对于我们中的一些人或 IT 背景较少的人来说,这些数字算不了什么。但对于安全爱好者来说,这令人担忧,因为越来越多的数据处于危险之中。
在开源技术和数据库的世界中,安全是重要的话题之一。时不时会有许多与安全相关的新发明和发展。其中之一是 Security-Enhanced Linux 或简称 (SELinux),它是由美国国家安全局 (NSA) 于近 21 年前开发的。尽管这是多年前引入的,但它已经迅速发展并被广泛用作 Linux 系统的安全措施之一。虽然很难找到有关如何使用数据库配置它的信息,但 MongoDB 已经利用了这一点。在这篇文章中,我们将介绍 SELinux 以及如何在 MongoDB 副本集中配置它。
为此,我们将为我们的测试环境使用 3 个 CentOS 8 VM,并使用 MongoDB 4.4。在开始之前,让我们深入了解 SELinux。
强制、许可和禁用模式
这是 SELinux 可以在任何给定时间运行的三种模式。当然,就安全策略而言,它们都有自己的功能和目的。我们将一一进行。
在强制模式下,任何配置的策略都将在系统上强制执行,并且用户或进程的每一次未经授权的访问尝试都会被 SELinux 拒绝。不仅如此,那些访问被拒绝的操作也会被记录在相关的日志文件中。虽然这是最推荐的模式,但由于SELinux本身的复杂性等各种原因,现在大多数Linux系统都没有系统管理员启用该模式。
对于许可模式,我们可以肯定地说 SELinux 处于半启用状态。在这种模式下,SELinux 不会应用任何策略,同时不会拒绝任何访问。尽管如此,任何违反政策的行为仍会记录并记录在审计日志中。通常,此模式用于在最终确定并继续执行之前测试 SELinux。
对于禁用的最后一种模式,系统上没有运行增强的安全性。你知道你的系统现在运行的是什么 SELinux 模式吗?只需运行以下命令即可查看:
$ sestatus SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: targeted Current mode: enforcing Mode from config file: enforcing Policy MLS status: enabled Policy deny_unknown status: allowed Memory protection checking: actual (secure) Max kernel policy version: 33
对于我们的测试系统,SELinux 已启用并配置为 enforcing,以便我们可以继续本指南的其余部分。如果您的系统禁用或允许 SELinux,您可以按照以下步骤启用它并更改为强制执行。
- 编辑/etc/selinux/config 文件以将指令更改为 enforcing
vi /etc/sysconfig/selinux ... SELINUX=enforcing …
您需要确保将上述指令设置为 enforcing。
- 重新启动系统以应用设置
$重启
一旦系统上线,我们需要确认 SELinux 已经正确配置并且已经发生了变化。运行下面的命令来检查,这是除了我前面提到的第一个(sestatus)之外的另一种检查方式。
$ getenforce
强制执行
一旦我们看到“Enforcing”这个词,我们现在就可以确认这是好的。由于我们将使用副本集,我们需要确保已在所有 MongoDB 节点上配置了 SELinux。我相信这是我们在继续为 MongoDB 配置 SELinux 之前应该介绍的最重要的部分。
推荐的“ulimit”设置
在此示例中,我们假设 MongoDB 4.4 已安装在 3 个节点上。安装非常简单和容易,为了节省我们的时间,我们不会向您展示步骤,但这里是文档的链接。
在某些情况下,如果限制的默认值较低,系统的“ulimit”会导致一些问题。为了确保 MongoDB 正确运行,我们强烈建议按照此处的MongoDB 建议设置“ulimit”。虽然每个部署都可能有其独特的要求或设置,但最好遵循以下“ulimit”设置:
-f (file size): unlimited -t (cpu time): unlimited -v (virtual memory): unlimited -l (locked-in-memory size): unlimited -n (open files): 64000 -m (memory size): unlimited -u (processes/threads): 64000
要更改“ulimit”值,只需发出以下命令,例如,更改“-n”(打开文件)的值:
$ ulimit -n 64000
更改所有限制后 ,必须重新启动 mongod 实例以确保发生新的限制更改:
$ sudo systemctl restart mongod
配置 SELinux
根据 MongoDB 文档,当前的 SELinux 策略不允许 MongoDB 进程访问/sys/fs/cgroup,这是确定系统上可用内存所必需的。因此,对于我们的情况,其中 SELinux 处于强制模式,必须进行以下调整。
允许访问 cgroup
第一步是确保我们的系统安装了“ checkpolicy”包:
$ sudo yum install checkpolicy
yum install checkpolicy
Last metadata expiration check: 2:13:40 ago on Fri 11 Jun 2021 05:32:10 AM UTC.
Package checkpolicy-2.9-1.el8.x86_64 is already installed.
Dependencies resolved.
Nothing to do.
Complete!
接下来,我们需要为“ mongodb_cgroup_memory.te”创建一个自定义策略文件:
cat > mongodb_cgroup_memory.te <<EOF module mongodb_cgroup_memory 1.0; require { type cgroup_t; type mongod_t; class dir search; class file { getattr open read }; } #============= mongod_t ============== allow mongod_t cgroup_t:dir search; allow mongod_t cgroup_t:file { getattr open read }; EOF
创建策略文件后,最后一步是通过运行以下三个命令来编译和加载自定义策略模块:
$ checkmodule -M -m -o mongodb_cgroup_memory.mod mongodb_cgroup_memory.te $ semodule_package -o mongodb_cgroup_memory.pp -m mongodb_cgroup_memory.mod $ sudo semodule -i mongodb_cgroup_memory.pp
最后一个命令应该需要一段时间,一旦完成,MongoDB 进程应该能够使用 SELinux 强制模式访问正确的文件。
允许访问 FTDC 的 netstat
全时诊断数据捕获 (FTDC) 需要/proc/net/netstat。FTDC 简而言之是一种便于分析 MongoDB 服务器的机制。FTDC 中的数据文件是经过压缩的,不是人类可读的,并且继承了与 MongoDB 数据文件相同的文件访问权限。因此,只有有权访问 FTDC 数据文件的用户才能传输数据。
配置它的步骤几乎与前一个相同。只是自定义策略不同。
$ sudo yum install checkpolicy
Create a custom policy file “mongodb_proc_net.te”:
cat > mongodb_proc_net.te <<EOF
module mongodb_proc_net 1.0;
require {
type proc_net_t;
type mongod_t;
class file { open read };
}
#============= mongod_t ==============
allow mongod_t proc_net_t:file { open read };
EOF
最后一步是编译和加载自定义策略:
$ checkmodule -M -m -o mongodb_proc_net.mod mongodb_proc_net.te $ semodule_package -o mongodb_proc_net.pp -m mongodb_proc_net.mod $ sudo semodule -i mongodb_proc_net.pp
自定义 MongoDB 目录路径
需要注意的一件重要事情是,如果您在自定义目录中安装了 MongoDB,则还需要自定义 SELinux 策略。步骤与前一个略有不同,但并不太复杂。
首先,我们需要更新 SELinux 策略以允许 mongod 服务使用新目录,值得注意的是,我们需要确保在目录末尾包含 .* :
$ sudo semanage fcontext -a -t <type> </some/MongoDB/directory.*>
- mongod_var_lib_t用于数据目录
- mongod_log_t用于日志文件目录
- mongod_var_run_t用于 pid 文件目录
然后,更新新目录的 SELinux 用户策略:
$ sudo chcon -Rv -u system_u -t <type> </some/MongoDB/directory>
- mongod_var_lib_t用于数据目录
- mongod_log_t用于日志目录
- mongod_var_run_t用于 pid 文件目录
最后一步是将更新的 SELinux 策略应用到目录:
restorecon -R -v </some/MongoDB/directory>
由于 MongoDB 对数据和日志文件都使用默认路径,因此我们可以查看以下有关如何应用它的示例:
对于/mongodb/data 的非默认 MongoDB 数据路径:
$ sudo semanage fcontext -a -t mongod_var_lib_t '/mongodb/data.*' $ sudo chcon -Rv -u system_u -t mongod_var_lib_t '/mongodb/data' $ restorecon -R -v '/mongodb/data' For non-default MongoDB log directory of /mongodb/log (e.g. if the log file path is /mongodb/log/mongod.log): $ sudo semanage fcontext -a -t mongod_log_t '/mongodb/log.*' $ sudo chcon -Rv -u system_u -t mongod_log_t '/mongodb/log' $ restorecon -R -v '/mongodb/log'
自定义 MongoDB 端口
在某些情况下,某些 MongoDB 安装使用不同于默认端口号 27017 的端口号。在这种特殊情况下,我们还需要配置 SELinux,命令非常简单:
$ sudo semanage port -a -t mongod_port_t -p tcp <portnumber> For example, we are using port 37017: $ sudo semanage port -a -t mongod_port_t -p tcp 37017
部署使用 ClusterControl 启用的 MongoDB SELinux
使用 ClusterControl,您可以选择在部署 MongoDB 副本集期间启用 SELinux。但是,您仍然需要将模式更改为 enforcing,因为ClusterControl仅将其设置为 permissive。要在部署期间启用它,您可以按照下面的屏幕截图取消选中“禁用 AppArmor/SELinux”。

之后,您可以继续为 MongoDB 副本集添加节点并开始部署。在 ClusterControl 中,我们为 MongoDB 使用 4.2 版。

集群准备好后,我们需要将 SELinux 更改为对所有节点强制执行,并参考我们刚刚经历的步骤继续配置它。
结论
任何 Linux 系统都可以使用 3 种 SELinux 模式。对于 SELinux 强制模式,需要遵循几个步骤以确保 MongoDB 运行没有任何问题。还值得注意的是,一些“ ulimit”设置也需要更改以适应系统要求和规格。
我们希望这篇文章能帮助您为 MongoDB 服务器设置 SELinux。




