我在写基于Python的应该是能够执行“插件”,这样的功能可以很容易扩展的Web服务器。
为此,我认为这种方法有多个文件夹(每个插件),并出现了一批壳/ Python脚本对可能发生的不同事件的预定义的名字命名的。
一个例子是有一个on_pdf_uploaded.py
当PDF上传到服务器,执行文件。 要做到这一点,我会使用Python的子进程的工具。
为了方便和安全,这将允许我使用Unix环境变量来提供进一步的信息和设置进程的工作目录(CWD),以便它能够访问正确的文件,而无需找到自己的位置。
由于插件代码从不受信任来源的到来,我想让它尽可能的安全。 我的想法是执行在子进程的代码,但把它放到一个chroot监狱使用不同的用户,使其无法访问服务器上的任何其他资源。
不幸的是我无法找到这事,我不想依靠不可信脚本把自己变成一个监狱。
此外,我不能把主/调用进程进入一个chroot监狱,因为相关插件代码可能会在多个进程同时在服务器应答其他请求执行。
因此,这里的问题:怎样才能以最小权限的chroot监牢保护服务器的其余部分由错误的,不信任的代码被损坏执行子过程/脚本?
谢谢!
创建入狱后,你会打电话os.chroot
从Python源进入它。 但即便如此,已经被翻译打开任何共享库或模块文件仍然是开放的,而且我也没办法通过关闭这些文件的后果是什么os.close
会; 我从来没有尝试过。
即使这个工程,建立chroot的是一个大问题,所以一定好处是值得的代价。 在最坏的情况下,你必须确保与您打算使用的所有模块,以及所有相关的程序和共享库和其它文件的整个Python运行/bin
, /lib
等各获刑文件系统中可用。 ,当然,这样做不会保护其他类型的资源,即网络目的地,数据库。
另一种可能是在不受信任的代码作为字符串读取,然后exec code in mynamespace
,其中mynamespace
是只定义要公开到不可信代码符号字典。 这将是这类Python的虚拟机内的“监狱”的。 您可能需要解析源第一个找的东西像import
语句,除非更换内置__import__
功能将拦截(我不确定)。
也许这样的事情?
# main.py
subprocess.call(["python", "pluginhandler.py", "plugin", env])
然后,
# pluginhandler.py
os.chroot(chrootpath)
os.setgid(gid) # Important! Set GID first! See comments for details.
os.setuid(uid)
os.execle(programpath, arg1, arg2, ..., env)
# or another subprocess call
subprocess.call["python", "plugin", env])
编辑:想用叉子(),但我并没有真正理解它的所作所为。 看着它。 新的代码!
# main.py
import os,sys
somevar = someimportantdata
pid = os.fork()
if pid:
# this is the parent process... do whatever needs to be done as the parent
else:
# we are the child process... lets do that plugin thing!
os.setgid(gid) # Important! Set GID first! See comments for details.
os.setuid(uid)
os.chroot(chrootpath)
import untrustworthyplugin
untrustworthyplugin.run(somevar)
sys.exit(0)
这是有益的,我几乎只是偷了这些代码,所以荣誉给那家伙一个体面的例子。