Når man nu skal køre usikker kode…

Jeg hyggekoder lidt på et projekt hvor deltagerne skal kode en AI, som
så skal konkurrere mod hinanden. Grænsefladen er at deltageren skal
skrive en funktion i sproget X som tager et argument der repræsenterer
spillets tilstand og returnerer et enkelt træk.

I gamle dage ville man nok have udvist tillid til at deltageren højst
bøjede reglerne inden for rimelighedens grænser. Sådan fungerer det
desvære ikke i dag, hvor det vil opfattes som en direkte indbydelse til
at hacke min maskine.

En mulig vej er at vælge sproget X så det er tilpas restriktivt til at
det ikke kan gøre nogen skade. Det kan enten være et legetøjssprog eller
en tilpas lille delmængde af et eksisterende sprog man kan lave en
statisk analyse af. Begge dele vil dog øge omfanget af projektet
betragteligt.

I den anden grøft kan man køre hver enkelt AI i en separat virtuel
maskine sat op til formålet. Hvis AI'en vælger at ødelægge den virtuelle
maskine har den bare tabt, men ellers lider hverken jeg eller
konkurrencen nogen skade. Med moderne provisionerings-tools er det
faktisk en overkomelig vej at gå.

I stedet for virtualisering af en fuld maskine har jeg dog valgt at
bruge Linux Containers (LXC), som er en
udvidet chroot funktionalitet (ala vserver og jails).

Med LXC kan jeg som upriviligeret bruger starte en process som ikke kan
se andre processer end sig selv om en init-ligende process, ikke kan se
noget netværk og kun har adgang til det filhierarki jeg har givet den
adgang til. For lethedens skyld har jeg valgt at lade /etc, /home, /tmp
og /var være stort set tomme, mens /bin, /lib og /usr er mountet
read-only fra mit rigtige filhierarki.

Dermed håber jeg trygt at jeg kan køre den kode som deltageren kaster
efter mit projekt.

Det meste af min opsætning kan findes på
gist.github.com
hvor der også er konkrete eksempler på kommandoer og jeg har haft glæde
af at læse Stéphane Grabers blogserie om
LXC
,
især afsnit 7.

Kommentarer (22)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
#4 Morten Hansen

Tak for en god artikel, Peter. "Jeg hyggekoder lidt på et projekt hvor deltagerne skal kode en AI, som så skal konkurrere mod hinanden." Er det et lukket forum, eller minder det noget om BattleCode, du hyggekoder. Hvis andre herinde har lignende sider, modtages er jeg da lidt nysgærrig. Godt at holde sig selv lidt i form :-)

  • 1
  • 0
#5 Peter Makholm Blogger

Gør Docker ikke stort det samme?

I forhold til grænsefladen, jo.

Docker er et af de provisionerings-tools der gør det overkommeligt at bruge "rigtig" virtualisering. Ud fra et udviklingsperspektiv kommer det ud på et om man skal bruge din kommando eller man skal bruge

lxc-execute -n sandbox -q -- bash

Resten af den opsætning jeg har liggende på github svare stort set til at lave et specialiseret image. Så derfor tror jeg som udgangspunkt hverken Docker er lettere eller svære at arbejde med, i hvert fald ikke til min brug.

  • 1
  • 0
#6 Peter Makholm Blogger

Kører node.js, koden bliver dræbt hvis den kører mere end 3 sekunder.

Javascript er ikke lige min kop te. Jeg har selvfølgelig et konkret sprog i tankerne, men en del af den interessante udfordring er også at lave det forholdsvist sprog-agnostisk. Det sætter selvfølgelig nogle yderligere krav til grænsefladen som jeg ikke kommer ind på i blogindlæget.

Som hyggeprojekt drejer det sig heller ikke om at opfinde noget nyt og revolutionerende. Derfor er det helt fint at genopfinde tallerkener, hvis altså det er sjovt og lærerigt. Det jeg i processen lærer om LXC kan selvfølgelig genbruges i en række andre projekter hvor den færdige løsning ikke umidelbart passer ind. Måske endda jeg en dag ville blive involveret i en konkurrent til Amazon Lambda og så er det rart at kende til de underliggende teknologier.

  • 0
  • 0
#9 Allan Ebdrup Blogger

Javascript er et sprog de fleste kun koder af nød. Jeg synes letvægts-virtualisering med LXC virker som den helt rigtige fremgangsmåde her.

