{"action":"created","issue":{"url":"https://api.github.com/repos/openwhisk/openwhisk/issues/890","repository_url":"https://api.github.com/repos/openwhisk/openwhisk","labels_url":"https://api.github.com/repos/openwhisk/openwhisk/issues/890/labels{/name}","comments_url":"https://api.github.com/repos/openwhisk/openwhisk/issues/890/comments","events_url":"https://api.github.com/repos/openwhisk/openwhisk/issues/890/events","html_url":"https://github.com/openwhisk/openwhisk/issues/890","id":165621866,"number":890,"title":"Proposal: User containers should be mounted read-only","user":{"login":"domdom82","id":1755853,"avatar_url":"https://avatars.githubusercontent.com/u/1755853?v=3","gravatar_id":"","url":"https://api.github.com/users/domdom82","html_url":"https://github.com/domdom82","followers_url":"https://api.github.com/users/domdom82/followers","following_url":"https://api.github.com/users/domdom82/following{/other_user}","gists_url":"https://api.github.com/users/domdom82/gists{/gist_id}","starred_url":"https://api.github.com/users/domdom82/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/domdom82/subscriptions","organizations_url":"https://api.github.com/users/domdom82/orgs","repos_url":"https://api.github.com/users/domdom82/repos","events_url":"https://api.github.com/users/domdom82/events{/privacy}","received_events_url":"https://api.github.com/users/domdom82/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/openwhisk/openwhisk/labels/enhancement","name":"enhancement","color":"84b6eb"},{"url":"https://api.github.com/repos/openwhisk/openwhisk/labels/invoker","name":"invoker","color":"0e8a16"}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":19,"created_at":"2016-07-14T18:00:59Z","updated_at":"2016-08-22T18:40:25Z","closed_at":null,"body":"### This is a design-proposal for security hardening of the invoker.\r\n\r\nDuring my work on AppArmor I did some research and found that it is currently very hard to enforce a disk size quota on docker containers. There are some discussions going on here https://github.com/docker/docker/issues/3804 and there is the `--device-write-bps` option in docker 1.10 which only limits throughput. We can't use docker 1.10 for stability reasons anyway.\r\n\r\n**My proposal is this:**\r\n\r\nTo prevent any action container from flooding the host filesystem we mount the container in read-only mode. Each container will be given a writable `/tmp` directory that is mounted on a tmpfs volume with a small size (e.g. 512 MB, 1 GB etc.).\r\n\r\ntmpfs is ramdisk so nothing gets written to the actual disk of the host (docker logs of course being a different issue).\r\n\r\nI have been dabbling with `docker volume` but could not get it to actually create a real tmpfs volume with a size limit. The example for tmpfs [here](https://docs.docker.com/engine/reference/commandline/volume_create/) does not work. \r\n\r\nInstead my proposal looks something like this:\r\n\r\n1. when `makeContainer` gets called, the invoker first calls `makeTmpFs(containerName)`\r\n2. makeTmpFs calls \r\n\r\n    ```\r\n    tempDir = $(maketemp -d)\r\n    mount -t tmpfs -o size=512M,mode=0700 tmpfs $tempDir\r\n    ```\r\n3. `makeContainer` then starts the action container like so\r\n\r\n    ```\r\n    docker run -d --read-only -v $tempDir:/tmp --security-stuff whisk/nodeJsAction\r\n    ```\r\n4. `rmContainer` finally does\r\n\r\n    ```\r\n    umount $tempDir\r\n    ```\r\n\r\nAdvantages:\r\n1. Increased security. Containers can not flood the host.\r\n2. Increased speed. Tmpfs is RAM, so super-fast. mount / umount takes next to no time.\r\n3. We can really enforce a disk quota for actions.\r\n\r\nTradeoff we will have to make:\r\n1. Actions can no longer write wherever they want in the container.\r\n2. Blackbox implementers need to know. So the contract must be updated.\r\n\r\n\r\nOnce we can make the switch over to docker > 1.10 we can simply use the --tmpfs option of docker run and drop the above tmpfs handler in the invoker."},"comment":{"url":"https://api.github.com/repos/openwhisk/openwhisk/issues/comments/241508825","html_url":"https://github.com/openwhisk/openwhisk/issues/890#issuecomment-241508825","issue_url":"https://api.github.com/repos/openwhisk/openwhisk/issues/890","id":241508825,"user":{"login":"domdom82","id":1755853,"avatar_url":"https://avatars.githubusercontent.com/u/1755853?v=3","gravatar_id":"","url":"https://api.github.com/users/domdom82","html_url":"https://github.com/domdom82","followers_url":"https://api.github.com/users/domdom82/followers","following_url":"https://api.github.com/users/domdom82/following{/other_user}","gists_url":"https://api.github.com/users/domdom82/gists{/gist_id}","starred_url":"https://api.github.com/users/domdom82/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/domdom82/subscriptions","organizations_url":"https://api.github.com/users/domdom82/orgs","repos_url":"https://api.github.com/users/domdom82/repos","events_url":"https://api.github.com/users/domdom82/events{/privacy}","received_events_url":"https://api.github.com/users/domdom82/received_events","type":"User","site_admin":false},"created_at":"2016-08-22T18:40:25Z","updated_at":"2016-08-22T18:40:25Z","body":"Initial benchmark testing on Docker 1.12.1 using Kernel 4.4.0-28 looks encouraging:\r\n\r\n```\r\nServer Version: 1.12.1\r\nKernel Version: 4.4.0-28-generic\r\n\r\nStorage Driver: overlay\r\nBacking Filesystem: extfs\r\nCPUs: 4\r\n\r\nFull     = docker run, pause, unpause, rm\r\nNo pause = docker run, rm\r\nSkip rm  = docker run, pause, unpause  (for testing)\r\n\r\nTable shows the rate (per sec) of a docker sequence.  Measured with 5 iterations per thread.  Error count in parens.\r\n-----------------------------------------------------------------------------------------------------------------------\r\n            1 thread   2 threads (lock)   2 threads     Speedup      3 threads     Speedup\r\nFull         2.236          2.392          3.706          1.66        4.147          1.85\r\nNo pause     2.554                         3.982          1.56        4.452          1.74\r\nSkip rm      4.334                         6.857          1.58        6.727          1.55\r\n```\r\n\r\nThe numbers are comparable to Docker 1.11 and about 50% better than Docker 1.9,\r\nThis is a single-node benchmark, not a load test on a distributed system yet. Will conduct that now."}}
{"actor":{"display_login":"domdom82"}}