CodeJail部署指南

CodeJail是对于不可信代码的管理系统,主要针对Python的运行,也同样适用于其他编程语言。CodeJail的运行依赖AppArmor,在没有前置安装AppArmor的时候,CodeJail将无法被执行。

CodeJail安装

CodeJail可以从Github上直接获取到,浏览器访问地址https://github.com/edx/codejail或是使用SVN/git从https://github.com/edx/codejail.git直接获取。在获取到CodeJail之后通过python

setup.py进行安装。以一台干净的Ubuntu16.04系统为原料,开始安装的步骤

CodeJail的安装包使用Python2进行安装,安装依赖python-setuptools,所以定位至CodeJail源码文件夹之后使用

sudo apt-get install python-setuptools

sudo python2 setup.py install

操作成功完成CodeJail。安装

CodeJail部署

参数定义:

$SANDBOX_CALLER$:在项目中调用代码的用户。有别于sandbox,作为沙箱内部的代码运行权限用户。

$SANDENV$ :代码所运行的虚拟环境目录位置,需要有被sandbox的访问权限。

部署步骤:

1.为沙箱添加用户和用户组

sudo addgroup sandbox

sudo adduser --disabled-login sandbox --ingroup sandbox

2.创建虚拟环境

创建虚拟环境需要使用virtualenv进行,使用

sudo pip install virtualenv

完成virtualenv安装,使用

sudo virtualenv $SANDENV$

完成虚拟环境部署。

3.安装虚拟环境所用的Python第三方包

下面通过

source $SANDENV$/bin/activate

进入虚拟环境,根据需要,添加第三方Python包

pip install -r sandbox-requirements.txt

4.配置项目服务以沙箱的方式运行

创建配置文件/etc/sudoers.d/01-sandbox

sudo visudo -f /etc/sudoers.d/01-sandbox

并在文件中写入:

$SANDBOX_CALLER$ ALL=(sandbox) SETENV:NOPASSWD:$SANDENV$/bin/python

$SANDBOX_CALLER$ ALL=(sandbox) SETENV:NOPASSWD:/usr/bin/find

$SANDBOX_CALLER$ ALL=(ALL) NOPASSWD:/usr/bin/pkill

5.配置AppArmor配置文件。

创建配置文件的文件名参照被配置应用的路径的,如如下位置的文件

/home/administrator/sandbox/bin/python

其权限配置文件名为

home.administrator.sandbox.bin.python

记配置文件名为$APPARMOR_FILE$

所以使用以下代码配置文件:

sudo vi /etc/apparmor.d/$APPARMOR_FILE$

加入下述配置:

#include <tunables/global>

$SANDENV$/bin/python {

    #include <abstractions/base>

    #include <abstractions/python>

    $SANDENV$/** mr,

    #If you have code that the sandbox must be able to access, add lines

    #pointing to those directories:

    /the/path/to/your/sandbox-packages/** r,

    /tmp/codejail-*/ rix,

    /tmp/codejail-*/** wrix,

}

6.解析配置文件

运行

sudo apparmor_parser /etc/apparmor.d/$APPARMOR_FILE$

重启服务以使其生效

sudo service apparmor restart

7.重启项目服务

CodeJail使用

Codejail可以通过codejail.Jail.safe_exec()和codejail.Jail.jail_code()的方式运行Python代码,其使用方式如下。

import codejail#导入codejail模块

#配置codejail的环境信息

jail = codejail.configure('python','/home/administrator/sandbox/bin/python')

#运行Python代码

jail.safe_exec($str: python code$,$dict:outer variables$})

其中codejail.Jail.jail_code()会使用AppArmor管理的子线程运行Python代码。这个方法可以接收处理程序运行,复制进入当前环境的文件,命令行参数和标准输入流。之后,通过创建临时文件夹,创建或者复制所需文件,启动一个子线程运行代码,最终返回输出和运行状态。以下是codejail.Jail.jail_code()的运行时序图。


codejail.Jail.safe_exec()提供专门的处理方式器以执行Python代码,它模拟Python的exec语句,可以处理大量的Python代码,并通过codejail.Jail.jail_code()进行运行。codejail.Jail.safe_exec()会将参数中的全局字典修改为一个函数副作用,并将其序列化,并以json的方式传入codejail.Jail.jail_code()运行的子线程中。以下是codejail.Jail.jail_code()的运行时序图。


代码维护

在CodeJail进行业务扩展变更的时候,需要对所使用的虚拟环境进行更改。由于虚拟环境受到了AppArmor的保护,所以需要先通过

sudo aa-complain /etc/apparmor.d/$APPARMOR_FILE$

关闭AppArmor的保护,等完成环境更新之后再通过

sudo aa-enforce /etc/apparmor.d/$APPARMOR_FILE$

恢复对虚拟环境的权限保护。

Python3运行环境支持

CodeJail目前只支持Python2的导入运行,在Python3上的导入运行存在问题。不过,这并不影响CodeJail沙箱执行Python3的代码。具体的流程如下。

1.安装Python3,setup-tools,pip

在Ubuntu上可以直接使用

sudo apt-get install python3 python3-setuptools python3-pip

完成Python3的安装

2.虚拟环境安装

一般产生虚拟环境按照CodeJail部署-部署步骤-2的流程即可,但是在多Python环境下想要在虚拟环境指定所需要的对应版本的Python,则需要用—python参数来调用指定所需版本的Python

virtualenv --python=python3 $SANDENV$

3.项目配置文件

在CodeJail部署-部署步骤-4在/etc/sudoers.d/01-sandbox添加以下字段

$SANDBOX_CALLER$ ALL=(sandbox)SETENV:NOPASSWD:$SANDENV$/bin/python3

在CodeJail部署-部署步骤-5配置对应的Python3文件配置

4.CodeJail运行

在对CodeJail进行配置的时候,使用如下所示的参数

jail = codejail.configure('python3', $SANDENV$/bin/python3',user='sandbox', lang=codejail.python3)

之后jail便可以使用Python3进行代码执行。

CodeJail的配置

在使用CodeJail的过程中出现了无法使用tempfile库的问题。之后再缩小范围,发现写入文件本身就无法正常进行,现象如下:

#正常打开一个文件

f = open("xxx","w")

#进行写入操作,正常运行,但是内容未被写入

f.write("abc")

#关闭文件时报错

f.close()

在后来在codejail包下的limits.py文件内找到了对虚拟环境下子线程的运行配置。该部分内容限制了代码运行时使用的硬件资源。

更改FSIZE大小更改,解决无法创建写入文件的问题。

同样,codejail有jail_code代码运行时间的限制。默认为1秒。更改REALTIME项修改。

codejail禁止了创建子进程的功能,进行下述更改

#该行禁止了子进程的创建

rlimits.append((resource.RLIMIT_NPROC, (0, 0)))

#将0改为恰当的数值,这里设置为7848

rlimits.append((resource.RLIMIT_NPROC, (7848, 7848)))

此外,如果有多线程内核的需要可以进行下述更改

#改行对cpu进行了限制

rlimits.append((resource.RLIMIT_CPU, (cpu,cpu+1)))

#将其改为下句可以不限制内核使用

rlimits.append((resource.RLIMIT_CPU, (-1,-1)))

原始代码详细参见如下内容:

codejail/limits.py at master · edx/codejail · GitHub

关于resource的其他配置可以参考:

36.13. resource — Resource usage information — Python 2.7.13 documentation

35.11. resource — Resource usage information — Python 3.6.2rc1 documentation

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356

推荐阅读更多精彩内容