How to Secure Docker Containers with a Read-Only Filesystem
A compromised website sucks. A compromised website that an attacker can insert code into to manipulate your visitors is even worse! Out-of-the-box, Docker containers provide some security advantages over running directly on the host, however Docker provides additional features to increase security. There is a little known flag in Docker that will convert a container’s files system to read-only.
My father runs an e-commerce site for his dahlia flower hobby business at https://lobaughsdahlias.com. Many years ago, a hacker was able to gain access to the site files through FTP, and then injected a bit of code into the head of the theme. That code was capturing data about customers and sending it to a server in Russia. Luckily the issue was caught before any sensitive data was sent out, but it served to highlight the many layers it takes to secure a website.
Security is like an onion, peel back one layer and another reveals itself beneath. If the filesystem had been read-only, the attacker still would have been able to get in, but they would have been unable to alter anything on the filesystem, thus rendering their end goal moot.
To simplify securing a container, Docker provides a read-only runtime flag that will enforce the filesystem into a read-only state.
In the remainder of this article, I am going to show you how to utilize the read-only flag in Docker. This is not a theory lesson, but rather a walkthrough as I show you exactly the steps I took to deploy https://lobaugh.fish, a live production site, with a read-only filesystem.
- Working knowledge of Docker
- Docker installed
- Docker-compose installed
- An existing website to play with
The https://lobaugh.fish site is a constantly evolving site where I can share my passion for fishkeeping. The site is built on top of WordPress and hosted in a VPS at Digital Ocean. The webserver in use is Apache, which will be important to know for later.
There are two ways to add the read-only flag: via the docker cli too, and via docker-compose.