简体   繁体   English

对运行在服务器上的用户编写的 node.js 脚本进行沙箱化

[英]Sandboxing a node.js script written by a user running on the server

I'm developing a platform where users can create their own "widgets", widgets are basically js snippets ( in the future there will be html and css too ).我正在开发一个平台,用户可以在其中创建自己的“小部件”,小部件基本上是 js 片段(将来也会有 html 和 css )。

The problem is they must run even when the user is not on the website, so basically my service will have to schedule those user scripts to run every now and then.问题是即使用户不在网站上,它们也必须运行,所以基本上我的服务必须不时地安排这些用户脚本运行。

I'm trying to figure out which would be the best way to "sandbox" that script, one of the first ideas i had was to run on it's own process inside of a Docker, so let's say the user manages to somehow get into the shell it would be a virtual machine and hopefully he would be locked inside.我试图找出哪种方法是“沙箱”该脚本的最佳方式,我的第一个想法是在 Docker 内部运行它自己的进程,所以假设用户设法以某种方式进入shell 这将是一个虚拟机,希望他能被锁在里面。

I'm not a Docker specialist so i'm not even sure if that makes sense, anyway that would yield another problem which is spinning hundreds of dockers to run 1 simple javascript snippet.我不是 Docker 专家,所以我什至不确定这是否有意义,无论如何这会产生另一个问题,即旋转数百个 docker 以运行 1 个简单的 javascript 片段。

Is there any "secure" way of doing this?有没有任何“安全”的方式来做到这一点? Perhaps running the script on an empty scope and somehow removing access to the "require" method?也许在空范围内运行脚本并以某种方式删除对“require”方法的访问?

Another requirement would be to kill the script if it times out.另一个要求是在脚本超时时终止脚本。

EDIT: - Found this relevant stackexchange link编辑: - 找到这个相关的stackexchange 链接

This can be done with docker, you would create a docker image with their script in it and the run the image which creates a container for the script to run in.这可以通过 docker 来完成,您可以创建一个 docker 镜像,其中包含他们的脚本,然后运行该镜像,该镜像会为脚本运行创建一个容器。

You could even make it super easy and create a common image, based on the official node.js docker image, and pass in the users custom files at run time, run them, save the output, and then you are done.你甚至可以让它变得超级简单,基于官方的 node.js docker 镜像创建一个通用镜像,并在运行时传入用户自定义文件,运行它们,保存输出,然后你就完成了。 This approach is good because there is only one image to maintain, and it keeps the setup simple.这种方法很好,因为只需要维护一个图像,并且可以保持设置简单。

The best way to pass in the data would be to create a volume mount on the container, and mount the users directory into the container at the same spot everytime.传入数据的最佳方法是在容器上创建一个卷挂载,并将用户目录每次都挂载到容器的同一位置。

For example, let's say you had a host with a directory structure like this.例如,假设您有一台具有这样目录结构的主机。

/users/
     aaron/
     bob/
     chris/

Then when you run the containers you just need to change the volume mount.然后当您运行容器时,您只需要更改卷安装。

docker run -v /users/aaron:/user/ myimagename/myimage
docker run -v /users/bob:/user/ myimagename/myimage

I'm not sure what the output would be, but you could write it to /user/output inside the container and the output would be stored in the users output directory.我不确定输出是什么,但您可以将其写入容器内的 /user/output ,输出将存储在用户输出目录中。

As far as timeouts, you could write a simple script that looks at docker ps and if it is running for longer then the limit, docker stop the container.至于超时,您可以编写一个简单的脚本来查看 docker ps,如果它运行的时间超过限制,则 docker 停止容器。

Because everything is run in a container, you can run many at a time and they are isolated from each other and the host.因为一切都在一个容器中运行,您可以一次运行多个,并且它们彼此隔离并与主机隔离。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM