Skip to content

Instantly share code, notes, and snippets.

@eqhmcow
Last active July 18, 2019 02:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eqhmcow/2abd8ae2d800f8a9a190634615fb84fc to your computer and use it in GitHub Desktop.
Save eqhmcow/2abd8ae2d800f8a9a190634615fb84fc to your computer and use it in GitHub Desktop.
How to run "ls" in docker
---
Run "ls" in docker, handling various possible environmental issues that the shell normally directly handles.
That is, the below docker command is similar to simply issuing "ls" at a shell prompt, or adding an "ls" command to a shell script.
Without docker:
$ ls
With docker:
$ DOCKER_TMP=`mktemp -d` ; chmod 1777 $DOCKER_TMP ; DOCKER_GO="$DOCKER_TMP/go" ; alias ls > $DOCKER_GO ; echo "ls" >> $DOCKER_GO ; if [[ -t 0 ]] ; then DOCKER_TERM="-it" ; DOCKER_BASH="-ic" ; else DOCKER_TERM="-i -a stdin -a stdout -a stderr" ; DOCKER_BASH="-c" ; fi ; GID=`id -g` ; docker run -u $UID:$GID --cap-drop=ALL $DOCKER_TERM --rm --log-driver=none -v "$PWD:$PWD" -w "$PWD" -e "TERM=$TERM" -e "LANG=$LANG" -e "LS_COLORS=$LS_COLORS" -v /etc/passwd:/etc/passwd -v /etc/group:/etc/group -v $DOCKER_TMP:/tmp --entrypoint=/bin/bash ubuntu $DOCKER_BASH "source /tmp/go" ; rm -rf $DOCKER_TMP
Overview:
1. Need to run a docker container with much of the user's existing environment carried into the container, e.g.:
a. current working directory
b. shell aliases
c. environment variables
d. users on host (UNIX passwd / group details)
2. Need to handle two main cases:
a. interactive terminal (e.g. ssh login shell)
b. non-interactive command with shell pipelining (e.g. cat example | command > output)
Script walk-through:
# create a temp dir on the host for the container to use
DOCKER_TMP=`mktemp -d` ; chmod 1777 $DOCKER_TMP
# we're going to execute a command in the container by sourcing a file created
# on the host, under that tmp dir we just created
DOCKER_GO="$DOCKER_TMP/go"
# here are the commands we want to run inside the docker container
alias ls > $DOCKER_GO
echo "ls" >> $DOCKER_GO
# need to invoke docker differently depending on if we're at an interactive shell or not
if [[ -t 0 ]] ; then
DOCKER_TERM="-it"
DOCKER_BASH="-ic"
else
DOCKER_TERM="-i -a stdin -a stdout -a stderr"
DOCKER_BASH="-c"
fi
# we need to pass our uid and gid into docker
GID=`id -g`
# kick docker off:
docker run \
-u $UID:$GID \
--cap-drop=ALL \
$DOCKER_TERM \
--rm --log-driver=none \
-v "$PWD:$PWD" -w "$PWD" \
-e "TERM=$TERM" -e "LANG=$LANG" -e "LS_COLORS=$LS_COLORS" \
-v /etc/passwd:/etc/passwd -v /etc/group:/etc/group \
-v $DOCKER_TMP:/tmp \
--entrypoint=/bin/bash \
ubuntu $DOCKER_BASH "source /tmp/go"
# docker run walkthrough:
# -u $UID:$GID # execute command as current user
# --cap-drop=ALL # don't need any root privs
# $DOCKER_TERM # set appropriately for interactive tty vs non-interactive script
# --rm --log-driver=none # don't clutter host's disk with small containers or log files
# -v "$PWD:$PWD" -w "$PWD" # bind mount the current working directory into the container, set CWD when executing
# -e "TERM=$TERM" -e "LANG=$LANG" -e "LS_COLORS=$LS_COLORS" # pass in applicable environment variables for the app
# -v /etc/passwd:/etc/passwd -v /etc/group:/etc/group # let the container know what uids map to what user names
# -v $DOCKER_TMP:/tmp # pass in tmp dir that also has commands to execute
# --entrypoint=/bin/bash # assume bash as default shell
# ubuntu $DOCKER_BASH "source /tmp/go" # assume ubuntu as linux env, invoke bash appropriately
# for interactive tty vs non-interactive, source commands
# clean up tmp dir
rm -rf $DOCKER_TMP
Issues:
1. security issue - race condition with tmp dir - file created in insecure directory, then sourced as user
2. security issue - assumes uid and gid are set correctly for the current user (can be mitigated with sudo)
3. doesn't handle paths above current working directory - script could be updated to mitigate by adding more -v bind mounts based on e.g. /proc/mounts
4. only passes in /etc/passwd -- doesn't handle passing in user / group details from non-file external sources such as ldap / sssd - would likely need to be manually mitigated
5. doesn't handle user with additional groups - doesn't set additional gid on docker run command line. Could be mitigated with additional logic in script
6. assumes user wants bash and ubuntu as their execution environment, assumes we only need a few environment variables passed in. Could be improved with more logic in script / configurable defaults
7. usual docker security issues where docker gives users root access to host (can be mitigated with sudo)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment