用Golang写了个OJ

想在学校弄一个OJ服务器,现在写到了一个大致一个能用的版本,貌似还有很多问题,安全问题全部用docker作沙箱包了一层,现在跑的是没包的,因为有点难修改,等跑的比较稳定了再套上去,web框架是revel.

demo: http://115.28.174.83:9000/

代码: https://github.com/ggaaooppeenngg/OJ

共 26 个回复


jikai507

lz是搞ACM的吧~

# 0

ggaaooppeenngg

@sake 好厉害! 光看commit数就知道比我的吊太多了,一定要看看你们的实现. 怎么网站打不开?

@jikai507 我是ACM渣,闲得没事写的.

# 2

sake

@ggaaooppeenngg 是因为学校断电维护后,就一直没空把服务器开起来,过几天把服务器开起来。

# 3

clarkzjw

@ggaaooppeenngg 我和楼上sake一起的。。。话说我们一开始也打算用docker来作沙箱,不过现在跑的暂时没弄orz。。。

# 4

Oishi

前端貌似用的 semantic-ui框架?

# 5

ggaaooppeenngg

@Oishi 是semantic-ui,尝试一下, @jimmykuu 推荐的嘛.

@clarkzjw https://github.com/ggaaooppeenngg/sandbox,

这是我单独抽离出来的,readme还没写的的说,你们是用C++写的是么.

我们可以交流一下,写的时候还是有满多没有很好解决的地方,我QQ 471160171

# 6

clarkzjw

@ggaaooppeenngg 现在的版本判题部分是@sake 用C++写的,做了系统调用限制之类的。。现在这个项目的负责人是@sake 你可以联系他,邮件地址在他的 github页面

# 7

ggaaooppeenngg

@clarkzjw 先赞一个! 有打算支持go么?

# 9

sake

@ggaaooppeenngg 当然要支持go,毕竟go是oj的母语嘛,后面还需要人维护呢。

# 10

kzzhr

没想到用go写oj的这么多人。

有木有建个讨论组啊

# 11

sake

@kzzhr 我们oj有个讨论组--

# 12

clarkzjw

@kzzhr 你可以订阅我们的邮件列表Here (需要科学上网)不过刚刚建立起来,还比较冷清~

# 13

ggaaooppeenngg

@kzzhr @clarkzjw @sake 已订阅, 我的也更新了一点做了个logo,嘿嘿.

# 14

maemual

昨天看了一下你写的sandbox代码,基本思路和我之前用C++写的基本差不多,我比较感兴趣的是在上面说用Docker来实现一个隔离的沙盒。但是看了半天并没有看到如何和Docker结合的地方。

你是直接把sandbox程序放在Docker里面跑的吗?那么如果别人提交恶意代码,导致sandbox崩溃了,甚至Docker崩溃了,你是如何捕获这样的信息的呢?

# 15

ggaaooppeenngg

@maemual 因为感觉sandbox还没定型,所以没有把docker套上去,每次改一下还要专门套一下好麻烦,我现在是默认没有人能破坏计算机的状态在写. 在sandbox/Dockerbox文件夹下面就是dockerbox的内容,第一是docker不能往虚拟机上添加单个的文件,所以我曲线救国写了个dockerfile专门添加文件进去(貌似是以前有后来又把这个特性删了),然后放在里面跑,把标准输出和标准输入连到外面来,跑完测试以后把这个container删掉,这是我的实现方法.

我现在是尽量让sandbox往标准输出上尽量输出错误信息,就我现在的知识能够处理的信息,可能还有我现在的知识捕获不到的错误信息,即使这些错误发生了,但是最后当掉的就是一个docker的container,大不了这个测试不出结果罢了,一直在handling状态,然后我发现有题目一直是handling的状态,我就会去查提交了什么代码,然后对症下药,下次提交类似的代码或出现类似的结果就在输出的错误信息里面表示出来,这几天有很些人提交了虽然不会破坏计算机但是很奇怪的代码我都是这么改进的.我觉得docker崩了,不会影响真正的服务器就行,恶意代码也没指望AC的.我是这么一个思路

# 16

clarkzjw

@ggaaooppeenngg 我们开发版的前端正在用https://github.com/FezVrasta/bootstrap-material-design ,感觉material design真是很棒

# 17

bigbear

孤陋寡闻了, OJ是做什么用的? 点了几个进去都看不懂.

# 19

ggaaooppeenngg

@duguying 厉害! 其实我有个TODO一直没动.我现在是一个生产者去取数据库的新提交,然后马上标记为handling,接着去扫描,这样也不用同步什么的,交给多个消费者处理这些提交,这样,当然这个模型目前其实够用了.我觉得就是数据库扫描这里有点不对劲,如果我要多个生产者的话,想在数据库把unhandle标记成handling的地方加锁,但是那一次只有一个生产者,和没加锁一样的.所以我在想多个生产者是不是是多余的.

# 20

ggaaooppeenngg

@bigbear 就是Online Judge,一般是用作ACM判题的,接受代码用一些测试输入到标准输入,然后用标准输出和答案比较. 最重要的是安全问题,即你让别人的代码在你的服务器上跑,就不能让它有任何恶意行为.

# 21

duguying

@ggaaooppeenngg 说说我的思路吧,网站和judger分离,judger提供api(提供TCP,HTTP:jsonrpc两种协议)可供其他网站或应用调用。ojsite是oj网站的实现,ojsite收到用户提交的判题任务后将数据存入网站数据库mysql并标记为Task Add,然后ojsite将任务(Task)提交给judger,judger判定完成后将结果数据存储至sqlite,一秒后ojsite前端js会发送查询结果请求,首先查mysql若为Task Add则向judger发送请求查询题目判定结果,收到返回结果更新题目状态。至於想要实现分布式judger只需在ojsite上开发相关的middleware实现连接多个judger即可。

# 22

duguying

@ggaaooppeenngg 另外关于沙箱我也有未完成的技术债务,那就是windows上的沙箱,准确的说我目前的judger并不支持windows沙箱,windows版的executer充其量只能够称之为执行器,没有安全拦截的功能。之前也想过实现windows的sandbox,可是最终发现太难,要想实现windows沙箱需要掌握windows api hook技术,windows ddk(Driver Develop Kit),而且hook windows的native api可不是普通的api hook那么简单,后来我发现poj免费版的README文档中说他们的run.exe(执行器,相当于我的executer.exe)并不保证文件读写安全,也就是说他们的执行器也无法支持api拦截,于是我便坦然了。就我目前的技术能力是无法实现native api hook的,或许以后的某一天会去实现它。

# 23

leemaster

对于Unix 之流控制还是比较简单的,检测寄存器就行了,之前我尝试过用ptrace来搞,但是windows还有很多坑没踩

# 25