Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
matchlock — 에페머럴 마이크로VM 샌드박스로, AI 에이전트를 위한 네트워크 허용 목록, MITM 프록시를 통한 비밀 주입, VM 수준 격리를 제공합니다. 1초 미만으로 부팅되며, Go/Python/TypeScript SDK를 지원합니다. | Kitploit
도구/GitHubGitHub/jingkaihe/matchlock
Container SecuritySecurity VirtualizationNetwork SecurityCloud SecurityDevSecOpsSecret DetectionAPI SecurityAI Security
GitHubjingkaihe/matchlock

matchlock

에페머럴 마이크로VM 샌드박스로, AI 에이전트를 위한 네트워크 허용 목록, MITM 프록시를 통한 비밀 주입, VM 수준 격리를 제공합니다. 1초 미만으로 부팅되며, Go/Python/TypeScript SDK를 지원합니다.

저장소 보기
61137533개월 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
# Matchlock

> **실험적:** 이 프로젝트는 아직 활발히 개발 중이며, 변경 사항이 발생할 수 있습니다.

Matchlock는 일시적인 마이크로VM에서 AI 에이전트를 실행하기 위한 CLI 도구입니다. 네트워크 허용 목록, MITM 프록시를 통한 비밀 주입, VM 수준 격리를 제공합니다. 사용자의 비밀은 VM에 절대 들어가지 않습니다.

## Matchlock을 사용하는 이유

AI 에이전트는 코드를 실행해야 하지만, 에이전트에게 머신에 대한 무제한 액세스를 허용하는 것은 위험합니다. Matchlock를 사용하면 1초 미만에 부팅되는 완전한 Linux 환경을 에이전트에 제공할 수 있습니다. 격리되어 있고 일회용입니다.

`--allow-host` 또는 `--secret`을 전달하면 Matchlock가 네트워크를 봉쇄합니다. 명시적으로 허용된 호스트로의 트래픽만 통과하고, 나머지는 모두 차단됩니다. 에이전트가 API를 호출할 때 실제 자격 증명은 호스트에 의해 전송 중에 주입됩니다. 샌드박스는 항상 자리 표시자만 볼 수 있습니다. 에이전트가 악성 코드를 실행하도록 속아도 키가 유출되지 않으며 데이터가 이동할 곳이 없습니다. 내부에서는 에이전트가 필요한 모든 작업을 수행할 수 있는 완전한 Linux 환경을 얻습니다. 패키지를 설치하고, 파일을 쓰고, 지저분하게 만들 수 있습니다. 외부에서는 사용자 머신이 아무것도 느끼지 못합니다. 볼륨 오버레이 마운트는 작업이 끝나면 사라지는 격리된 스냅샷입니다. Linux 서버든 MacBook이든 동일한 CLI와 동일한 동작을 제공합니다.

## 빠른 시작

### 시스템 요구 사항

- **Linux** (KVM 지원)
- **macOS** (Apple Silicon)

### 설치

