使用 Jailkit 创建 chroot sftp 监狱
我工作中既喜欢又讨厌的事情之一就是被分配新的项目。它们可能涉及任何事情。几个月前,我被分配了一项任务,为一群客户创建一些 chroot 监狱,以便他们可以使用 sftp 安全地上传文件。要求是客户需要能够上传文件,但要以安全和私密的方式进行。例如,客户一不应看到客户二的文件。而且任何一个客户都不应能够浏览服务器的文件系统。我还被要求定义一个流程,以便我们的支持人员可以根据需要添加新的监狱。
我多次使用过 chroot 命令,这是一种非常方便的修复服务器的方法,这些服务器无法以其他方式修复 --- 就像当没有人记得某些多年无人问津的服务器上的 root 密码时一样。只需使用 live CD 启动服务器(Knoppix 是我的个人最爱,我将其加载到我随身携带的 USB 密钥中),挂载主驱动器,然后发出类似于以下的命令
chroot /mnt/hda1
突然之间,感觉您就像在本地文件系统上以 root 用户身份登录,而不是在 live CD 上。然后我可以更改密码、运行程序,并且通常会给自己惹麻烦。 :-)
chroot 的用途远不止将其用作系统恢复工具包的一部分。Chroot 在日常工作中对于隔离应该(或需要)与系统其余部分(以及彼此之间)隔离的应用程序和用户非常有用。
要创建监狱,您需要创建一个文件夹,其中包含普通 Linux 计算机的目录结构的副本。不同之处在于,您只将所需的最少内容复制到目录结构中。您找出应用程序需要哪些库和文件的方法是使用 ldd 或 strace。如果可以,我更喜欢使用 ldd,因为它的输出更易读,但有时需要两者才能找到难以捉摸的库。
例如,假设我想创建一个只包含 bash shell 的监狱,仅此而已。这是一个愚蠢的例子,但非常简单。
我首先需要创建将容纳监狱的目录
daniel@bart:~$ mkdir /opt/jail
现在它只是一个空目录,所以我们现在需要向其中添加一些应用程序。Bash 位于 /bin 目录中,所以我首先重新创建 /bin 目录,然后像这样将 bash 二进制文件复制到其中
daniel@bart:~$ mkdir /opt/jail/bin
daniel@bart:~$ cp /bin/bash /opt/jail/bin/
然后我在 bash 上运行 ldd 以找出它使用的库,如下所示
daniel@bart:~$ ldd /bin/bash
linux-gate.so.1 => (0xffffe000)
libncurses.so.5 => /lib/libncurses.so.5 (0xb7ec2000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7ebe000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7d7d000)
/lib/ld-linux.so.2 => (0xb7f1f000)
daniel@bart:~$
我可以忽略 linux-gate.so.1 文件,它是 Linux 内核创建的虚拟对象,但我需要其他文件,所以我创建目录然后将它们复制过来
daniel@bart:~$ mkdir -p /opt/jail/lib/tls/i686/cmov
daniel@bart:~$ cp /lib/libncurses.so.5 /opt/jail/lib/
daniel@bart:~$ cp /lib/tls/i686/cmov/libdl.so.2 /opt/jail/lib/tls/i686/cmov/
daniel@bart:~$ cp /lib/tls/i686/cmov/libc.so.6 /opt/jail/lib/tls/i686/cmov/
daniel@bart:~$ cp /lib/ld-linux.so.2 /opt/jail/lib/
现在我可以像这样测试监狱
daniel@bart:~$ sudo chroot /opt/jail /bin/bash
bash-3.2#
bash-3.2# 提示符的存在告诉我我成功了。
现在这是一个非常无用的监狱,只有 bash。我可以 'cd' 和 'pwd' 和 'exit' 并执行其他 bash 内置命令,但我不能 'ls' 或 'less' 或 'cp' 或 'mv' 或任何其他外部于 bash 的命令。添加更多二进制文件与添加 bash 相同:复制二进制文件,然后 ldd 它以找到其库,然后将它们复制进来。许多程序使用完全相同的库,因此您经常会发现,将二进制文件复制到现有监狱中就是您需要做的全部,因为库已经在那里了。
一旦我复制了一些二进制文件,这可能会变成一个非常好的沙箱。但是,当我开始构建自定义监狱时,我有一些具体的需求,并且上述监狱远未满足一些陷阱
1. 分配到监狱的用户在登录时需要自动 chroot 到他们的监狱中
2. 不应有 shell 访问权限 --- 我们不希望他们能够 ssh 登录,他们应该只能使用 sftp 和 scp
3. 这需要在昨天完成,并且需要是可重复的。
理论上,第一个问题很容易解决,只需创建一个伪 shell,其唯一目的是将您 chroot 到您的监狱中。是的。容易。哦,并且要安全地完成它,不要有任何可能打开安全漏洞的捷径。是的,绝对容易。
理论上和实践中,第二个问题实际上很容易解决,只需复制 sftp 和 scp 二进制文件,并排除 ssh 二进制文件和任何 shell 二进制文件即可。
第三个问题才是真正的关键。我需要一个快速、可重复的流程。特别是由于一旦事情启动并运行,计划是将所有事情移交给支持团队,以便他们可以根据需要创建新的监狱。
那么我做了什么?我开始寻找其他人已经构建的东西,我找到了 Jailkit。
还有其他一些工具可以自动创建监狱,因此在选择自己的解决方案时,请务必进行一些搜索并探索所有选项。我喜欢 jailkit 的一些地方是
1. 它有许多预配置的集合,您可以混合和匹配这些集合来构建完美的监狱。我称它们为监狱集。
2. 如果现有的监狱集都不能满足您的需求,您可以自定义它们或创建新的监狱集。
3. 创建多个监狱很容易,并且每个监狱可以分配多个用户 --- 但用户不能属于多个监狱,但在我看来这是一件好事。
4. 向监狱添加用户非常容易,几乎到了“就这么简单?”的地步
5. Jailkit 用于在用户登录时 chroot 用户的伪 shell 每次运行时都会检查潜在的安全风险,如果发现任何不好的情况(例如监狱目录被设置为 setuid root),则会断开用户连接。
6. Jailkit 网站提供了清晰、易于遵循的说明,引导您完成几个潜在的监狱设置,并且它有一个很好的故障排除部分,可以帮助您解决由于某种或其他原因导致事情无法正常工作时的问题。
以下是我在服务器上创建监狱的操作
就实际服务器而言,除了安装带有 ssh-server 选项的基本 ubuntu-server 操作系统外,我没有对其进行太多操作。哦,我还安装了 build-essential 元软件包,以便我可以编译和安装 Jailkit。
从 Jailkit 网站下载 tarball 后,Jailkit 从源代码安装,如下所示
daniel@bart:~$ wget http://olivier.sessink.nl/jailkit/jailkit-2.5.tar.gz
daniel@bart:~$ tar -zxvf jailkit-2.5.tar.gz
daniel@bart:~$ cd jailkit-2.5
daniel@bart:~/jailkit-2.5$ ./configure
daniel@bart:~/jailkit-2.5$ make
daniel@bart:~/jailkit-2.5$ sudo make install
整个解包-编译-安装过程非常快。默认情况下,Jailkit 将其二进制文件安装到 /usr/sbin/ 中,并将配置和模板文件安装到 /etc/jailkit/ 中。
安装后,创建监狱很容易。正如我上面所说,Jailkit 附带了几个默认的监狱集。这些在 /etc/jailkit/jk_init.ini 中定义,它们包括 scp、sftp、apache、basicshell 等。至于了解可用的监狱集以及每个监狱集包含的内容,我能说的最好的事情是浏览 /etc/jailkit/jk_init.ini 文件并熟悉它们。您还可以在此文件中定义自己的自定义集。
您可以使用 jk_init 脚本创建监狱,并指定您希望监狱位于何处以及您希望监狱中包含哪些监狱集。下面的示例是我用来创建一个具有 sftp 和 scp 功能的监狱的示例
daniel@bart:~$ sudo jk_init -v /path/to/jail sftp scp jk_lsh
jk_lsh 监狱集提供了一个特殊的 shell,它通过配置文件限制它将执行的二进制文件。这样,即使用户上传了自己的二进制文件,他们也无法执行它。
此时的监狱(假设没有出错)在技术上是一个有效的监狱,但其中还没有任何用户,并且由于此监狱没有“shell”,因此尝试手动 chroot 进入其中进行测试是相当无用的。因此,接下来的当务之急是创建一些用户并将他们添加到监狱中。一旦用户使用以下方法创建并添加到监狱中,他们每次登录时都将被放入该 shell 中。因此,您绝对需要创建仅限监狱的用户。不要将普通用户放入监狱!
daniel@bart:~$ sudo groupadd companyname
daniel@bart:~$ sudo useradd -g companyname -m username
daniel@bart:~$ sudo passwd username
daniel@bart:~$ sudo jk_jailuser -m -j /path/to/jail username
我创建组的原因是因为我正在此服务器上为每个客户公司创建监狱,并且将所有用户分组(没有双关语的意思)是有意义的。我还将 passwd 命令添加到上面的示例中,因为 useradd 命令(至少在 Ubuntu 上)默认情况下不设置密码。在您选择的 Linux 发行版上,情况可能会有所不同。
jk_jailuser 实用程序在如上例所示运行时,会将现有用户的 shell 更改为 /etc/passwd 文件中的 jk_chrootsh,并将主目录更改为 /path/to/jail/./home/username。它还将用户添加到位于 /path/to/jail/etc/passwd 的精简版 passwd 文件中,并将用户的组添加到位于 /path/to/jail/etc/group 的精简版 group 文件中。
如果您想自己编辑这两个 passwd 文件,您可以这样做。只需将 /etc/passwd 中的用户行更改为类似于以下内容
username:x:1010:1010::/path/to/jail/./home/username:/usr/sbin/jk_chrootsh
并将 /path/to/jail/etc/passwd 中的用户行更改为类似于以下内容
username:x:1010:1010::/home/username:/usr/sbin/jk_lsh
(我害怕手动操作会搞砸事情,所以我尽可能使用 jk_jailuser 实用程序。)
现在我们需要允许用户执行 scp 和 sftp 程序。编辑 /path/to/jail/etc/jailkit/jk_lsh.ini 文件并添加一些行,如下所示
[group companyname]
paths= /usr/bin, /usr/lib/
executables= /usr/bin/scp, /usr/lib/sftp-server, /usr/lib/openssh/sftp-server, /usr/libexec/sftp-server
这就是全部内容。我现在有了一个功能齐全的监狱,我可以通过使用 sftp 或 scp 连接到服务器来对其进行测试。当我 sftp 登录并查看时,我只看到监狱目录下的目录,这正是我想要的行为。
如果您稍后发现监狱需要包含其他二进制文件,Jailkit 还包含一个方便的复制命令,您可以使用该命令将其他文件复制到监狱中,如下所示
daniel@bart:~$ sudo jk_cp /path/to/jail /path/to/command
非常简单,它可以处理所有依赖项、库等的定位。我对 jk_cp 命令的唯一抱怨是您必须指定 jk_cp
有时我遇到了 Jailkit 无法正确复制所有内容的问题,或者它只是遗漏了一些库。在这些情况下,我不得不尝试复制其他库。与其重新发明轮子,不如直接将您指向 Jailkit 网站,该网站有一个非常好的页面介绍监狱故障排除。(链接在链接中)
一旦我在我的监狱服务器上运行了 jailkit,并且我有一个可重复的流程来添加用户,我的下一步是创建两个_非常_简单的 shell 脚本,用于创建监狱和创建受限用户。这些脚本由我们的支持人员使用,他们具有有限的 sudo 访问权限,只能以 root 身份运行这些脚本以及 passwd 命令(以便他们可以在需要时更改受限用户的密码)。
这两个脚本分别名为 mkjail 和 jailuser。它们不是那么漂亮,如果被错误的人使用,可能会被认为是危险的。但对于由特定授权和培训人员组成的精选小组进行内部使用,它们工作良好。
随着服务器的设置、脚本的就位以及员工的培训,我的工作完成了。服务器正在不断使用,并且在需要时创建新的监狱,而无需我的干预。当然,项目一完成,我立即被分配了另外三个项目。。。但这就是在技术领域工作的美妙之处,对吧?这绝对不会无聊。 :-)
诚然,创建 sftp 监狱可能不是每个人都需要做的事情,但 jailkit 已经进入了我的系统管理员技巧包。每当我需要将用户或进程隔离到沙箱中,而 Xen 虚拟机又太过分时,我首先想到的就是 jailkit。