codetainer
building  a  browser  
  code  `sandbox`
Jen  Andre  
E4E  Conference,  Sep  2015
about me
@fun_cuddles  /  jenpire.com  /  
organizer  @BostonGoLang  
EIR  Accomplice  VC  
co-­‐founder  @threatstack,    
formerly  researcher  
@Mandiant,  @Symantec    
what is a ‘codetainer’?
“try ‘X’ in your browser”
… for all X?
inspiration
use cases
tutorials  for  APIs  
learn  programming  language  X  
training  on  UNIX  tools,  debugging,  etc  
remote  management  for  containers
requirements
flexible  &  powerful  enough  to  support  mulXple  use-­‐
cases  (programmable,  API  driven)  
self-­‐hosted  (open  source!)  
reasonably  secure-­‐able  :)
containers to the rescue!
“Docker  allows  you  to  package  an  applicaXon  with  all  
of  its  dependencies  into  a  standardized  unit  for  
so`ware  development.”
host linux system
container process
process
virtual file system
system namespaces
docker daemon/API tools
container process
process
virtual file system
system namespaces
…
process  virtualiza/on
not your parent’s virtualization
• it’s  lightweight!    
• process  containers  measured  in  terms  of  kilobytes  or  megabytes  
instead  of  GB  
• startup  measured  in  seconds,  not  minutes  
• images  are  layered  and  reusable  
• (see  DockerHub)  
• there’s  powerful  introspecXon  /  management  APIs  
• Management  is  programmable
introspection
peer  “inside”  of  containers  and  perform  acXons
codetainer architecture
codetainer
API server
loaded via
iframe
docker
API
“codetainer”
process
“codetainer”
process
“codetainer”
process
http /
websockets
sqlite
/api/v1/codetainer/{id}/attach
/api/v1/codetainer/{id}/create
/api/v1/codetainer/{id}/stop
…
components
•   “codetainer”  
•   this  is  just  a  Docker  container    
• “codetainer  image”    
•   this  is  a  Docker  image  registered  for  codetainer  use  
• “codetainer  profile”    
•   this  is  a  profile  associated  with  a  codetainer  that  
defines  its  runXme  characterisXcs  (e.g.  security)
other tools
• Go  
• Docker  APIs  wrifen  in  this  
• It’s  just  a  nice,  clean  language  you  can  be  producXve  in  quickly  
• xterm.js  
• for  rendering  terminals  in  the  browser  
• sqlite  
• for  storing  metdata  about  ‘codetainers’  
using codetainer!
starting the server
$	
  ./bin/codetainer	
  server	
  
Codetainer	
  10:34:16	
  [~INFO]	
  Initializing	
  Codetainer	
  
(0.1.0)	
  
Codetainer	
  10:34:16	
  [~INFO]	
  URL:	
  http://127.0.0.1:3000	
  
$	
  ./bin/codetainer	
  —help	
  
usage:	
  Codetainer	
  [<flags>]	
  <command>	
  [<args>	
  ...]	
  
Flags:	
  
	
  	
  -­‐-­‐help	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  Show	
  help	
  (also	
  see	
  -­‐-­‐help-­‐long	
  
and	
  -­‐-­‐help-­‐man).	
  
	
  	
  -­‐v,	
  -­‐-­‐debug	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  Enable	
  debug	
  logging.	
  
	
  	
  -­‐-­‐dev	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  Enable	
  dev	
  mode.	
  
	
  	
  -­‐q,	
  -­‐-­‐quiet	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  Remove	
  all	
  output	
  logging.	
  
step 1: create an image
• Create  your  Docker  image    
• Register  a  Docker  image  for  use  in  a  codetainer  
• POST	
  /api/v1/image
$	
  curl	
  -­‐XPOST	
  http://127.0.0.1:3000/api/v1/image	
  -­‐-­‐data	
  "id=tcpdump-­‐
demo:latest&description=hi"	
  2>	
  /dev/null	
  |	
  jq	
  .	
  
{	
  
	
  	
  "image":	
  {	
  
	
  	
  	
  	
  "id":	
  
"e5d42500e0419df4a29d1ed443de2da5c2c8d2e683cb045883b79b2e826910b0",	
  
	
  	
  	
  	
  "command":	
  "",	
  
	
  	
  	
  	
  "description":	
  "hi",	
  
	
  	
  	
  	
  "Tags":	
  [	
  
	
  	
  	
  	
  	
  	
  "tcpdump-­‐demo:latest"	
  
	
  	
  	
  	
  ],	
  
	
  	
  	
  	
  "CreatedAt":	
  "0001-­‐01-­‐01T00:00:00Z",	
  
	
  	
  	
  	
  "UpdatedAt":	
  "0001-­‐01-­‐01T00:00:00Z",	
  
	
  	
  	
  	
  "Enabled":	
  true	
  
	
  	
  }	
  
step 2: launch a codetainer
• POST	
  /api/v1/codetainer
$	
  curl	
  -­‐XPOST	
  http://127.0.0.1:3000/api/v1/codetainer/	
  -­‐-­‐data	
  
"name=tcpdump&image-­‐id=tcpdump-­‐demo:latest"	
  2>	
  /dev/null	
  |	
  jq	
  .	
  
{	
  
	
  	
  "codetainer":	
  {	
  
	
  	
  	
  	
  "id":	
  
"07fd1305dc22714ff5c005f8edb5db8bb462ff931bb94c51feab879a10cbcaa6",	
  
	
  	
  	
  	
  "name":	
  "tcpdump",	
  
	
  	
  	
  	
  "image-­‐id":	
  
"e5d42500e0419df4a29d1ed443de2da5c2c8d2e683cb045883b79b2e826910b0",	
  
	
  	
  	
  	
  "Defunct":	
  false,	
  
	
  	
  	
  	
  "Running":	
  false,	
  
	
  	
  	
  	
  "Profile":	
  "",	
  
	
  	
  	
  	
  "CreatedAt":	
  "0001-­‐01-­‐01T00:00:00Z",	
  
	
  	
  	
  	
  "UpdatedAt":	
  "0001-­‐01-­‐01T00:00:00Z"	
  
	
  	
  }	
  
step 3: interact with it!
• /api/v1/codetainer/{id}/attach	
  (attach	
  via	
  websockets)	
  
• /api/v1/codetainer/{id}/view	
  (render	
  terminal	
  view)	
  
• /api/v1/codetainer/{id}/send	
  (send	
  keystrokes)
more!
• List/Upload/Download  files  in  a  codetainer  
• GET	
  /api/v1/codetainer/{id}/files	
  
• GET	
  /api/v1/codetainer/{id}/files/
download	
  
• PUT	
  /api/v1/codetainer/{id}/files/upload
command-line too
$	
  ./bin/codetainer	
  list	
  
Found	
  2	
  codetainers.	
  
-­‐-­‐	
  [4505c3c844a46f4966280cd6762d3512ba8c04ebd5cb550ba90732c11a5514ee]	
  
lRf9QWOrhAYbNf4_PUdZ58DtKpfmTihu	
  (Running)	
  
-­‐-­‐	
  [c2fce38a8ba86caf0e3f1462177809f14d905c26e3cd04ac907d7d18ad9a63f0]	
  
R0bZK2O-­‐1SWsoTp7a2gas1-­‐cHjnFIlf_	
  (Running)	
  
$	
  ./bin/codetainer	
  image	
  register	
  ubuntu:14.04	
  
Codetainer	
  08:01:31	
  [~INFO]	
  Registering	
  New	
  Image:	
  
&{91e54dfb11794fad694460162bf0cb0a4fa710cfa3f60979c177d920813e	
  
	
  267c	
  	
  	
  [ubuntu:14.04]	
  0001-­‐01-­‐01	
  00:00:00	
  +0000	
  UTC	
  0001-­‐01-­‐01	
  
00:00:00	
  +0000	
  UTC	
  true}	
  
odetainer	
  08:01:31	
  [~INFO]	
  Registration	
  succeeded.
challenges
Dealing  with  missing  introspecXon  APIs  (e.g.  file  lisXng)  
minimize  risk  of  abuse  by  ‘sandboxing’  what  a  
container  can  do
Docker Security Knobs
{	
  
	
  	
  "Config":	
  {	
  
	
  	
  	
  	
  "NetworkDisabled":	
  true	
  
	
  	
  },	
  
	
  	
  "HostConfig":	
  {	
  
	
  	
  	
  	
  "Privileged":	
  false,	
  
	
  	
  	
  	
  "ReadonlyRootfs":	
  true,	
  
	
  	
  	
  	
  "Memory":	
  1000000000,	
  
	
  	
  	
  	
  "Ulimits":	
  [{	
  "Name":	
  "nofile",	
  "Soft":	
  
1024,	
  "Hard":	
  2048	
  }]	
  
	
  	
  }	
  
limiting a codetainer’s permissions using
profiles
$	
  ./bin/codetainer	
  profile	
  register	
  ./
secure.json	
  secure	
  
2015/09/18	
  10:52:54	
  Created	
  profile	
  with	
  
id=767653c7-­‐8fb6-­‐4f78-­‐bfcf-­‐3853bbe6df64:	
  
2015/09/18	
  10:52:54	
  -­‐-­‐	
  
2015/09/18	
  10:52:54	
  {	
  
	
  	
  "Config":	
  {	
  
	
  	
  	
  "NetworkDisabled":	
  true	
  
	
  	
  },	
  
	
  	
  "HostConfig":	
  {	
  
• pass	
  codetainer-­‐profile-­‐id	
  to	
  POST	
  /api/v1/
codetainer	
  when	
  creating	
  a	
  codetainer
secure.json
Missing APIs
• Docker  has  an  API  to  ‘exec’  processes  in  the  context  
of  a  container.  
• SoluXon:  mount  all  codetainers  with  a  shared  “/
codetainer/uXls”  volume  with  custom  tools.  
• Example:  /api/v1/codetainer/{id}/files    
• Executes  /codetainer/uXls/files    —path  <path>    
• returns  JSON  path  lisXng
demo time!
• creaXng  a  codetainer  
• lsof  tutorial
status
• “Alpha”  -­‐  works  but  needs  a  lifle  more  ‘umph’  to  
make  it  producXon  ready    
• Auth  for  API  
• DocumentaXon,  documentaXon,  documentaiton  
• TesXng
contribute!
github.com/codetainerapp/codetainer
jandre@gmail.com  or  @fun_cuddles  on  twifer
or just say hi…

Codetainer: a Docker-based browser code 'sandbox'

  • 1.
    codetainer building  a  browser   code  `sandbox` Jen  Andre   E4E  Conference,  Sep  2015
  • 2.
    about me @fun_cuddles  / jenpire.com  /   organizer  @BostonGoLang   EIR  Accomplice  VC   co-­‐founder  @threatstack,     formerly  researcher   @Mandiant,  @Symantec    
  • 3.
    what is a‘codetainer’?
  • 4.
    “try ‘X’ inyour browser”
  • 5.
  • 6.
  • 7.
    use cases tutorials  for APIs   learn  programming  language  X   training  on  UNIX  tools,  debugging,  etc   remote  management  for  containers
  • 8.
    requirements flexible  &  powerful enough  to  support  mulXple  use-­‐ cases  (programmable,  API  driven)   self-­‐hosted  (open  source!)   reasonably  secure-­‐able  :)
  • 9.
  • 10.
    “Docker  allows  you to  package  an  applicaXon  with  all   of  its  dependencies  into  a  standardized  unit  for   so`ware  development.” host linux system container process process virtual file system system namespaces docker daemon/API tools container process process virtual file system system namespaces … process  virtualiza/on
  • 11.
    not your parent’svirtualization • it’s  lightweight!     • process  containers  measured  in  terms  of  kilobytes  or  megabytes   instead  of  GB   • startup  measured  in  seconds,  not  minutes   • images  are  layered  and  reusable   • (see  DockerHub)   • there’s  powerful  introspecXon  /  management  APIs   • Management  is  programmable
  • 12.
    introspection peer  “inside”  of containers  and  perform  acXons
  • 13.
    codetainer architecture codetainer API server loadedvia iframe docker API “codetainer” process “codetainer” process “codetainer” process http / websockets sqlite /api/v1/codetainer/{id}/attach /api/v1/codetainer/{id}/create /api/v1/codetainer/{id}/stop …
  • 14.
    components •  “codetainer”  •  this  is  just  a  Docker  container     • “codetainer  image”     •  this  is  a  Docker  image  registered  for  codetainer  use   • “codetainer  profile”     •  this  is  a  profile  associated  with  a  codetainer  that   defines  its  runXme  characterisXcs  (e.g.  security)
  • 15.
    other tools • Go  • Docker  APIs  wrifen  in  this   • It’s  just  a  nice,  clean  language  you  can  be  producXve  in  quickly   • xterm.js   • for  rendering  terminals  in  the  browser   • sqlite   • for  storing  metdata  about  ‘codetainers’  
  • 16.
  • 17.
    starting the server $  ./bin/codetainer  server   Codetainer  10:34:16  [~INFO]  Initializing  Codetainer   (0.1.0)   Codetainer  10:34:16  [~INFO]  URL:  http://127.0.0.1:3000   $  ./bin/codetainer  —help   usage:  Codetainer  [<flags>]  <command>  [<args>  ...]   Flags:      -­‐-­‐help                              Show  help  (also  see  -­‐-­‐help-­‐long   and  -­‐-­‐help-­‐man).      -­‐v,  -­‐-­‐debug                    Enable  debug  logging.      -­‐-­‐dev                                Enable  dev  mode.      -­‐q,  -­‐-­‐quiet                    Remove  all  output  logging.  
  • 18.
    step 1: createan image • Create  your  Docker  image     • Register  a  Docker  image  for  use  in  a  codetainer   • POST  /api/v1/image $  curl  -­‐XPOST  http://127.0.0.1:3000/api/v1/image  -­‐-­‐data  "id=tcpdump-­‐ demo:latest&description=hi"  2>  /dev/null  |  jq  .   {      "image":  {          "id":   "e5d42500e0419df4a29d1ed443de2da5c2c8d2e683cb045883b79b2e826910b0",          "command":  "",          "description":  "hi",          "Tags":  [              "tcpdump-­‐demo:latest"          ],          "CreatedAt":  "0001-­‐01-­‐01T00:00:00Z",          "UpdatedAt":  "0001-­‐01-­‐01T00:00:00Z",          "Enabled":  true      }  
  • 19.
    step 2: launcha codetainer • POST  /api/v1/codetainer $  curl  -­‐XPOST  http://127.0.0.1:3000/api/v1/codetainer/  -­‐-­‐data   "name=tcpdump&image-­‐id=tcpdump-­‐demo:latest"  2>  /dev/null  |  jq  .   {      "codetainer":  {          "id":   "07fd1305dc22714ff5c005f8edb5db8bb462ff931bb94c51feab879a10cbcaa6",          "name":  "tcpdump",          "image-­‐id":   "e5d42500e0419df4a29d1ed443de2da5c2c8d2e683cb045883b79b2e826910b0",          "Defunct":  false,          "Running":  false,          "Profile":  "",          "CreatedAt":  "0001-­‐01-­‐01T00:00:00Z",          "UpdatedAt":  "0001-­‐01-­‐01T00:00:00Z"      }  
  • 20.
    step 3: interactwith it! • /api/v1/codetainer/{id}/attach  (attach  via  websockets)   • /api/v1/codetainer/{id}/view  (render  terminal  view)   • /api/v1/codetainer/{id}/send  (send  keystrokes)
  • 21.
    more! • List/Upload/Download  files in  a  codetainer   • GET  /api/v1/codetainer/{id}/files   • GET  /api/v1/codetainer/{id}/files/ download   • PUT  /api/v1/codetainer/{id}/files/upload
  • 22.
    command-line too $  ./bin/codetainer  list   Found  2  codetainers.   -­‐-­‐  [4505c3c844a46f4966280cd6762d3512ba8c04ebd5cb550ba90732c11a5514ee]   lRf9QWOrhAYbNf4_PUdZ58DtKpfmTihu  (Running)   -­‐-­‐  [c2fce38a8ba86caf0e3f1462177809f14d905c26e3cd04ac907d7d18ad9a63f0]   R0bZK2O-­‐1SWsoTp7a2gas1-­‐cHjnFIlf_  (Running)   $  ./bin/codetainer  image  register  ubuntu:14.04   Codetainer  08:01:31  [~INFO]  Registering  New  Image:   &{91e54dfb11794fad694460162bf0cb0a4fa710cfa3f60979c177d920813e    267c      [ubuntu:14.04]  0001-­‐01-­‐01  00:00:00  +0000  UTC  0001-­‐01-­‐01   00:00:00  +0000  UTC  true}   odetainer  08:01:31  [~INFO]  Registration  succeeded.
  • 23.
    challenges Dealing  with  missing introspecXon  APIs  (e.g.  file  lisXng)   minimize  risk  of  abuse  by  ‘sandboxing’  what  a   container  can  do
  • 24.
  • 25.
    {      "Config":  {          "NetworkDisabled":  true      },      "HostConfig":  {          "Privileged":  false,          "ReadonlyRootfs":  true,          "Memory":  1000000000,          "Ulimits":  [{  "Name":  "nofile",  "Soft":   1024,  "Hard":  2048  }]      }   limiting a codetainer’s permissions using profiles $  ./bin/codetainer  profile  register  ./ secure.json  secure   2015/09/18  10:52:54  Created  profile  with   id=767653c7-­‐8fb6-­‐4f78-­‐bfcf-­‐3853bbe6df64:   2015/09/18  10:52:54  -­‐-­‐   2015/09/18  10:52:54  {      "Config":  {        "NetworkDisabled":  true      },      "HostConfig":  {   • pass  codetainer-­‐profile-­‐id  to  POST  /api/v1/ codetainer  when  creating  a  codetainer secure.json
  • 26.
    Missing APIs • Docker has  an  API  to  ‘exec’  processes  in  the  context   of  a  container.   • SoluXon:  mount  all  codetainers  with  a  shared  “/ codetainer/uXls”  volume  with  custom  tools.   • Example:  /api/v1/codetainer/{id}/files     • Executes  /codetainer/uXls/files    —path  <path>     • returns  JSON  path  lisXng
  • 28.
    demo time! • creaXng a  codetainer   • lsof  tutorial
  • 29.
    status • “Alpha”  -­‐ works  but  needs  a  lifle  more  ‘umph’  to   make  it  producXon  ready     • Auth  for  API   • DocumentaXon,  documentaXon,  documentaiton   • TesXng
  • 30.