https://github.com/toolkithub/rce-engine
HTTP API for running untrusted code inside isolated Docker containers
https://github.com/toolkithub/rce-engine
docker http remote-code-execution systemd
Last synced: 2 months ago
JSON representation
HTTP API for running untrusted code inside isolated Docker containers
- Host: GitHub
- URL: https://github.com/toolkithub/rce-engine
- Owner: ToolKitHub
- License: mit
- Created: 2024-08-06T23:54:34.000Z (11 months ago)
- Default Branch: main
- Last Pushed: 2025-04-02T20:14:27.000Z (3 months ago)
- Last Synced: 2025-04-24T01:47:16.208Z (2 months ago)
- Topics: docker, http, remote-code-execution, systemd
- Language: Rust
- Homepage:
- Size: 205 KB
- Stars: 3
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# rce-engine
[](https://github.com/toolkithub/rce-engine/releases)
[](LICENSE)
## Table of Contents
- [What is rce-engine?](#what-is-rce-engine)
- [Features](#features)
- [Requirements](#requirements)
- [Quick Start](#quick-start)
- [API Reference](#api)
- [Performance](#performance)
- [Security](#security)
- [Configuration](#environment-variables)## What is rce-engine?
rce-engine is a service that provides a HTTP API for running untrusted code inside isolated Docker containers. Each code execution happens in a fresh container that is destroyed after completion, ensuring security and isolation.
## Features
- [x] Secure code execution in isolated containers
- [x] Support for 41 programming languages
- [x] Fast container startup and execution
- [x] Built-in security with gVisor
- [x] Simple HTTP API interface
- [x] Resource usage controls## Requirements
- Ubuntu 22.04 or newer
- Sudo privileges
- 2GB RAM minimum
- 20GB free disk space
- Internet connection
- Port 8080 (configurable)## Quick Start
Install rce-engine
```bash
curl -fsSLO --tlsv1.2 https://raw.githubusercontent.com/toolkithub/rce-engine/main/scripts/installer.sh && bash installer.sh
```Need more control? Check our [detailed installation guides](#installation-instructions).
## Api
| Action | Method | Route | Requires token |
| :-------------------------- | :----- | :------- | :------------- |
| Get service info | GET | / | No |
| Get docker info | GET | /version | Yes |
| [Run code](docs/api/run.md) | POST | /run | Yes |## Docker images
When a run request is posted to rce-engine it will create a new temporary container.
The container is required to listen for a json payload on stdin and must write the
run result to stdout as a json object containing the properties: stdout, stderr and error.
The docker images used [here](https://hub.docker.com/u/toolkithub).## Performance
The following numbers were obtained using [rce-images](https://github.com/toolkithub/rce-images)
on a 5$ linode vm running 'Hello World' with [httpstat](https://github.com/reorx/httpstat)
multiple times locally on the same host and reading the numbers manually.
Not scientific numbers, but it will give an indication of the overhead involved.| Language | Min | Max |
| :------- | :------ | :------ |
| Python | 250 ms | 350 ms |
| C | 330 ms | 430 ms |
| Haskell | 500 ms | 700 ms |
| Java | 2000 ms | 2200 ms |### With [gVisor](https://gvisor.dev/) (optional)
| Language | Min | Max |
| :------- | :------ | :------ |
| Python | 450 ms | 570 ms |
| C | 1300 ms | 1500 ms |
| Haskell | 1760 ms | 2060 ms |
| Java | 4570 ms | 4800 ms |## Security
Docker containers are not as secure as a vm and there has been weaknesses in the past
where people have been able to escape a container in specific scenarios.
The recommended setup is to store any database / user data / secrets on a separate machine then the one that runs docker + rce-engine,
so that if anyone is able to escape the container it will limit what they get access to.Depending on your use-case you should also consider to:
- Disable network access using `DOCKER_CONTAINER_NETWORK_DISABLED`
- Drop [capabilities](https://man7.org/linux/man-pages/man7/capabilities.7.html) using `DOCKER_CONTAINER_CAP_DROP`
- Use the [gVisor](https://gvisor.dev/) runtime## Installation instructions
- [Run rce-engine with systemd](docs/install/ubuntu-22.04.md) (recommended)
- [Run rce-engine in a docker container](docs/install/docker-ubuntu-22.04.md) (some people run into issues while running rce-engine in a container, see open issues)
- [gVisor](docs/install/ubuntu-22.04-gvisor.md)## FAQ
**Q:** How is fork bombs handled?
**A:** The number of processes a container can create can be set with the `DOCKER_CONTAINER_ULIMIT_NPROC_HARD` variable.
##
**Q:** How is infinite loops handled?
**A:** The container will be killed when the `RUN_MAX_EXECUTION_TIME` value is reached.
---
**Q:** How is large output handled?
**A:** rce-engine will stop reading the output from the container when it has read the number of bytes defined in `RUN_MAX_OUTPUT_SIZE`.
---
**Q:** How is high memory usage handled?
**A:** The max memory for a container can be set with the `DOCKER_CONTAINER_MEMORY` variable.
## Environment variables
### Required
| Variable name | Type | Description |
| :---------------------------------- | :--------------------------- | :-------------------------------------------------------------------------- |
| SERVER_LISTEN_ADDR | <ipv4 address> | Listen ip |
| SERVER_LISTEN_PORT | 1-65535 | Listen port |
| SERVER_WORKER_THREADS | <integer> | How many simultaneous requests that should be processed |
| API_ACCESS_TOKEN | <string> | Access token is required in the request to run code |
| DOCKER_UNIX_SOCKET_PATH | <filepath> | Path to docker unix socket |
| DOCKER_UNIX_SOCKET_READ_TIMEOUT | <seconds> | Read timeout |
| DOCKER_UNIX_SOCKET_WRITE_TIMEOUT | <seconds> | Write timeout |
| DOCKER_CONTAINER_HOSTNAME | <string> | Hostname inside container |
| DOCKER_CONTAINER_USER | <string> | User that will execute the command inside the container |
| DOCKER_CONTAINER_MEMORY | <bytes> | Max memory the container is allowed to use |
| DOCKER_CONTAINER_NETWORK_DISABLED | <bool> | Enable or disable network access from the container |
| DOCKER_CONTAINER_ULIMIT_NOFILE_SOFT | <integer> | Soft limit for the number of files that can be opened by the container |
| DOCKER_CONTAINER_ULIMIT_NOFILE_HARD | <integer> | Hard limit for the number of files that can be opened by the container |
| DOCKER_CONTAINER_ULIMIT_NPROC_SOFT | <integer> | Soft limit for the number of processes that can be started by the container |
| DOCKER_CONTAINER_ULIMIT_NPROC_HARD | <integer> | Hard limit for the number of processes that can be started by the container |
| DOCKER_CONTAINER_CAP_DROP | <space separated list> | List of capabilies to drop |
| RUN_MAX_EXECUTION_TIME | <seconds> | Maximum number of seconds a container is allowed to run |
| RUN_MAX_OUTPUT_SIZE | <bytes> | Maximum number of bytes allowed from the output of a run |#### Optional
| Variable name | Type | Description |
| :-------------------------------- | :--------------- | :-------------------------------------------------------------------- |
| DOCKER_CONTAINER_READONLY_ROOTFS | <bool> | Mount root as read-only (recommended) |
| DOCKER_CONTAINER_TMP_DIR_PATH | <filepath> | Will add a writeable tmpfs mount at the given path |
| DOCKER_CONTAINER_TMP_DIR_OPTIONS | <string> | Mount options for the tmp dir (default: rw,noexec,nosuid,size=65536k) |
| DOCKER_CONTAINER_WORK_DIR_PATH | <filepath> | Will add a writeable tmpfs mount at the given path |
| DOCKER_CONTAINER_WORK_DIR_OPTIONS | <string> | Mount options for the work dir (default: rw,exec,nosuid,size=131072k) |
| DEBUG_KEEP_CONTAINER | <bool> | Don't remove the container after run is completed (for debugging) |