Tja, vores maskinlæringsekspert skrev for nylig en kategoriserings-løsning og han påstod at han kunne gøre det mindst dobbelt så hurtigt i Node.js end de sprog han plejer at bruge til den slags.

Men det afhænger nok af hvad det er man skal kode.

  • 1
  • 0
#10 Michael Zedeler

Tja, vores maskinlæringsekspert skrev for nylig en kategoriserings-løsning og han påstod at han kunne gøre det mindst dobbelt så hurtigt i Node.js end de sprog han plejer at bruge til den slags.

Det lyder direkte sært. Node.js har da ingen særlige optimeringstricks, man ikke også kan bruge i andre tilsvarende sprog. Jeg kunne vældig godt tænke mig at høre mere om præcis hvad det er, han mener :-)

  • 1
  • 0
#11 Peter Makholm Blogger

Lyder rimeligt nok, men kan du klare dig helt uden de der konfigurationsfiler?

Ikke helt.

Skal man anvende lxc som upriviligeret bruger, så er det nok i hvert fald nødvendigt at administrator har sat uid- og gid-ranges af i henholdsvis /etc/subuid og /etc/subgid. Jeg tror også at lxc forventer at få eksplicit at vide hvile uid/gid-maps den skal sætte op.

Template-filen svare lidt til en Dockerfile. Er det så mere eller mindre konfiguration end et Dockerimage? Der følger også nogle eksisterende templates med en standard lxc-installation. Hvad jeg brugt den template der hedder lxc-download.template ville det nok svare meget godt til dit docker-eksempel (bortset fra at docker laver nogle smarte ting med image layers bag om ryggen på dig).

Så nej, jeg kommer ikke helt uden om konfiguration, men jeg kan komme tæt på alt efter hvad du betragter som konfiguration.

  • 0
  • 0
#12 Torben Mogensen Blogger

En mulig vej er at vælge sproget X så det er tilpas restriktivt til at det ikke kan gøre nogen skade. Det kan enten være et legetøjssprog eller en tilpas lille delmængde af et eksisterende sprog man kan lave en statisk analyse af. Begge dele vil dog øge omfanget af projektet betragteligt.

I min erfaring tager det ikke mere end en dags tid at lave en fortolker eller compiler for et brugbart (men ikke avanceret) sprog, hvis targetsproget er et højniveausprog (f.eks. ML), og hvis man laver syntaksen så tilpas enkel, at man ikke skal lave alt for mange Ninja-tricks for at få mosml-yacc e.lign. til at parse det entydigt. Specielt hvis sprogets faciliteter kan mappes mere eller mindre direkte til målsprogets ditto.

  • 0
  • 0
#13 Troels Henriksen

Tja, vores maskinlæringsekspert skrev for nylig en kategoriserings-løsning og han påstod at han kunne gøre det mindst dobbelt så hurtigt i Node.js end de sprog han plejer at bruge til den slags.

Maskinlæring laves ofte i Matlab, som er ret langsomt hvis ikke man gør omfattende brug af de indbyggede biblioteker (som er skrevet i Fortran og C). Det samme gør sig gældende for R og til dels Python, som også nyder nogen anvendelse til maskinlæring. V8 (det har ikke noget at gøre med Node.js) er rimeligt hurtigt i forhold til notorisk dårlige sprog, men er ikke derudover spektakulært. For et par år siden mødte vi Lars Bak til GOTO, og han forklarede at de med Darts VM havde fået lige så god ydelse som V8, men med langt mindre kode og mindre implementeringstid. Det kan selvfølgelig have været ren markedsføring.

Derudover var min pointe nu ikke omkring Javascripts ydelse, men hvilken nydelse det bibringer at bruge det.

Iøvrigt har Torben ret - det er nemt at lave et enkelt højniveausprog. Jeg vil dog ikke anbefale SML som målsprog, da gængse implementeringer typisk ikke er for hurtige.

  • 0
  • 0
#14 Jacob Christian Munch-Andersen

Derudover var min pointe nu ikke omkring Javascripts ydelse, men hvilken nydelse det bibringer at bruge det.

Min umiddelbare fornemmelse om JavaScripts ry er at 90% af grunden til at folk mener at det er dårligt stammer fra alle de andre ting der er galt med HTML, HTTP, CSS og browsere generelt.

Personligt finder jeg at JavaScript er et af de allerletteste sprog at arbejde med, det giver nydelse. Browser-stakken er en helt anden sag ...

  • 1
  • 0
#15 Peter Andersen
  • 1
  • 0
#16 Allan Ebdrup Blogger

