我的服务器运行 CentOS:Nginx + PHP-FPM(通过 Fast-CGI 实现 PHP)。每个站点都有自己的 VirtualHost。
目前 Nginx 和 PHP-FPM 均在 root 下运行。我知道这是不好的做法,任何网站都没有理由访问其自身目录之外的文件。
我该如何创建被监禁的用户并指示 nginx && php-fpm 进行相应的操作?
答案1
好的,您使用了一种奇怪的设置,但一般来说:
首先,Linux 不支持真正的(bsd 风格)jail(除非您安装 openvz 或 vserver),但将所有内容设置为以非特权用户 + chroots 运行可以大大提高安全性。以非 root 用户身份运行是必不可少的,chroots 只是潜在攻击者的(可以说是相当大的)绊脚石。
根据 php-fpm 网站,chrooting 是通过配置命令支持的。当然,php-fpm 好像没有文档……如果您浏览源代码 tarball,您可能会找到一些文档,或者至少是一个示例配置。http://php-fpm.org/about/说可以设置用户、组和 chroot。我从未使用过 php-fpm,但这应该是相当常识的。
要让 nginx 以非 root 用户身份运行,请打开 nginx 配置文件,找到以“user”开头的行,并将其更改为系统上的非特权用户。创建一个使用 nologin 作为 shell 的新用户或使用 nobody 用户。
然后,chroot 任何守护进程的过程基本上如下:
- 为特定守护进程的根目录创建目录
- 在 chroot 目录中创建一个骨架目录结构(所以 ./etc、./usr/lib 等)
- 复制所有需要的二进制文件和配置文件(包括 nginx.conf、nginx 二进制文件以及您需要的任何辅助程序)
- 复制 chroot 中需要的其他文件。这至少是 /etc/password 文件的存根(不是影子密码文件,只需要一种查找用户名到 uid 的方法)、/etc/group 文件和 /etc/localtime(如果没有时区信息,php 会无休止地抱怨)。
- 最后,在复制过来的二进制文件上运行 ldd。这将为您提供要复制的库列表。浏览此列表,并将所需的共享对象复制到 chrooted 目录中的等效位置。尝试保留符号链接,或将原始文件复制到以前有符号链接的位置。
- 使用 mknod 创建所需的设备。如果您不知道设备编号,请谷歌搜索(例如:/dev/random 是 c 1 8,/dev/null 是 c 2 2)
- 虽然配置文件中的内容路径应该保持不变,但有时需要进行调整。当您手动 chroot 守护进程时,配置文件中的所有内容都应忽略 chroot 后将不可见的路径部分,例如 /var/log/somelogfile 将保留为 /var/log/somelogfile,尽管它的新路径实际上是 /chroot/nginx/var/log/somelogfile
请记住,任何可以通过配置文件进行 chroot 的守护进程都将不是需要这组步骤 - 在加载相关库依赖项和配置文件后,程序将完成 chrooting。这让生活变得简单多了。
完成此操作后,理论上您应该已准备好运行 chroot 的 nginx(或其他任何程序)。在 nginx 的 /etc/init.d/ 脚本中,找到 nginx 二进制文件实际运行的位置,并将其更改为使用 chroot,例如:
$DAEMON -c $CONFIGFILE
变成
/usr/sbin/chroot /chroot/目录/此处 $DAEMON -c $CONFIGFILE
然后,您就可以使用 init.d 脚本正常启动 nginx。 *如果您从 chroot 收到错误,例如“chroot:无法运行命令 `/bin/that/actually/exists':没有这样的文件或目录”,则说明您缺少一些库或其他必需的东西。任何导致二进制文件完全无法运行的事情都会导致该错误(实际上,我的一个 centos 盒子显示操作不允许)。
由于我的声誉点数不够高,无法发布大量链接,请查看 www (dot) securityfocus (dot) com (slash) infocus/1694(逐步保护 apache) - 它是一个不同的 http 守护进程,但基本步骤相同,至少就 chrooting 而言。
还要记住,需要注意 chroot 文件夹中的文件权限 - 基本上,只要运行 nginx 的用户可以读取/处理 chroot 中的文件,一切都会好起来。
最后,作为 chroot 环境中需要什么类型的东西的一个例子,下面是来自开放墙运行着许多 chrooted 东西的机器。我使用 mysql 作为示例:
localhost!root:/# find /chroot/mysql
/chroot/mysql
/chroot/mysql/var
/chroot/mysql/var/run
/chroot/mysql/var/run/mysql.sock
/chroot/mysql/var/run/mysqld.pid
/chroot/mysql/var/log
/chroot/mysql/etc
/chroot/mysql/etc/my.cnf
/chroot/mysql/etc/hosts
/chroot/mysql/etc/host.conf
/chroot/mysql/etc/resolv.conf
/chroot/mysql/etc/group
/chroot/mysql/etc/passwd
/chroot/mysql/etc/my.cnf.orig
/chroot/mysql/etc/nsswitch.conf
/chroot/mysql/tmp
/chroot/mysql/lib
/chroot/mysql/lib/libtermcap.so.2
/chroot/mysql/lib/libdl.so.2
/chroot/mysql/lib/libc.so.6
/chroot/mysql/lib/librt.so.1
/chroot/mysql/lib/libpthread.so.0
/chroot/mysql/lib/libz.so.1
/chroot/mysql/lib/libcrypt.so.1
/chroot/mysql/lib/libnsl.so.1
/chroot/mysql/lib/libstdc++.so.6
/chroot/mysql/lib/libm.so.6
/chroot/mysql/lib/libgcc_s.so.1
/chroot/mysql/lib/ld-linux.so.2
/chroot/mysql/lib/libnss_compat.so.2
/chroot/mysql/lib/libnss_files.so.2
/chroot/mysql/lib/libnss_compat-2.3.6.so
/chroot/mysql/lib/libnss_files-2.3.6.so
/chroot/mysql/data
/chroot/mysql/data/mysql
/chroot/mysql/data/mysql/db.frm
/chroot/mysql/data/mysql/db.MYI
/chroot/mysql/data/mysql/db.MYD
[further mysql tables have been omitted]
/chroot/mysql/dev
/chroot/mysql/dev/null
/chroot/mysql/usr
/chroot/mysql/usr/local
/chroot/mysql/usr/local/libexec
/chroot/mysql/usr/local/libexec/mysqld
/chroot/mysql/usr/local/charsets
/chroot/mysql/usr/local/charsets/README
/chroot/mysql/usr/local/charsets/Index.xml
/chroot/mysql/usr/local/charsets/armscii8.xml
/chroot/mysql/usr/local/charsets/ascii.xml
/chroot/mysql/usr/local/charsets/cp1250.xml
/chroot/mysql/usr/local/charsets/cp1251.xml
/chroot/mysql/usr/local/charsets/cp1256.xml
/chroot/mysql/usr/local/charsets/cp1257.xml
/chroot/mysql/usr/local/charsets/cp850.xml
/chroot/mysql/usr/local/charsets/cp852.xml
/chroot/mysql/usr/local/charsets/cp866.xml
/chroot/mysql/usr/local/charsets/dec8.xml
/chroot/mysql/usr/local/charsets/geostd8.xml
/chroot/mysql/usr/local/charsets/greek.xml
/chroot/mysql/usr/local/charsets/hebrew.xml
/chroot/mysql/usr/local/charsets/hp8.xml
/chroot/mysql/usr/local/charsets/keybcs2.xml
/chroot/mysql/usr/local/charsets/koi8r.xml
/chroot/mysql/usr/local/charsets/koi8u.xml
/chroot/mysql/usr/local/charsets/latin1.xml
/chroot/mysql/usr/local/charsets/latin2.xml
/chroot/mysql/usr/local/charsets/latin5.xml
/chroot/mysql/usr/local/charsets/latin7.xml
/chroot/mysql/usr/local/charsets/macce.xml
/chroot/mysql/usr/local/charsets/macroman.xml
/chroot/mysql/usr/local/charsets/swe7.xml
/chroot/mysql/usr/local/share
/chroot/mysql/usr/local/share/mysql
/chroot/mysql/usr/local/share/mysql/english
/chroot/mysql/usr/local/share/mysql/english/errmsg.sys
/chroot/mysql/bin
/chroot/mysql/bin/test
/chroot/mysql/bin/nohup
可以通过其配置文件进行 chrooted 的守护进程的设置示例是 maradns:
localhost!root:/# find /chroot/maradns/
/chroot/maradns/
/chroot/maradns/logger
/chroot/maradns/db.[removed]
/chroot/maradns/db.[removed2]
/chroot/maradns/db.[removed3]
正如您所见,maradns 不需要太多操作即可进行 chroot(实际上它只需要 /etc/mararc 文件中的“chroot_dir = “/chroot/maradns”)。
无论如何,这是一个很长且极其漫无边际的帖子,针对的是与您所使用的软件略有不同的软件,但我希望这些信息仍然有用。
答案2
nginx 需要 root 身份绑定到 80 端口作为主进程。然后其工作进程以不同的用户身份运行(基于配置)。
要使 chrooted nginx 和 php-fpm 正常运行并不难 - 只要确保 nginx 有办法访问 php-fpm(使用 tcp 最简单)并确保它将正确的路径传递给 php-fpm(当然是相对于 chrooted php-fpm)。
额外的安全提示是正确设置文件权限。以下是我的做法:
健康)状况:
- 说所有内容都位于 /var/www/root
- php 文件的扩展名为 .php
- php-fpm 以用户“php”、组“php”的身份运行
- nginx 以用户“www”、组“www”的身份运行
权限:
- 所有文件都拥有 php:www 的所有权(所有者“php”,组“www”)
- 目录的权限为 750
- php 文件的权限为 600
- 其余均为 640
简而言之:
chown -R php:www /var/www/root
find /var/www/root -type d -exec chmod 750 {} \;
find /var/www/root -type f -exec chmod 640 {} \;
find /var/www/root -type f -name '*.php' -exec chmod 600 {} \;
可以给予更精细的许可,但这个应该足够容易并且不会破坏任何东西。