Dify-Sandbox: 安全な分離環境でコードを実行する

## はじめに

Dify-Sandboxは、信頼できないコードを安全な環境で実行するためのシンプルなソリューションを提供します。複数のユーザーが実行するコードをサブミットできる、マルチテナント環境での使用を想定して設計されています。コードはサンドボックス化された環境で実行され、コードがアクセスできるリソースとシステムコールが制限されます。

---

こちらの記事もおすすめ

https://hamaruki.com/dify-v0-6-9-release-notes/

https://hamaruki.com/difys-docker-compose-upgrade-instructions/

## Dify-Sandboxとは

Dify-Sandboxは、Go言語で書かれたオープンソースのサンドボックスライブラリであり、信頼できないコードを安全に実行するための環境を提供します。

**主な機能：**

* **システムコールの制限:** Linuxのseccomp機能を使用して、実行中のプロセスが許可されたシステムコールのみに制限されます。これにより、悪意のあるコードがシステムに損害を与えるのを防ぐことができます。
* **リソース制限:** メモリ使用量、CPU時間、プロセス数などを制限できます。これにより、悪意のあるコードがシステムリソースを枯渇させるのを防ぐことができます。
* **分離環境:** コードは、ホストシステムから隔離された環境で実行されます。これにより、悪意のあるコードがホストシステムにアクセスしたり、損害を与えたりするのを防ぐことができます。
* **多言語サポート:** Node.js、Python3などの複数のプログラミング言語をサポートしています。

## Dify-Sandboxの利点

Dify-Sandboxを使用する利点は次のとおりです。

* **セキュリティの向上:** 信頼できないコードを実行する場合でも、システムを保護できます。
* **リソースの効率的な使用:** コードが使用できるリソースを制限することで、システムリソースを効率的に使用できます。
* **柔軟性:** 複数のプログラミング言語をサポートしているため、さまざまなユースケースで使用できます。

## Dify-Sandboxのユースケース

Dify-Sandboxは、次のようなユースケースで使用できます。

* **オンラインジャッジシステム:** ユーザーが提出したコードを安全に実行し、評価することができます。
* **コードの実行環境:** 信頼できないコードを安全に実行するための環境を提供できます。
* **セキュリティテスト:** 悪意のあるコードがシステムに与える影響を分析するために使用できます。

## Dify-Sandboxの仕組み

Dify-Sandboxは、以下のコンポーネントで構成されています。

* **Sandbox Manager:** サンドボックス環境の作成、管理、破棄を行います。
* **Seccomp Profile:** 実行可能なシステムコールを定義します。
* **Resource Limits:** コードが使用できるリソースを制限します。
* **Sandbox Environment:** コードが実行される分離された環境です。

Dify-Sandboxは、コードを実行する前に、まずSeccomp ProfileとResource Limitsを設定します。次に、Sandbox Environmentを作成し、その中でコードを実行します。Sandbox Environmentは、ホストシステムから隔離されているため、コードは許可されたシステムコールのみにアクセスでき、リソースの使用量も制限されます。

## Dify-Sandboxの使い方

Dify-Sandboxを使用するには、以下の手順に従います。

### インストール

Dify-Sandboxは、Dockerイメージとして提供されています。以下のコマンドを実行して、Dockerイメージをダウンロードします。

```bash
docker pull langgenius/dify-sandbox
```

### 実行

以下のコマンドを実行して、Dify-Sandboxコンテナを起動します。

```bash
docker run -p 8194:8194 langgenius/dify-sandbox
```

```bash
C:\Prj\dify-sandbox>docker run -p 8194:8194 langgenius/dify-sandbox
2024/07/13 07:55:00 setup.go:29: [INFO]initializing nodejs runner environment...
2024/07/13 07:55:00 setup.go:85: [INFO]nodejs runner environment initialized
2024/07/13 07:55:00 setup.go:31: [INFO]initializing python runner environment...
2024/07/13 07:55:00 setup.go:43: [INFO]python runner environment initialized
2024/07/13 07:55:00 config.go:96: [INFO]network has been enabled
2024/07/13 07:55:00 server.go:20: [INFO]config init success
2024/07/13 07:55:00 server.go:24: [ERROR]failed to setup runner dependencies: open dependencies/python-requirements.txt: no such file or directory
2024/07/13 07:55:00 server.go:26: [INFO]runner dependencies init success
2024/07/13 07:55:00 server.go:42: [INFO]installing python dependencies...
2024/07/13 07:55:00 server.go:48: [INFO]python dependencies installed
2024/07/13 07:55:00 server.go:50: [INFO]initializing python dependencies sandbox...
2024/07/13 07:55:12 env.go:30: [WARN]python lib path /usr/lib/python3.10 is not available
2024/07/13 07:55:12 env.go:30: [WARN]python lib path /usr/lib/python3 is not available
2024/07/13 07:55:12 env.go:30: [WARN]python lib path /run/systemd/resolve/stub-resolv.conf is not available
2024/07/13 07:55:12 env.go:30: [WARN]python lib path /run/resolvconf/resolv.conf is not available
2024/07/13 07:55:12 server.go:55: [INFO]python dependencies sandbox initialized
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

2024/07/13 07:55:12 cocrrent.go:31: [INFO]setting max requests to 50
2024/07/13 07:55:12 cocrrent.go:13: [INFO]setting max workers to 4
[GIN-debug] POST   /v1/sandbox/run           --> github.com/langgenius/dify-sandbox/internal/controller.RunSandboxController (6 handlers)
[GIN-debug] GET    /v1/sandbox/dependencies  --> github.com/langgenius/dify-sandbox/internal/controller.GetDependencies (4 handlers)
[GIN-debug] POST   /v1/sandbox/dependencies/update --> github.com/langgenius/dify-sandbox/internal/controller.UpdateDependencies (4 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
[GIN-debug] Listening and serving HTTP on :8194
[GIN] 2024/07/13 - 07:56:03 | 401 |       3.356µs |      172.17.0.1 | GET      "/"

```


<blockquote class="twitter-tweet" data-media-max-width="800"><p lang="ja" dir="ltr">Dify-SandboxをDockerで無事に起動できたぽい！ <a href="https://t.co/dRB370dMkm">https://t.co/dRB370dMkm</a> <a href="https://t.co/Fnu7IuF8f3">pic.twitter.com/Fnu7IuF8f3</a></p>&mdash; Maki@Sunwood AI Labs. (@hAru_mAki_ch) <a href="https://twitter.com/hAru_mAki_ch/status/1812034424059646023?ref_src=twsrc%5Etfw">July 13, 2024</a></blockquote> 
### コードの実行

Dify-Sandbox APIを使用して、コードを実行します。APIのドキュメントは、GitHubリポジトリにあります。

## 貢献ガイド

Dify-Sandboxプロジェクトへの貢献を歓迎します。貢献する前に、以下のガイドラインを確認してください。

### コード構造

以下のコードファイル構造を参照すると、コードの構成をより理解しやすくなります。

```bash
[cmd/]
├── server                // サーバー起動のエントリーポイント
├── lib                   // 共有ライブラリのエントリーポイント
└── test                  // 一般的なテストスクリプト
[build/]                  // 各種アーキテクチャとプラットフォーム用のビルドスクリプト
[internal/]               // 内部パッケージ
├── controller            // HTTPリクエストハンドラ
├── middleware            // リクエスト処理用ミドルウェア
├── server                // サーバーのセットアップと設定
├── service               // コントローラー用のサービス提供
├── static                // 設定ファイル
│   ├── nodejs_syscall    // Node.jsシステムコールのホワイトリスト
│   └── python_syscall    // Pythonシステムコールのホワイトリスト
├── types                 // エンティティ
├── core                  // 分離と実行のためのコアロジック
│   ├── lib               // 共有ライブラリ
│   ├── runner            // コード実行
│   │   ├── nodejs        // Node.jsランナー
|   |   └── python        // Pythonランナー
└── tests                 // CI/CD用のテスト
```

### 原理

現在、コアロジックには2つの主要なエントリーポイントがあります。1つはDifySandboxのHTTPサービスエントリーポイント、もう1つは動的リンクライブラリのエントリーポイントです。Sandboxがコードを実行する際、まず一時的なコードファイルが生成されます。このファイルの冒頭で動的リンクライブラリを呼び出して実行環境（Sandbox）を初期化し、その後にユーザーコードが実行されます。最終的に、ユーザーが提出したコードを直接実行するのではなく、この一時ファイルを実行することで、システムの安全性を確保します。

動的リンクライブラリでは、Seccomp（Secure Computing Mode）を使用してシステムコールを制限しています。許可されるシステムコールは`static`ディレクトリの`nodejs_syscall`および`python_syscall`ファイルに定義されており、ARM64とAMD64の両アーキテクチャ向けのシステムコールホワイトリストを提供しています。特別な理由がない限り、これらのファイルを変更しないでください。

## まとめ

Dify-Sandboxは、信頼できないコードを安全に実行するための効率的かつ柔軟なソリューションです。HTTP APIを使用することで、簡単にコードを実行し、結果を取得できます。詳細については、GitHubリポジトリのドキュメントを参照してください。

<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>