Det lyder direkte sært. Node.js har da ingen særlige optimeringstricks, man ikke også kan bruge i andre tilsvarende sprog. Jeg kunne vældig godt tænke mig at høre mere om præcis hvad det er, han mener :-)

Jeg prøver at spørge ham, men umiddelbart tror jeg bare det var JavaScripts dynamiske natur der var fordelen. Og det at han nemt kunne finde nogle node.js moduler til wordstemming.

  • 0
  • 0
#17 Fini Alring

Jeg arbejdede på et lign. projekt for ca. ti år siden hvor jeg lavede en slags AI game platform, hvor flere AI'er kunne dyste imod hinanden. Platformen understøttede at man kunne implementere forskellige spil og dertilhørende specifikke api'er (fodbold, gemmeleg, labyrint osv.). Det hele blev kodet i java men tanken var at det hele kørte igennem web service api endpoints og server delen fungerede også som "dommer" og kunne validere inputs fra spillerne og throttle så alle spillerne kun kunne lave det samme antal moves i sekundet m.v. (så en bold f.eks kun kunne sparkes indenfor den givne hastighedgrænse). Dermed kan alle sprog benyttes til at skabe spillere og sikkerheden (ifht. snyd) var let at holde under kontrol.

Desværre fik jeg kun publiceret en kedelig demo version, men har i mange år overvejet at genskabe projektet i node.js. JavaScript er genialt til den slags opgaver ;)

  • 0
  • 0
#18 Peter Makholm Blogger

Desværre fik jeg kun publiceret en kedelig demo version, men har i mange år overvejet at genskabe projektet i node.js. JavaScript er genialt til den slags opgaver ;)

Det lyder ganske rigtigt meget tilsvarende.

Antag at jeg ikke har nogen forudindtaget mening om JavaScript og lad os glemme de dårlige oplevelser vi alle har med JavaScript på grund af at vi skal understøtte forskellige dialekter af både sprog og standard library og at DOM-manipulation, som mange af os mest har brugt javascript til, i virkeligheden er en totalt nederen opgave. Hvorfor er det så at JavaScript er genialt at bruge til denne slags opgaver?

  • 0
  • 0
#19 Fini Alring

Ja det var måske lidt forudindtaget.. Jeg har elsket JavaScript siden jeg opdagede det i Netscape back in 1995 ;)

Der er en hel del produktivitet at hente ved at oprette api'er og lign. via JavaScript/Node og f.eks Express. Desuden er sproget meget fleksibelt ifht. at kunne lege med koden istedet for at være bundet ned af den. Det er selvfølgelig en smagssag, og ligeså meget gælder det om hvad man skal bruge koden til på længere sigt.

Uden at være ekspert i AI kode, synes jeg at JavaScript egner sig godt til formålet, pga. lambda, community, performance og fleksibilitet. Men jeg ser systemet i flere dele; system delen og ai delen. Hvis systemet er som jeg beskrev kan AI koden skrives i et hvilket som helst sprog.

Faldt iøvrigt over denne: http://javascriptbattle.com/

  • 0
  • 0
#20 Dan Rasmussen

Hurtig udvikling skal ikke forveksles med hurtig afvikling. Node.js er glimrende for prototyping, da man udvikler i et script sprog, som nemt giver adgang til mange velfungerende open-source moduler. Samtidig performer node også fint, så det kan bruges i produktion. Jeg er overbevist om at andre tilsvarende sprog med en stor community har samme kvaliteter. JavaScript egner sig derimod ikke specielt godt til ressourcekrævende beregninger, til det formål vil prototyping i Matlab eller lignende programmer være et bedre valg.

  • 0
  • 0
#21 Fini Alring

Selvfølgelig skal man overveje mange faktorer. Men intet udelukker dig fra at lave en 64+ kerne assembler cloud kode der feeder en lille web service client :) Har aldrig sagt at JS er bedst i performance, men i mange usecases performer det langt bedre end f.eks .net+IIS og java+apache.

  • 1
  • 1
#22 Michael Zedeler

Template-filen svare lidt til en Dockerfile. Er det så mere eller mindre konfiguration end et Dockerimage?

Den ene linie, jeg skrev i mit oprindelige indlæg, er sådan set nok til at køre et script i en docker container. Det er ikke nødvendigt at angive en konfiguration (hverken i form af en Dockerfile eller andet).

Til gengæld er der sikkert ikke helt så mange frihedsgrader, som lxc har.

  • 0
  • 1
Log ind eller Opret konto for at kommentere