Deploy ClamAV on Upsun, on one-time scan
What is ClamAV?
ClamAV (Clam AntiVirus) is an open-source antivirus engine designed for detecting malwares, viruses, and other malicious threats. It is widely used for scanning file servers, and web applications. ClamAV is known for its lightweight nature and ability to be integrated into various security systems.
Why integrate ClamAV into your web application?
Integrating ClamAV into a web application, provides several security benefits:
- Protect Uploaded Files: If your application allows users to upload files, scanning them for viruses ensures that no malicious files enter your system.
- Regulatory Compliance: Many industries require businesses to scan files for malware as part of cybersecurity compliance.
- Prevent System Contamination: Detecting and removing infected files early prevents malware from spreading across your infrastructure.
- Increase User Trust: Ensuring that files are clean enhances trust in your platform, especially in cloud-based environments like Upsun.
Using ClamAV with service mode vs one-time scan mode
There are two possible (and cumulative) policy approaches to file verification with ClamAV:
- One-time scan mode: This mode of ClamAV allows the user to scan an entire file tree without distinction. A pro is that all files can be scanned, however this does take a considerably long amount of time to process all the verifiers - which some may consider to be a con.
- Service mode: This mode of ClamAV allows the user to scan specific files on demand. eg. the user uploads 3 new files and scans only these. A pro is that this process is very fast, due to the limitation of files to be processed, however a con is that it also requires communication between the application and the antivirus.
This tutorial covers how to run ClamAV in one-time scan mode.
Setting up ClamAV
Add ClamAV binary
To use ClamAV on Upsun, you need to install the ClamAV binaries.
Let’s use Upsun composable-image to add ClamAV to our application container:
|
|
Add ClamAV configuration
After adding the ClamAV binaries, you need to configure ClamAV. This involves modifying two configuration files to add on the reposotory project, each corresponding to one of the two main commands:
graph LR; Upsun-->ClamAV; ClamAV-->freshclam(freshclam); ClamAV-->clamav(clamscan); freshclam(freshclam)-->freshclam.conf([freshclam.conf]); clamav(clamscan)-->clamd.conf([clamd.conf]);
This includes updating the virus database (aka freshclam
).
# Log section
LogFileMaxSize 5M
LogTime yes
LogRotate yes
# Database upsate
DNSDatabaseInfo current.cvd.clamav.net
DatabaseMirror db.local.clamav.net
DatabaseMirror database.clamav.net
MaxAttempts 5
# Configure path
DatabaseDirectory /app/var/lib
NotifyClamd /app/var/etc/clamd.conf
As well as the configuration of ClamAV itself:
# Log section
LogFile /app/var/log/clamav.log
LogFileMaxSize 5M
LogTime yes
# Configure path
DatabaseDirectory /app/var/lib
The storage locations for the virus database and the configuration files have been modified to adapt them to Upsun. These modifications were made by adding DatabaseDirectory
and NotifyClamd
to the mount points with write permissions.
Add mount endpoint for storage
Since ClamAV needs to write to the disk, we must add appropriate mount points with the necessary write permissions.
|
|
Additionally, these mount points must have a specific directory structure.
To do this, let’s combine everything into a shell script to set up this structure (on the reposotory project), that will be executed during each deployment to ensure the structure’s existence.
#!/usr/bin/env bash
# -*- coding: utf-8 -*-
echo "Prepare folder for clamav..."
mkdir -p \
"${PLATFORM_APP_DIR}/var/log" \
"${PLATFORM_APP_DIR}/var/lib" \
"${PLATFORM_APP_DIR}/var/etc"
echo "Move config on mount..."
cp "${PLATFORM_APP_DIR}/etc/clamd.conf" "${PLATFORM_APP_DIR}/var/etc/"
You will note the use of the built-in variable PLATFORM_APP_DIR
to define the application’s default path.
And let’s add execution permissions to the script.
chmod +x scripts/clam_install.sh
This script can only be executed once the mount points are mounted, which is done in Upsun during the deployment step.
To automate this, we will add the script call to the deployment hooks.
|
|
Deploying ClamAV on Upsun
We need to push these additions to the Upsun project. (If you don’t have one, create a project on Upsun.)
git add .
git commit -m "Add ClamAV on the project"
git push
Finally, ClamAV requires a minimum set of resources, so we need to fine-tune the resources allocated to ClamAV:
- Disk : > 512Mb
- Memory : > 1.5Gb
Test the ClamAV integration on Upsun
After the deployment, test that everything works as expected by opening an SSH connection:
upsun ssh
Let’s start by triggering the update of ClamAV’s virus database.
web@clamav.0:~/$ freshclam --config-file="${PLATFORM_APP_DIR}/etc/freshclam.conf"
Mon Feb 17 15:50:25 2025 -> ClamAV update process started at Mon Feb 17 15:50:25 2025
Mon Feb 17 15:50:25 2025 -> daily database available for download (remote version: 27552)
Time: 1.1s, ETA: 0.0s [========================>] 61.56MiB/61.56MiB
Mon Feb 17 15:50:28 2025 -> Testing database: '/app/var/lib/tmp.3f810acf2f/clamav-0bcf78864fd8e25406deda53ee394581.tmp-daily.cvd' ...
Mon Feb 17 15:50:43 2025 -> Database test passed.
Mon Feb 17 15:50:43 2025 -> daily.cvd updated (version: 27552, sigs: 2072975, f-level: 90, builder: raynman)
Mon Feb 17 15:50:43 2025 -> main database available for download (remote version: 62)
Time: 4.4s, ETA: 0.0s [========================>] 162.58MiB/162.58MiB
Mon Feb 17 15:50:59 2025 -> Testing database: '/app/var/lib/tmp.3f810acf2f/clamav-86fc871948269630ae1178e89bbe3e82.tmp-main.cvd' ...
Mon Feb 17 15:51:17 2025 -> Database test passed.
Mon Feb 17 15:51:17 2025 -> main.cvd updated (version: 62, sigs: 6647427, f-level: 90, builder: sigmgr)
Mon Feb 17 15:51:17 2025 -> bytecode database available for download (remote version: 335)
Time: 0.3s, ETA: 0.0s [========================>] 282.94KiB/282.94KiB
Mon Feb 17 15:51:17 2025 -> Testing database: '/app/var/lib/tmp.3f810acf2f/clamav-e5e2c8f801634258bc2f8d8119dbdd44.tmp-bytecode.cvd' ...
Mon Feb 17 15:51:17 2025 -> Database test passed.
Mon Feb 17 15:51:17 2025 -> bytecode.cvd updated (version: 335, sigs: 86, f-level: 90, builder: raynman)
To check that it’s working as expected, let’s create a file that simulates an infected file:
web@clamav.0:~/$ echo 'X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*' > \
"${PLATFORM_APP_DIR}/data/folder2scan/fake.txt"
Now, let’s run a scan:
web@clamav.0:~/$ clamscan \
--database="${PLATFORM_APP_DIR}/var/lib" \
--log="${PLATFORM_APP_DIR}/var/log/scan.log" \
--move="${PLATFORM_APP_DIR}/data/quarantine" \
--recursive \
"${PLATFORM_APP_DIR}/data/folder2scan"
Loading: 20s, ETA: 0s [========================>] 8.70M/8.70M sigs
Compiling: 6s, ETA: 0s [========================>] 41/41 tasks
/app/data/scan/fake.txt: Eicar-Signature FOUND
/app/data/scan/fake.txt: moved to '/app/data/quarantine/fake.txt'
----------- SCAN SUMMARY -----------
Known viruses: 8704755
Engine version: 1.3.2
Scanned directories: 1
Scanned files: 1
Infected files: 1
Data scanned: 0.00 MB
Data read: 0.00 MB (ratio 0.00:1)
Time: 28.929 sec (0 m 28 s)
Start Date: 2025:02:17 15:57:55
End Date: 2025:02:17 15:58:24
Automating updates and scans
In order to automate the database updates and the scans, we will be grouping all the necessary commands into shell scripts to make their usage easier:
#!/usr/bin/env bash
# -*- coding: utf-8 -*-
echo "Update Virus database..."
freshclam --config-file="${PLATFORM_APP_DIR}etc/freshclam.conf"
#!/usr/bin/env bash
# -*- coding: utf-8 -*-
echo "Trigger scan by one-time call..."
clamscan \
--database="${PLATFORM_APP_DIR}/var/lib" \
--log="${PLATFORM_APP_DIR}/var/log/scan.log" \
--move="${PLATFORM_APP_DIR}/data/quarantine" \
--recursive \
"${PLATFORM_APP_DIR}/data/folder2scan"
Now let’s add execution permissions to the script.
chmod +x scripts/*.sh
Then, automate these step by setting up some CRON jobs:
|
|
Finally, commit everything:
git add .
git commit -m "Add automation (CRONs)"
git push
Extra feature
You can use runtime-operation provided by Upsun to trigger a new scan:
Declare runtime operation
|
|
Call runtime operation
Then, trigger this runtime operation from your development machine (or any other environment with access to the Upsun CLI).
upsun operation:run trigg_clamav --project <PROJECT_ID> --environment <ENVIRONMENT_NAME>
Conclusion
By following this guide, you have learned how to set up ClamAV on Upsun, utilizing features like Upsun composable-image and deployment hooks to automate updates and scans. This approach not only strengthens your infrastructure’s security but also enhances user trust, especially in cloud environments like Upsun. With proper configuration and automation scripts, ClamAV can be a powerful tool for maintaining system integrity while remaining lightweight and easy to integrate.
Project on our Github Upsun