首页 > 解决方案 > 我可以在运行时限制我在 CGI 脚本中允许进入的文件夹吗?

问题描述

我正在为我的网站编写 cgi 程序(全部由一个 lighttpd 服务托管)。这些程序读取它们各自驻留的子文件夹中的目录和文件。它们使用网络服务器的用户 ID 运行。

我想确保不会发生可能导致我的程序在其预期工作空间之外读取的错误。我想象在运行时在我的 cgi 程序顶部附近的某处添加一行,如下所示:

restrict_io(".");

如果他们做了一些时髦的事情,比如尝试从 /usr/bin 运行任意东西或打开 ../other_website/stuff 中的文件,那么该行之后的任何内容都会出现访问错误。

有什么简单的解决方案吗?我浏览了各种解决方案,但他们似乎都需要我的大量投资才能了解他们是否真的可以做我想做的事。

chroot(2) 文档说“它不打算用于任何类型的安全目的,既不完全沙箱化进程也不限制文件系统系统调用”它还需要网络用户没有的功能或 root。它也可能过于复杂,因为我怀疑您需要仔细准备新的“/”。

seccomp(2) 文档很长而且阅读起来很乏味。听起来它做了很多,但不清楚它是否可以做我想要的。

promise(2) 仅适用于 BSD,而我的服务器是 Linux 的一种风格,我希望保持这种状态,因为我使用该机器的目的不仅仅是网络托管。再说一次,我也不确定质押是否符合我的要求。

LXC,还没有读到它。

Docker 看起来像是某家公司的产品。我还没有读过它是否是免费的、开源的。

如果您还没有在字里行间阅读,C 解决方案将是最好的,但如果不是 C,请不要犹豫,也提供一个答案。一个代码片段值一千字。

标签: linuxsecuritycgisandbox

解决方案


我发现 AppArmor(Linux 内核的一部分)完全符合我的要求。

您在代码中调用 aa_change_profile(const char * profile) 。该配置文件首先以 root 身份使用 CLI util apparmor_parser 注册。您可能需要使用内核参数启用 apparmor,然后启动服务:

linux ... apparmor=1 security=apparmor

sudo systemctl 启用 apparmor

示例 cgi.armor:

profile restricted_cgi {
  deny network,
  /home/pi/website1/** r,
}

sudo apparmor_parser -a cgi.armor

使用 -lapparmor 编译的示例 my_program.c:

#include <sys/apparmor.h>
...
int armor = aa_change_profile("restricted_cgi");
if(armor) {
  printf("Armor error: %s\n", strerror(errno));
  return 1;
}

推荐阅读