{"id":13453206,"url":"https://github.com/Yelp/dockersh","last_synced_at":"2025-03-24T01:31:14.453Z","repository":{"id":18994503,"uuid":"22216394","full_name":"Yelp/dockersh","owner":"Yelp","description":"A shell which places users into individual docker containers","archived":true,"fork":false,"pushed_at":"2019-08-27T20:34:28.000Z","size":141,"stargazers_count":1276,"open_issues_count":0,"forks_count":78,"subscribers_count":87,"default_branch":"master","last_synced_at":"2025-03-12T22:35:43.841Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Yelp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-07-24T14:37:18.000Z","updated_at":"2025-01-02T01:08:17.000Z","dependencies_parsed_at":"2022-09-13T08:41:31.205Z","dependency_job_id":null,"html_url":"https://github.com/Yelp/dockersh","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yelp%2Fdockersh","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yelp%2Fdockersh/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yelp%2Fdockersh/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yelp%2Fdockersh/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Yelp","download_url":"https://codeload.github.com/Yelp/dockersh/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245194203,"owners_count":20575724,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T08:00:34.679Z","updated_at":"2025-03-24T01:31:13.904Z","avatar_url":"https://github.com/Yelp.png","language":"Go","funding_links":[],"categories":["Go","Developer Workspaces \u0026 Productivity"],"sub_categories":[],"readme":"ARCHIVAL NOTICE\n===============\n\nThis project is no longer maintained and is left up for historic purposes.\n\n\ndockersh\n========\n\nA user shell for isolated, containerized environments.\n\nWhat is this?\n=============\n\ndockersh is designed to be used as a login shell on machines with multiple interactive users.\n\nWhen a user invokes dockersh, it will bring up a [Docker](https://docker.com/) container (if not already running), and\nthen spawn a new interactive shell in the container's namespace.\n\ndockersh can be used as a shell in ``/etc/passwd`` or as an ssh ``ForceCommand``.\n\n\nThis allows you to have a single ssh process on the normal ssh port which places user\nsessions into their own individual docker containers in a secure and locked down manner.\n\nWhy do I want this?\n===================\n\nYou want to allow multiple users to ssh onto a single box, but you'd like some isolation\nbetween those users. With dockersh each user enters their\nown individual docker container (acting like a lightweight virtual machine), with their home directory mounted from the host\nsystem (so that user data is persistent between container restarts), but with its own kernel namespaces for\nprocesses and networking.\n\n\nThis means that the user is isolated from the rest of the system, and they can only see their own processes,\nand have their own network stack. This gives better privacy between users, and can also be used for more easily\nseparating each user's processes from the rest of the system with per user constraints.\n\n\nNormally to give users individual containers you have to run an ssh daemon in each\ncontainer, and either have have a different port for each user to ssh to or some nasty\nForcecommand hacks (which only work with agent forwarding from the client).\n\n\nDockersh eliminates the need for any of these techniques by acting like a regular\nshell which can be used in ``/etc/passwd`` or as an ssh\n[ForceCommand](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man5/sshd_config.5?query=sshd_config).  \nThis allows you to have a single ssh process, on the normal ssh port, and gives\na secure way to connect users into their own individual docker\ncontainers.\n\nSECURITY WARNING\n================\n\ndockersh tries hard to drop all privileges as soon as possible, including disabling \nthe suid, sgid, raw sockets and mknod capabilities of the target process (and all children),\nhowever this doesn't mean that it is safe enough to allow public access to dockersh containers!\n\n*WARNING:* Whilst this project tries to make users inside containers have lowered privileges\nand drops capabilities to limit users ability to escalate their privilege level, it is not certain\nto be completely secure. Notably when Docker adds user namespace support, this can be used\nto further lock down privileges.\n\n*SECOND WARNING:* The dockersh binary needs the suid bit set so that it can make the syscalls to adjust\nkernel namespaces, so any security issues in this code are likely to be exploitable to root.\n\nRequirements\n============\n\nLinux \u003e= 3.8\n\nDocker \u003e= 1.2.0\n\nIf you want to build it locally (rather than in a docker container), Go \u003e= 1.2\n\nInstallation\n============\n\nWith docker\n-----------\n\n(This is the recommended method).\n\nBuild the Dockerfile in the local directory into an image, and run it like this:\n\n    $ docker build .\n    # Progress, takes a while the first time..\n    ....\n    Successfully built 3006a08eef2e \n    $ docker run -v /usr/local/bin:/target 3006a08eef2e\n\nWithout docker\n--------------\n\nYou need to install golang (tested on 1.2 and 1.3), then you should just be able to run:\n\n    go get\n    make\n\nand a 'dockersh' binary will be generated in your ``$GOPATH`` (or your current\nworking directory if ``$GOPATH`` isn't set). N.B. This binary needs to be moved to where\nyou would like to install it (recommended ``/usr/local/bin``), and owned by root + u+s\n(suid). This is done automatically if you use the Docker based installed, but\nyou need to do it manually if you're compiling the binary yourself.\n\nInvoking dockersh\n=================\n\nThere are two main methods of invoking dockersh. Either:\n\n1. Put the path to dockersh into ``/etc/shells``, and then change the users shell\n   in /etc/passwd (e.g. ``chsh myuser -s /usr/local/bin/dockersh``)\n1. Set dockersh as the ssh ``ForceCommand`` in the users ``$HOME/.ssh/config``, or\n   globally in ``/etc/ssh/ssh_config``\n\n*Note:* The dockersh binary needs the suid bit set to operate!\n\nConfiguration\n=============\n\nWe use [gcfg](https://code.google.com/p/gcfg/) to read configs in an ini style format.\n\nThe global config file, ``/etc/dockershrc`` has a ``[dockersh]`` block in it, and zero or more ``[user \"foo\"]`` blocks.\n\nThis can be used to set settings globally or per user, and also to enable the setting\nof settings in the (optional) per user configuration file (``~/.dockersh``), if enabled.\n\nConfig file values\n------------------\n\nSetting name  | Type | Description | Default value | Example value\n------------- | ---- | ----------- | ------------- | -------------\nimagename  | String | The name of the container image to launch for the user. The %u sequence will interpolate the username | busybox | ubuntu, or %u/mydockersh\ncontainername | String | The name of the container (per user) which is launched. | %u_dockersh | %u-dsh\nmounthome | Bool | If the users home directory should be mounted in the target container | false | true\nmounttmp | Bool | If /tmp should be mounted into the target container (so that ssh agent forwarding works). N.B. Security risk | false | true\nmounthometo | String | Where to map the user's home directory inside the container. | %h | /opt/home/myhomedir\nmounthomefrom | String | Where to map the user's home directory from on the host. | %h | /opt/home/%u\nusercwd | String | Where to chdir into the container when starting a shell. | %h | /\ncontainerusername | String | Username which should be used inside the container. | %u | root\nshell | String | The shell that should be started for the user inside the container. | /bin/ash | /bin/bash\nmountdockersocket | Bool | If to mount the docker socket from the host. (DANGEROUS) | false | true\ndockersocket | String | The location of the docker socket from the host. | /var/run/docker.sock | /opt/docker/var/run/docker.sock\nentrypoint | String | The entrypoint for the persistent process to keep the container running | internal | /sbin/yoursupervisor\ncmd | Array of Strings | Additional parameters to pass when launching the container as the command line | | -c'/echo foo'\ndockeropt | Array of Strings | Additional options to pass to docker when launching the container. Can be used to mount additional volumes or limit memory etc. | | -v /some/place:/foovol\nenableuserconfig | Bool | Set to true to enable reading of per user ``~/.dockersh`` files | false | true\nenableuserimagename | Bool | Set to true to enable reading of imagename parameter from ``~/.dockersh`` files | false | true\nenableusercontainername | Bool | Set to true to enable reading of containername parameter from ``~/.dockersh`` files. (Dangerous!) | false | true\nenableusermounthome | Bool | Set to true to enable reading of mounthome parameter from ``~/.dockersh`` files | false | true\nenableusermounttmp | Bool | Set to true to enable reading of mounttmp parameter from ``~/.dockersh`` files | false | true\nenableusermounthometo | Bool | Set to true to enable reading of mounthometo parameter from ``~/.dockersh`` files | false | true\nenableusermounthomefrom | Bool | Set to true to enable reading of mounthomefrom parameter from ``~/.dockersh`` files | false | true\nenableuserusercwd | Bool | Set to true to enable reading of usercwd parameter from ``~/.dockersh`` files | false | true\nenableusercontainerusername | bool | Set to true to enable reading of containerusername parameter from ``~/.dockersh`` files | false | true\nenableusershell | Bool | Set to true to enable reading of shell parameter from ``~/.dockersh`` files | false | true\nenableuserentrypoint | Bool | Set to true to enable users to set their own supervisor daemon / entry point to the container for PID 1 | false | true\nenableusercmd | Bool | Set to true to enable users to set the additional command parameters to the entry point | false | true\nenableuserdockeropt | Bool | Set to true to enable users to set additional options to the docker container that's started. (Dangerous!) | false | true\n\nNotes:\n\n  * Boolean settings are set by just putting the setting name in the config (see examples below).\n  * You must set both ``enableuserconfig`` and the specific ``enableuserxxx`` setting that you want in ``/etc/dockersh`` to\n    get any values parsed from ``~/.dockersh``\n  * Array values are represented by having the same config key appear multiple times, once per value.\n\nConfig interpolations\n---------------------\n\nThe following sequences are interpolated if found in configuration variables:\n\nSequence | Interpolation\n---------|--------------\n%u | The username of the user running dockersh\n%h | The homedirectory (from /etc/passwd) of the user running dockersh\n\nExample configs\n---------------\n\nA very restricted environment, with only the busybox container, limited to 32M of memory, ``/etc/dockersh`` looks like this:\n\n    [dockersh]\n    imagename = busybox\n    shell = /bin/ash\n    usercwd = /\n\nA fairly restricted shell environment, but with homedirectories and one admin user being allowed additional privs, set the following ``/etc/dockersh``\n\n    [dockersh]\n    imagename = ubuntu:precise\n    shell = /bin/bash\n    mounthome\n\n    [user \"someadminguy\"]\n    mounttmp\n    mountdockersocket\n    \nIn a less restrictive environment, you may allow users to choose their own container and shell, from a 'shell' container\nthey have uploaded to the registry, and have ssh agent forwarding working, with the following ``/etc/dockersh``\n\n    [dockersh]\n    imagename = \"%u/shell\"\n    mounthome\n    mounttmp\n    enableuserconfig\n    enableusershell\n\n    [user \"someadminguy\"]\n    mountdockersocket\n\nAnd an example user's ``~/.dockersh``\n\n    [dockersh]\n    shell = /bin/zsh\n\nOr just allowing your users to run whatever container they want:\n\n    [dockersh]\n    mounthome\n    mounttmp\n    enableuserconfig\n    enableuserimagename\n\nCaveats\n=======\n\n  * User namespaces are not supported (yet) so if users escalate to root inside the container, they can probably escape\n  * Tty/Pty handling is not great - whilst things appear to work, they don't go well in unusual circumstances (e.g. your process being killed due to OOM).\n  * This code *has not* been audited by a 3rd party or a container expert, there are probably issues waiting to be found!\n\nTODO\n====\n\n * How do we deal with changed settings (i.e. when to recycle the container)\n    * Document just kill 1 inside the container?\n * Fix up go panics when exiting the root container.\n * getpwnam so that we can interpolate the user's shell from /etc/shells (if used in ForceCommand mode!)\n * Decent test cases\n * Use libcontainer a lot more, in favour of our code:\n    * https://github.com/docker/libcontainer/pull/143 - better nsenter with cgroups\n    * https://github.com/docker/libcontainer/pull/150 - better forkexec\n * Find a better way to make ssh agent sockets work than to bind /tmp\n\nContributing\n============\n\nPatches are very very welcome!\n\nThis is our first real Go project, so we apologise about the shoddy quality of the code.\n\nPlease make a branch and send us a pull request.\n\nPlease ensure that you use the supplied pre-commit hook to correctly format your code\nwith go fmt:\n\n    ln -s hooks/pre-commit .git/hooks/pre-commit\n\nCopyright\n=========\n\nCopyright (c) 2014 Yelp. Some rights are reserved (see the LICENSE file for more details).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FYelp%2Fdockersh","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FYelp%2Fdockersh","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FYelp%2Fdockersh/lists"}