在线运行代码编译器的原理:基于Docker实现在线编译运行代码

在线编译器的基本原理是利用 Docker 容器来隔离编译和执行环境。Docker 提供了一个轻量级的虚拟化环境,可以在其中运行各种操作系统和应用程序,而不会影响到主机系统。

欢迎体验我自用的小工具 在线运行代码 , 小水管,还请见谅

1. 安装 Ubuntu 镜像

首先,我们需要安装一个 Ubuntu 镜像,以便在其中运行编译和执行命令。

docker pull ubuntu

安装完成后,我们就相当于拥有了一台 Ubuntu 系统的电脑。在这个系统中进行的任何操作都不会影响到主机系统,即使是格式化系统。

2. 在 Docker 中执行命令

我们可以通过以下命令在 Docker 容器中执行命令:

docker run --rm ubuntu ls

这条命令启动了一个 Ubuntu 系统,并在其中执行了 ls 命令。--rm 参数会在命令执行完毕后自动删除容器,因为我们只需要一次性的执行环境。

3. 编译和执行代码

接下来,我们需要在容器中编译和执行用户提交的代码。为了确保安全,我们需要将代码原样输入到容器中,而不是通过拼接命令的方式。

面临的问题

1. 如何将代码放到容器中?

不安全的方案一

我们可以通过 && 符号将多个命令连接起来,例如:

echo ls>test.sh && chmod +x test.sh && ./test.sh

这条命令的作用是将 ls 代码写入 test.sh 文件,赋予其可执行权限,然后运行它。拼接好的完整命令如下:

docker run --rm ubuntu /bin/bash -c "echo ls>test.sh && chmod 777 test.sh && ./test.sh"

存在的问题:

  • 多行代码处理echo 命令不支持多行代码。
  • 特殊字符处理:代码中的特殊字符(如 \n)可能会导致转义问题。
  • 命令注入漏洞:用户可以通过构造恶意代码来执行任意命令,例如:
echo 1 && rm /* -rf &&echo 1>test.sh && chmod +x test.sh && ./test.sh

2. 安全的解决方案

为了解决上述问题,我们可以使用 cat 命令将代码原样输入到文件中。cat 命令的使用方式如下:

cat>1.c<<EOF
printf("\n");
EOF

运行后,1.c 文件中的内容将是:

printf("\n");

存在的问题:

  • EOF 固定问题:用户可以通过构造特定的代码来利用固定的 EOF 字符串。
  • 变量问题:代码中以 $ 开头的字符串会被当做变量处理。

3. 终极解决方案

为了避免上述问题,我们可以使用 Docker 的 -i 参数,将标准输入直接传递到容器中。这样,用户提交的代码将在容器中执行,而不是在主机上执行。

docker run -i ubuntu /bin/bash

执行这条命令后,我们可以在容器中输入任意命令,例如:

cat>test.py<<\EOF
print("hello")
EOF
python test.py

在这个方案中,EOF 字符串被替换为随机的 UUID 字符串,以防止用户构造特定的代码。此外,cat 命令在限定字符串前加反斜杠,以防止 $username 这类字符串被当做变量处理。

资源限制

为了确保在线编译器的安全性和稳定性,我们还需要对程序的运行时间和资源使用进行限制。

1. 程序运行时间的限制

可以通过设置超时时间来限制程序的运行时间,例如:

timeout 5s python test.py

2. 内存的限制

可以使用 ulimit 命令来限制程序的内存使用,例如:

ulimit -v 524288  # 限制内存为 512MB

3. CPU 限制

可以使用 cpulimit 工具来限制程序的 CPU 使用率,例如:

cpulimit -l 50 python test.py  # 限制 CPU 使用率为 50%

4. 提交代码和输入内容大小的限制

可以通过限制 HTTP 请求的大小来限制用户提交的代码和输入内容的大小,例如:

client_max_body_size 1M;  # 限制请求大小为 1MB

通过利用 Docker 容器和 cat 命令,我们可以构建一个安全的在线编译器。关键在于确保用户提交的代码在容器中执行,而不是在主机上执行。此外,通过设置资源限制,我们可以进一步提高系统的安全性和稳定性。

关键点回顾

  • 使用 Docker 容器:隔离编译和执行环境。
  • 使用 cat 命令:将代码原样输入到文件中。
  • 随机 UUID 字符串:防止用户构造特定的代码。
  • 资源限制:限制程序的运行时间、内存和 CPU 使用。

通过这些措施,我们可以构建一个安全、可靠的在线编译器,为用户提供一个安全的编程环境。

标签: Docker

相关文章

编译最新的kkFileView并使用docker打包

kkFileView 是一个开源的文件预览服务,支持多种文件格式的在线预览。本文将详细介绍如何编译 kkFileView 的最新版本,并将其打包成 Docker 镜像。1. 环境准备在开始之前,...

整理一些Docker运维中常用的命令

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。以下是一些在 Docker 运维中常...

图片Base64编码

CSR生成

图片无损放大

图片占位符

Excel拆分文件