云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

文件存储_oracle删除数据库实例_评分榜

小七 141 0

CTF3体系结构

在哲学,CTF3和我们以前的CTF一样:我们给了人们一个机会解决他们通常只能阅读的问题关于。然而,就基础设施而言,这是我们目前为止最复杂的CTF:我们需要任意构建、运行和测试分布式系统代码。在这一周的直播中,我们的7500名参与者推了超过64万次,这意味着我们需要一个可扩展的、健壮的体系结构来提供隔离在用户之间。参与者发布了数属于演练对于这个实际水平,所以我们不会在这里发布官方解决方案。相反,我们会我们给你介绍一下我们是如何工作的。(如果你愿意为了以视频形式看到这一点,我们刚刚发布了CTF3包装。)顺便说一句,CTF的架构反映了很多我们已经学会了建造条纹。如果你对这个感兴趣有点像,我们在招聘工程师在旧金山和遥远的美国时区。我还写了古拉发布我们正在处理的问题。(原来我们有除了建造CTF之外的事情:)。)概述CTF3包括五个水平。从一个很高的水平看,大多数水平都很相似级别:用户会向我们推送一些代码,我们会在沙盒中运行它环境,然后我们会给你一个分数。唯一的例外是吉特币级别,我们只验证人们挖掘的Git提交本地(或其云供应商)。代码以最简单的方式提交给我们:你只是运行git push。在后台,我们收到了你的代码通过git外壳并使用包装器和提交钩子来实现特定于CTF的逻辑。"包装器和提交挂钩"有很多活动部件,不过。一个重要的设计目标是将组件和可以水平缩放系统。有状态的作品数量很少,只能小音量。在下面的部分中,我们将详细介绍所有的部件都是如何工作的,但这里是如何大致适合一起:提交管道想知道你运行git push之后到底发生了什么?这个以下步骤在所有级别之间都很常见。你解决了条纹-ctf.com网站公共知识产权我们的一个前端服务器。您已连接到所选网关服务器上的端口22。安哈普罗西守护程序负载平衡你的流量到我们的一个提交者盒。我们有三个提交箱在池中的大部分事件。作为一种优化,负载平衡使用IP粘性来路由每个连接上的同一提交者后端。这个提交者大多是无状态的:他们只持有代码你在推,然后便利标签每次提交。如果你犯了一个大错误发送到同一个提交者很好,因为你不必这样做每次推送时重新上传。在以前的CTF中,我们只公开了我们的机器主机名(因此您可以直接连接到e、 g.0-01级条纹-ctf.com网站). 在这种情况下,它是很难将机器从池中取出或重新平衡交通。控制这里的负载平衡使我们可以操作以牺牲系统附加约束为代价的灵活性设计(例如,haproxy只知道你的IP地址,所以我们做不到粘性基于用户名)。你所选择的提交者的面向公众的sshd收到了我们在网络界面上给你的用户名比如0-ohngii5M级。我们将PAM堆栈配置为使用LDAP。所以我们可以用web界面共享用户数据库一个快速而肮脏的LDAP服务器实现(称为假用户)直接从我们的中央数据库中获取用户名。用户有空密码,这(给定适当的设置在sshd.conf文件和PAM)意味着您可以登录而无需粘贴密码或给我们你的SSH密钥。当然,缺点是用户名变成了一个秘密凭证。此时sshd运行用户的shell,这是一个定制的在/usr/local/bin/login shell中编写脚本。炮弹是很简单:它设置了一些环境变量,去掉了一群然后(从概念上)运行一堆Ruby代码完成了所有级别的工作。首先,我们实际上会生成一个新的Ruby解释器并加载我们每次登录的代码。结果证明这是站不住脚的。第一个所有,装载捆绑机加上我们所有的代码花费了几秒钟,对于登录来说太慢了会议。所以我们把只用于登录的代码分开我们称之为CTF3NoBundler的模块。这是管理起来很痛苦,这意味着没有绑定器的代码不能使用最多我们在Bundler土地上写的那些图书馆。即使有这样的分裂,它仍然需要大约100-200毫秒加载我们的代码,这实际上是所有的CPU时间。当我们测试的时候连续运行大约20个并发登录,提交者框在负载下停了下来。我们有效地控制了自己通过一次又一次地加载相同的代码。在这一点上,也许最明显的做法是用更快的加载语言重写。但是,实际上提交过程中涉及到相当数量的代码,但没有任何内容一旦代码启动并运行,它就会出错。所以,我们决定尝试加载一次,为每个登录模型分叉。我们拿了一个看看用宙斯这个目的。这是一个很酷的工具,但不幸的是它的目标是开发而不是生产强大的故障处理我们需要这样的核心。所以相反,我们基于类似的想法编写了一个更简单的实现,叫波塞冬。标准管道这是Gitcoin和标准管道分道扬镳。标准提交管道的其余部分如下所示:接下来,我们构建了用户级别的存储库(即您要克隆的实际存储库)在磁盘上。这种懒惰的组装意味着我们不必浪费磁盘空间在用户真正获取代码之前。如果是pull,我们只需要运行gitshell搞定了。然而,推压还有很多事情要做。为了使提交的文件与有可能,我们希望git推送成为可能直接从一个新的克隆。所以在运行gitshell之前,我们玩某个分支重命名技巧。然后我们调用gitshell,后者又调用邮递员钩子。hook也被实现为fast的Poseidon客户端靴子。波塞冬主机中的接收后代码你得分的协调人。首先,它调用了一个运行在单例巨人服务器。为了这个和其他对于需要同步响应的服务,我们使用了Ruby我们在Stripe内部使用的节俭抽象。测试用例分配者只是简单地抓取一些免费的测试用例数据库中的记录,将其标记为已分配,然后返回结果案例。这些测试用例最初是由test_case_generator守护程序创建(运行于testasaurus的箱子-好吧,我们没货了在某一点上的名字)。生成器只是运行我们的基准测试针对随机测试用例的解决方案。我们将元数据存储在数据库,其中实际的blob数据存储在S3上,因此您的客户机以后可以下载。一旦post receive钩子有了测试用例,它就启动了听两个新的RabbitMQ队列:一个用于结果,另一个用于显示到用户。钩子随后提交一个建筑物RabbitMQ上的RPC。我们使用RabbitMQ作为rpc的缓冲区预期可能会被备份,或者在没有同步响应的情况下需要。队列的另一端是一个builder守护进程,运行在一个恰当命名的构建框上。在接收到RPC时,守护进程从提交者的git守护进程到临时目录中。然后,建造者询问了一个中央构建缓存如果缓存了生成提交,则为Thrift服务。如果不是,那么建造者催生了一个码头工人在用户的主目录中装入代码的容器跑了/建筑.sh在集装箱里。然后我们又流回来了这个前几个100 KB的输出。建筑商然后涂上焦油打开输出目录并为生成RabbitMQ score RPC每个测试用例。score RPC包含一个获取tarball的URL从一个nginx运行在构建框中。最后,建造者上传了构建的tarball并通知了build\u缓存关于新SHA1的信息。在缓存的情况下,构建器只是使这个逻辑短路马上把分数传过来。每个score RPC都由一个executor守护进程提供服务在工人的箱子上。执行器获取了生成产品然后生成一个新的容器,其中装载了代码。它然后(终于!)运行您的代码,再次流式输出返回到你。一旦完成,执行者将决定然后将结果RPC发送回post receive钩子。post receive钩子聚合了您的结果,并从那里开始编制了最终结果。它发送了一个FinalScoreRPC将测试运行的结果表示为RabbitMQ。在线路的另一端,一个resulter守护进程在巨大的盒子里徘徊等待着消费最终核心RPC。在使用RPC时,它更新了用户的high分数。Gitcoin管道gitcoon有自己的架构。因为我们不需要运行任何对于您的代码(我们只需要验证所谓的Gitcoin),我们可以用更少的复杂度过日子。我们的采矿机器人为了清理水平,你只需要比我们的快机器人。第