전체 설치 세부 사항은 [`docs/install.md`](https://github.com/jingkaihe/matchlock/blob/main/docs/install.md)를 참조하세요.

**빠른 설치**

아래 스크립트는 OS를 감지하고, macOS에서는 Homebrew를 사용하여 matchlock을 설치하고, Debian/RHEL 계열 Linux 배포판에서는 rpm/deb를 사용하여 설치합니다.

```bash
curl -fsSL https://raw.githubusercontent.com/jingkaihe/matchlock/main/scripts/install.sh | bash

# Or install a specific release
curl -fsSL https://raw.githubusercontent.com/jingkaihe/matchlock/main/scripts/install.sh | bash -s -- --version 0.2.4
```

**Homebrew**

Homebrew 기반 설치는 macOS와 Linux 모두에서 지원됩니다.

```bash
brew tap jingkaihe/essentials
brew install matchlock
```

**Debian / Ubuntu (.deb)**

```bash
sudo dpkg -i ./matchlock_<version>_linux_amd64.deb
sudo apt-get install -f
matchlock diagnose
```

**Fedora / RHEL / CentOS Stream (.rpm)**

```bash
sudo dnf install ./matchlock_<version>_linux_amd64.rpm
matchlock diagnose
```

`matchlock diagnose`에서 호스트 설정이 누락되었다고 보고하면 다음을 실행하세요:

```bash
sudo matchlock setup linux
```

특정 사용자를 명시적으로 등록하려면 다음을 실행하세요:

```bash
sudo matchlock setup user <name>
```

### 사용법

```bash
# Basic
matchlock run --image alpine:latest cat /etc/os-release
matchlock run --image alpine:latest -it sh
matchlock run --image alpine:latest --no-network -- sh -lc 'echo offline'

# Network allowlist
matchlock run --image python:3.12-alpine \
  --allow-host "api.openai.com" python agent.py

# Keep interception enabled even with an empty allowlist,
# so hosts can be added/removed at runtime.
matchlock run --image alpine:latest --rm=false --network-intercept
matchlock allow-list add <vm-id> api.openai.com,api.anthropic.com
matchlock allow-list delete <vm-id> api.openai.com

# Secret injection (never enters the VM)
export ANTHROPIC_API_KEY=sk-xxx
matchlock run --image python:3.12-alpine \
  --secret [email protected] python call_api.py

# Long-lived sandboxes
matchlock run --image alpine:latest --rm=false   # prints VM ID
matchlock run --image nginx:latest -d             # same as above, detached
matchlock exec vm-abc12345 -it sh                # attach to it
matchlock port-forward vm-abc12345 8080:8080     # forward host:8080 -> guest:8080

# Publish ports at startup
matchlock run --image alpine:latest --rm=false -p 8080:8080

# Lifecycle
matchlock list | kill | rm | prune

# Build from Dockerfile (uses BuildKit-in-VM)
matchlock build -f Dockerfile -t myapp:latest .

# Pre-build rootfs from registry image (caches for faster startup)
matchlock build alpine:latest

# Image management
matchlock image ls                                           # List all images
matchlock image rm myapp:latest                              # Remove a local image
docker save myapp:latest | matchlock image import myapp:latest  # Import from tarball
```

## SDK

Matchlock는 애플리케이션에 샌드박스를 직접 포함할 수 있는 Go, Python, TypeScript SDK를 제공합니다. VM을 실행하고, 명령을 실행하고, 출력을 스트리밍하고, 파일을 프로그래밍 방식으로 관리할 수 있습니다.

**Go**

```go
package main

import (
	"context"
	"fmt"
	"os"

	"github.com/jingkaihe/matchlock/pkg/sdk"
)

func main() {
	ctx := context.Background()

	client, err := sdk.NewClient(sdk.DefaultConfig())
	if err != nil {
		panic(err)
	}
	defer client.Close(0)
	defer client.Remove()

	sandbox := sdk.New("alpine:latest").
		AllowHost("dl-cdn.alpinelinux.org", "api.anthropic.com").
		AddSecret("ANTHROPIC_API_KEY", os.Getenv("ANTHROPIC_API_KEY"), "api.anthropic.com")
	if _, err := client.Launch(sandbox); err != nil {
		panic(err)
	}
	if _, err := client.Exec(ctx, "apk add --no-cache curl"); err != nil {
		panic(err)
	}
	// The VM only ever sees a placeholder - the real key never enters the sandbox
	result, err := client.Exec(ctx, "echo $ANTHROPIC_API_KEY")
	if err != nil {
		panic(err)
	}
	fmt.Print(result.Stdout) // prints "SANDBOX_SECRET_a1b2c3d4..."

	curlCmd := `curl -s --no-buffer https://api.anthropic.com/v1/messages \
  -H "content-type: application/json" \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -d '{"model":"claude-haiku-4-5-20251001","max_tokens":1024,"stream":true,
       "messages":[{"role":"user","content":"Explain TCP to me"}]}'`
	if _, err := client.ExecStream(ctx, curlCmd, os.Stdout, os.Stderr); err != nil {
		panic(err)
	}
}
```

Go SDK 개인 IP 동작 (`10/8`, `172.16/12`, `192.168/16`):

- 기본값(설정되지 않음): 네트워크 구성이 전송될 때마다 개인 IP가 차단됩니다.
- 명시적 차단: `.WithBlockPrivateIPs(true)` (또는 `.BlockPrivateIPs()`) 호출
- 명시적 허용: `.AllowPrivateIPs()` 또는 `.WithBlockPrivateIPs(false)` 호출

```go
sandbox := sdk.New("alpine:latest").
	AllowHost("api.openai.com").
	AddHost("api.internal", "10.0.0.10").
	WithNetworkMTU(1200).
	AllowPrivateIPs() // explicit override: block_private_ips=false

