A Docker Antivirus in Ruby
Tags: docker, antivirus, clamav, atomic
Published: 2019-12-09 20:22:44

*Originally posted on [Medium](https://medium.com/@wdhif/a-docker-antivirus-in-ruby-a4cceb4528e0)*

Last year, I've had the occasion to work on a project to build Docker images for developers. For security reasons, the developers were not allowed to push to a registry the Docker images they had built on their computer. Instead, they had to use a 'builder', in Ruby, that would take their Dockerfile and build the image for them, after running some tests of course.

One of those test was an antivirus, the [docker-antivirus](https://github.com/wdhif/docker-antivirus).

{% github wdhif/docker-antivirus no-readme %}

### How to run an Antivirus on a Docker image?

The first thing was to choose an antivirus, the choice was pretty straight forward. It should be open-source, run on Linux, and be performant. The answer was ClamAV.
![ClamAV](https://miro.medium.com/max/500/0*nuijrp8xGa25YWLL.png)
ClamAV is an open-source antivirus that works on Linux with a public virus database with, as of 10 February 2017 contained over 5,760,000 virus signatures.


---

The idea was to:
1. Instantiate a Docker container with the image we want to test.
2. Mount the container file system
3. Run ClamAV on the mounted file system
4. Print some result

But we already got an issue here, **it is not possible to mount the root of a container**.

### Atomic to the rescue

Atomic is a project by Red Hat to deploy and manage container-based infrastructures. One of the product of Project Atomic is the [Atomic Run Tool](https://github.com/projectatomic/atomic).

One of the command added by this tool is [atomic mount](https://github.com/projectatomic/atomic/blob/master/Atomic/mount.py), which allow us to mount a container root. Atomic mount uses [OSTree](https://ostree.readthedocs.io/en/latest/), a library allowing us to interact with hierarchical file systems.

Using Atomic mount, we are able to mount the root of a container, and therefore this allow us to run ClamAV on it.

### Wrapping things up

By using both ClamAV and Atomic, I was able to create a little utility in Ruby to help me check viruses on a Docker image.

![The docker-antivirus in action](https://miro.medium.com/max/2444/0*24jR-PvCoR_hn4NU.gif)

By running the docker-antivirus on the Busybox Docker image, we can confirm that this image is safe. We also have some informations about the scan itself. For example, how many files were scanned or how much time did it took. But we must also test the docker-antivirus on a malicious Docker image.

### Testing our solution with the EICAR test

The EICAR test file is a simple characters chain created by the European Institute for Computer Antivirus Research (EICAR) to test without any risks antivirus solutions.

```
X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
```

This simple characters chain is designed to trigger any antivirus, although it is completely harmless. For testing purpose, I simply created a Docker image containing this file, the [docker-eicar](https://github.com/wdhif/docker-eicar).

Here, we can see the result of the docker-antivirus when analyzing the docker-eicar image:

![Running the docker-antivirus with the docker-eicar image](https://miro.medium.com/max/1262/1*LzA1i8eWKqkd4M5-geRNAA.png)

As you can see, the docker-antivirus tells us that there is in fact something wrong with the docker-eicar image.

### What's next?

I am planning on adding more information about the virus itself in case it's detected. I would also like to make the docker-antivirus more easy to use, maybe by embedding it inside a docker image, or maybe by using static builds.

You can also participate yourself in the [development of this project](https://github.com/wdhif/docker-antivirus), contributions are more than welcome!