仅将“expect”限制为 stdin/stdout 交互

仅将“expect”限制为 stdin/stdout 交互

我需要接受来自用户的作业文件,这基本上包括控制台与我将为他们运行的进程的交互。自然,想到的第一个想法是使用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.exproot

# 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

相关内容