// SDK network interception (request/response mutation, body shaping, SSE data-line transform)
sandbox = sandbox.WithNetworkInterception(&sdk.NetworkInterceptionConfig{
	Rules: []sdk.NetworkHookRule{
		{
			Phase:      sdk.NetworkHookPhaseBefore,
			Action:     sdk.NetworkHookActionMutate,
			Hosts:      []string{"api.openai.com"},
			SetHeaders: map[string]string{"X-Trace-Id": "trace-123"},
		},
		{
			Phase:  sdk.NetworkHookPhaseAfter,
			Action: sdk.NetworkHookActionMutate,
			Hosts:  []string{"api.openai.com"},
			BodyReplacements: []sdk.NetworkBodyTransform{
				{Find: "internal-id", Replace: "redacted"},
			},
		},
	},
})
```

빌더 없이 `client.Create(...)`를 직접 사용하는 경우 다음을 설정하세요:
- `BlockPrivateIPsSet: true`
- `BlockPrivateIPs: false` (또는 `true`)

완전 오프라인 샌드박스(게스트 NIC 없음/송신 없음)의 경우 다음을 사용하세요:
- CLI: `--no-network`
- Go SDK 빌더: `.WithNoNetwork()`
- Python SDK 빌더: `.with_no_network()`
- TypeScript SDK 빌더: `.withNoNetwork()`

**Python** ([PyPI](https://pypi.org/project/matchlock/))

```bash
pip install matchlock
# or
uv add matchlock
```

```python
import os
import sys

from matchlock import Client, Sandbox

sandbox = (
    Sandbox("python:3.12-alpine")
    .allow_host(
        "dl-cdn.alpinelinux.org",
        "files.pythonhosted.org", "pypi.org",
        "astral.sh", "github.com", "objects.githubusercontent.com",
        "api.anthropic.com",
    )
    .add_secret(
        "ANTHROPIC_API_KEY", os.environ["ANTHROPIC_API_KEY"], "api.anthropic.com"
    )
)

SCRIPT = """\
# /// script
# requires-python = ">=3.12"
# dependencies = ["anthropic"]
# ///
import anthropic, os

client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
with client.messages.stream(
    model="claude-haiku-4-5-20251001",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Explain TCP/IP."}],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
print()
"""

with Client() as client:
    client.launch(sandbox)
    client.exec("pip install --quiet uv")
    client.write_file("/workspace/ask.py", SCRIPT)
    client.exec_stream("uv run /workspace/ask.py", stdout=sys.stdout, stderr=sys.stderr)

client.remove()
```

**TypeScript**

```bash
npm install matchlock-sdk
```

```ts
import { Client, Sandbox } from "matchlock-sdk";

const SCRIPT = `import Anthropic from "@anthropic-ai/sdk";

const anthropic = new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY,
});

const stream = anthropic.messages
  .stream({
    model: "claude-haiku-4-5-20251001",
    max_tokens: 1024,
    messages: [{ role: "user", content: "Explain TCP/IP." }],
  })
  .on("text", (text) => {
    process.stdout.write(text);
  });

await stream.finalMessage();
process.stdout.write("\\n");
`;

