Welcome to my blog!

ClamAV API in Azure

January 06, 2021

ClamAV is an open-source antivirus solution that uses a virus database to detect and remove malware. One of the largest issues with ClamAV is that it’s protocol (Clamd) contains command such as shutdown, so exposing clamd directly to external services is not a great idea.

Enter REST

To prevent the clamd protocol being directly exposed, I decided to use a REST Proxy (there are a few of these that exist in different languages). The REST service exposes the clamd status path (/) as well as the scan result and scan reply path (scan and scanReply).

Given how tightly coupled the REST service and the ClamAV server are, I decided that a docker-compose file would be best suited for this task.

The solution used is similar to this, with changes so that the docker-compose file looks like:

version: '3.3'

services: 
  clamav-rest: 
    image: lokori/clamav-rest
    ports: 
      - "80:8080"
    links: 
      - clamav-server
    environment: 
      CLAMD_HOST: clamav-server
    restart: always


  clamav-server: 
    image: mkodockx/docker-clamav

How to get it working in Azure

Now that I had the docker-compose file working, I needed a way to get this running in Azure. Thankfully, Azure have a feature that allows you to create a multi-container app within a webapp. You can read more on this here.

At first, I followed this tutorial through an authenticated terminal. However, the end result never worked and it appeared as if the docker-compose file was corrupted in the portal. Sure enough, the following command works in Cloudshell only:

az webapp create --resource-group myResourceGroup --plan myAppServicePlan --name <app-name> --multicontainer-config-type compose --multicontainer-config-file docker-compose.yml

and thats it!

Not only do you prevent the clamd service from being exposed, but you also allow for an easier method of network access restrictions and a solution that can act as a central utility for all the applications on your Azure tenant.

You can test the REST API through curl like so:

echo "hi" > test.txt
curl -F "name=blabla" -F "file=@./test.txt" https://<your app service domain>/scan

Everything ok : true

and to test a vulnerability, you can use an eicar file by placing the following in a file:

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

and you can see the result as

curl -F "name=blabla" -F "file=@./eicar.txt" https://<your app service domain>/scan

Everything ok : false