我需要接受来自用户的作业文件,这基本上包括控制台与我将为他们运行的进程的交互。自然,想到的第一个想法是使用expect
脚本作为作业文件:
spawn process
expect "ready"
send "process DATA"
set timeout 100
expect {
"done" {send_user "success"}
timeout {send_user "failure"}
}
但是,由于我想自动接受作业,因此我想防止用户做一些愚蠢或危险的事情,例如生成 10 个sysbench
进程,或将随机文件写入磁盘,或尝试读取/etc/passwd
.我想将它们限制为与我为它们生成的进程进行 STDIN/STDOUT 交互。
我该怎么办呢?到目前为止我的想法是:
- 写我自己的“expect lite”。听起来可行,但愚蠢且耗时。
- 清理
expect
作业文件。听起来很复杂而且容易出错。 - 发明我自己的安全语言并将其翻译为
expect
.可行,但我必须提供文档和教程,以便用户可以学习。 - 使用配额和权限限制作业流程。这并不是一个真正的选择,因为我希望
process
使用大量的 CPU 时间并创建 tmp 文件(我相信它会清理这些文件)。 - 为用户提供交互式访问
process
.这不是一个选择,因为作业可能必须在队列中等待一段时间。
我是否缺少一些明显的东西,例如expect
限制脚本的配置参数,或者我可以使用的类似工具?
答案1
TCL 安全翻译器可与expect
.为了说明这一点,我创建了两个脚本:unsafe.exp
代表用户提交的文件和safe.exp
,它使用安全解释器来运行unsafe.exp
。这是代码unsafe.exp
:
#!/usr/bin/expect
spawn whoami
expect {
"user" { send_user "safe success\n" }
"root" { send_user "unsafe success\n" }
}
运行结果unsafe.exp
为root
# expect unsafe.exp
spawn whoami
root
unsafe success
现在,safe.exp
将阻止用户使用 等危险命令spawn
,同时仍提供对send
和等基本功能的访问expect
。这是代码:
#!/usr/bin/expect
# create a safe interpreter
interp create -safe untrusted
# provide it with essetial expect functions
interp alias untrusted send_user {} send_user
interp alias untrusted send {} send
interp alias untrusted expect {} expect
interp alias untrusted interact {} interact
# censor the "spawn" function
# not providing it would be just as safe, but scripts using it would fail
proc safe_spawn {args} {
puts "censored spawn"
}
interp alias untrusted spawn {} safe_spawn
# create a safe process to interact with
spawn sudo -u user whoami
# run unsafe.exp
untrusted invokehidden source unsafe.exp
以 root 身份运行safe.exp
会导致
# expect safe.exp
spawn sudo -u user whoami
censored spawn
user
safe success