Do not create docker images with a root user as it gives full privilages to a user who has access to the docker container.
Example : We can run a DOS(Denial of service) attack once we have full access(root privilages) to the container.
- Run a ubuntu docker container -
docker run --rm -it ubuntu sh
- Run this command to see who is the user -
whoami
. This returnsroot
as the user. This is bad. - Now you can install/run whatever you want as part of the container.
- Lets install
apt-get update && apt-get install stress -y
- Stress is a tool by which you can generate huge load on a system
- Run
stress --vm 2 --vm-bytes 2G --timeout 30
When this command is executed the docker container (VM as well) will become slow/unresponsive for 30 seconds. This means that any application running on the container will be unresponsive for long.–vm this flag helps us in creating workers for the job. More workers, more stress. –vm-bytes this flag is used to set the amount of memory. –timeout flag directs the stress tool to stop the job(s) after X seconds. Here it is 30 seconds.
- Build images with a non root user
- Create a file with name
Dockerfile
with the following content -########################################## # Dockerfile to change from root to # non-root privilege ########################################### # Base image is Ubuntu FROM ubuntu:latest # Add a new user "john" with user id 8877 RUN useradd -u 8877 john # Change to non-root privilege USER john
- Run
docker build . -t ubuntu:test
. With this command, the we create a docker image - ubuntu:test - Run the docker container -
docker run --rm -it ubuntu:test
. Herewhoami
will givejohn
- With this continer you cannot install any new libraries. Test with
apt-get intall stress
which givesPermission denied
error - You cannot be a root with such images which makes your containers secure
Do not run the containers in privilage mode. It gives full access to the host machine.
- Run
docker run --privileged -it --rm ubuntu sh
- As the continer is running in privileged mode. It disables all the security measures.
- Run command
mount
which gives all the mount points - Now you can mount any of these mounts from the host system
- Run
mkdir /hostroot && mount /dev/sda1 /hostroot
- This mount the host machines data to your container
- Avoid running the containers in privilage mode
Sometimes people just mount the docker socket inside the container. If an attacker gains access to this container, he literally has root access.
- Mount socket
docker run -it -v /var/run/docker.sock:/var/run/docker.sock ubuntu:latest sh
- Run
apt-get update ; apt-get install docker.io -y
to install docker client docker --version
to check if docker is runningdocker run -it --rm centos sh
- With this you can run containers in host machine
- As we can see it is very dangerous to mount the docker socket inside any container. The centos container can do anything that the host system can do as root.
- Try to avoid docker socket.
By default unix uses docker socket. You can expose it via HTTP as well. People do not care security of this HTTP REST API.
- Expose docker via REST API
sudo cp /lib/systemd/system/docker.service /etc/systemd/system/
sudo vi /etc/systemd/system/docker.service
- Add
-H tcp://0.0.0.0:2376
at the end of ExecStart sudo systemctl daemon-reload
reload new configsudo systemctl restart docker.service
restart dockercurl http://localhost:2376/version
-> gives the docker versionsudo apt-get install jq -y
this is a json formatterdocker run --rm -it -d ubunut
run an ubuntu instancehttp://localhost:2376/containers/json | jq
gives list of containers(similar todocker ps
)- Stop container
http://localhost:2376/containers/<container-name>/stop
- Here the API is unauthenticaed
- API is Non-SSL
This gives attacer a clear access.
-
Run an apache2 or nginx as a proxy
-
Configure SSL, Authentication in nginx/apache2
-
Config for apache 2 -
-
Run these commands
sudo a2enmod proxy sudo a2enmod proxy_http sudo a2enmod proxy_balancer sudo a2enmod lbmethod_byrequests sudo systemctl restart apache2 sudo vi /etc/apache2/sites-available/000-default.conf Add this content - <VirtualHost *:80> ProxyPreserveHost On ProxyPass / http://127.0.0.1:2376/ ProxyPassReverse / http://127.0.0.1:2376/ </VirtualHost> sudo systemctl restart apache2
-
With these config you are able to proxy your load to port 80.
curl http://localhost/version
should give you the docker version -
Adding authentication -
sudo apt install apache2-utils sudo htpasswd -c /etc/apache2/.htpasswd sammy Enter your password here Check if password exists cat /etc/apache2/.htpasswd vi /etc/apache2/sites-available/000-default.conf Add this content - <Location /> AuthType Basic AuthName "Restricted Content" AuthUserFile /etc/apache2/.htpasswd Require valid-user </Location> Run - sudo systemctl restart apache2
-
Now access
curl http://localhost/version
this should prompt you username/password
The docker image could contain outdated/vulnerable packages.
Old docker images contain vulnerable components. Based on this attacker could try attacking the docker container.
- Keep your image version updated.
- You can scan these docker images with tools like Black Duck Binary Analysis which gives you a list of vulnerable packages installed in the docker images. Based on this information you can upgrade your image.
- Use the latest base image while building your custom image.