const client = new Client();
try {
  const sandbox = new Sandbox("node:22-alpine")
    .allowHost("registry.npmjs.org", "*.npmjs.org", "api.anthropic.com")
    .addSecret("ANTHROPIC_API_KEY", process.env.ANTHROPIC_API_KEY ?? "", "api.anthropic.com");

  await client.launch(sandbox);
  await client.exec(
    "npm init -y >/dev/null 2>&1 && npm install --quiet --no-bin-links @anthropic-ai/sdk",
    { workingDir: "/workspace" },
  );
  await client.writeFile("/workspace/ask.mjs", SCRIPT);
  await client.execStream("node ask.mjs", {
    workingDir: "/workspace",
    stdout: process.stdout,
    stderr: process.stderr,
  });
} finally {
  await client.close();
  await client.remove();
}
```

더 많은 예제는 [`examples/`](https://github.com/jingkaihe/matchlock/blob/main/examples) 디렉토리에서 확인하세요:

| 설명 | 예제 |
|---|---|
| 비밀 주입을 사용한 Anthropic API 응답 스트리밍 (Go) | [`examples/go/basic/`](https://github.com/jingkaihe/matchlock/blob/main/examples/go/basic) |
| ExecInteractive를 사용한 PTY 대화형 터미널 (Go) | [`examples/go/exec_modes/`](https://github.com/jingkaihe/matchlock/blob/main/examples/go/exec_modes) |
| 네트워크 인터셉션 훅을 통한 API 키 주입 (Go) | [`examples/go/network_interception/`](https://github.com/jingkaihe/matchlock/blob/main/examples/go/network_interception) |
| 파일 작업 변형을 위한 VFS 인터셉션 훅 (Go) | [`examples/go/vfs_hooks/`](https://github.com/jingkaihe/matchlock/blob/main/examples/go/vfs_hooks) |
| Anthropic API 응답 스트리밍 (Python) | [`examples/python/basic/`](https://github.com/jingkaihe/matchlock/blob/main/examples/python/basic) |
| 스트림, 파이프 및 대화형 실행 모드 (Python) | [`examples/python/exec_modes/`](https://github.com/jingkaihe/matchlock/blob/main/examples/python/exec_modes) |
| 네트워크 인터셉션 훅을 통한 API 키 주입 (Python) | [`examples/python/network_interception/`](https://github.com/jingkaihe/matchlock/blob/main/examples/python/network_interception) |
| 파일 작업 변형을 위한 VFS 인터셉션 훅 (Python) | [`examples/python/vfs_hooks/`](https://github.com/jingkaihe/matchlock/blob/main/examples/python/vfs_hooks) |
| Anthropic API 응답 스트리밍 (TypeScript) | [`examples/typescript/basic/`](https://github.com/jingkaihe/matchlock/blob/main/examples/typescript/basic) |
| 스트림, 파이프 및 대화형 실행 모드 (TypeScript) | [`examples/typescript/exec_modes/`](https://github.com/jingkaihe/matchlock/blob/main/examples/typescript/exec_modes) |
| 네트워크 인터셉션 훅을 통한 API 키 주입 (TypeScript) | [`examples/typescript/network_interception/`](https://github.com/jingkaihe/matchlock/blob/main/examples/typescript/network_interception) |
| GitHub 부트스트랩을 사용한 마이크로VM의 Claude Code CLI | [`examples/claude-code/`](https://github.com/jingkaihe/matchlock/blob/main/examples/claude-code) |
| SDK를 통한 샌드박스 내 Docker를 사용한 Claude Code | [`examples/claude-code-with-docker/`](https://github.com/jingkaihe/matchlock/blob/main/examples/claude-code-with-docker) |
| 샌드박스에서 Claude Pro/Max 구독을 사용한 Claude Code | [`examples/claude-danger/`](https://github.com/jingkaihe/matchlock/blob/main/examples/claude-danger) |
| GitHub 부트스트랩을 사용한 마이크로VM의 OpenAI Codex CLI | [`examples/codex/`](https://github.com/jingkaihe/matchlock/blob/main/examples/codex) |
| systemd를 사용한 샌드박스 내 Docker 데몬 | [`examples/docker-in-sandbox/`](https://github.com/jingkaihe/matchlock/blob/main/examples/docker-in-sandbox) |
| Agent Client Protocol을 사용한 Streamlit 챗봇 | [`examples/agent-client-protocol/`](https://github.com/jingkaihe/matchlock/blob/main/examples/agent-client-protocol) |
| Kodelet 및 Playwright MCP를 사용한 브라우저 자동화 | [`examples/playwright/`](https://github.com/jingkaihe/matchlock/blob/main/examples/playwright) |

## 아키텍처

```mermaid
graph LR
    subgraph Host
        CLI["Matchlock CLI"]
        Policy["Policy Engine"]
        Proxy["Transparent Proxy + TLS MITM"]
        VFS["VFS Server"]

        CLI --> Policy
        CLI --> Proxy
        Policy --> Proxy
    end

    subgraph VM["Micro-VM (Firecracker / Virtualization.framework)"]
        Agent["Guest Agent"]
        FUSE["/workspace (FUSE)"]
        Image["Any OCI Image (Alpine, Ubuntu, etc.)"]

        Agent --- Image
        FUSE --- Image
    end

    Proxy -- "vsock :5000" --> Agent
    VFS -- "vsock :5001" --> FUSE
```

### 네트워크 모드

| 플랫폼 | 모드 | 메커니즘 |
|----------|------|-----------|
| Linux | 투명 프록시 | 포트 80/443의 nftables DNAT |
| macOS | NAT (기본값) | Virtualization.framework 내장 NAT |
| macOS | 인터셉션 (`--allow-host`/`--secret` 사용 시) | L4의 gVisor 사용자 공간 TCP/IP |

## 문서

- [수명 주기 및 정리 런북](https://github.com/jingkaihe/matchlock/blob/main/docs/lifecycle.md)
- [네트워크 인터셉션](https://github.com/jingkaihe/matchlock/blob/main/docs/network-interception.md)
- [VFS 인터셉션](https://github.com/jingkaihe/matchlock/blob/main/docs/vfs-interception.md)
- [개발자 참조](https://github.com/jingkaihe/matchlock/blob/main/AGENTS.md)

## 라이선스

MIT
도구 다운로드