How to install ClamAV on docker and use it in nodejs
Post

How to install ClamAV on docker and use it in nodejs

Let’s use ClamAV, an open-source anti-virus software, in nodejs.

ClamAV ?
ClamAV is a free antivirus software that detects viruses, Trojans, worms, and spam on Linux, macOS, and Windows operating systems. It’s commonly used on email and file servers and can detect malware in compressed files of many formats.

Prerequisites

  • nodejs
  • docker

Install ClamAV (feat.docker-based)

The ClamAV installation method is different for each os, so I will install it in the docker.
pull the image from docker hub, run:

1
$ docker pull clamav/clamav:latest

change the mount path /path/to/databases to your own folder.
run the container, run:

1
2
3
4
5
$ docker run -it --rm \
    --name "clam_container_01" \
    --publish 3310:3310 \
    --mount type=bind,source=/path/to/databases,target=/var/lib/clamav \
    clamav/clamav:latest

For details, see the site ClamAV Installing docker

Now, TCP service of ClamAV is ready.

Install clamscan

Clamscan is required to use ClamAV in nodejs.

clamscan ?
Nodejs module to scan files on your server with ClamAV via TCP to a remote server or local UNIX Domain socket.

Install clamscan in your nodejs project, run:

1
$ yarn add clamscan

Let’s also install axios for TCP to a remote server, run:

1
$ yarn add axios

Usages

First, check if TCP with ClamAV is possible.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import NodeClam from "clamscan";
import axios from 'axios'

const clamscan = await new NodeClam().init({
    clamdscan: {
        host: '127.0.0.1',
        port: 3310,
    }
});

clamscan.getVersion((err, version) => {
    if (err) return console.error(err);
    console.log(`ClamAV Version: ${version}`);
});

Run the code:

1
2
$ node myscan
ClamAV Version: ClamAV 1.0.1/26813/Wed Feb 15 08:29:30 2023

Let’s create a function that returns the result by receiving the url of the file to be scanned for viruses.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const checkVirus = async (url) => {
    return new Promise(async (resolve, reject) => {
        try {
            const response = await axios.get(url, {
                responseType: 'stream'
            }); 
    
            const resData = response.data;
            const av = clamscan.passthrough();
            resData.pipe(av);
    
            av.on('scan-complete', result => {
                const { isInfected, viruses } = result;    
                resolve({isInfected: isInfected, viruses: viruses});
             });
        } catch(e) {
            reject(e);
        } 
    })
}

Let’s try the checkVirus function, insert the url of the file to be checked.

1
2
const result = await checkVirus('http://your_url');
console.log('result', result);

Run the code:

1
2
3
4
5
6
$ node myscan
// If the file contains viruses, output is:
{isInfected: true, viruses: [Win.Test.EICAR_HDB-1]} 

// If the file does not contain viruses, output is:
{isInfected: false, viruses: []}

Reference

  1. ClamAV Site
  2. clamscan Site