Skip to content

Repository files navigation

A tool to download and update clamav databases and database patch files for the purposes of hosting your own database mirror.

Copyright (C) 2021-2025 Cisco Systems, Inc. and/or its affiliates. All rights reserved.

PyPI version PyPI - Python Version

About

This tool downloads the latest ClamAV databases along with the latest database patch files.

This project replaces the clamdownloader.pl Perl script by Frederic Vanden Poel, formerly provided here: https://www.clamav.net/documents/private-local-mirrors

Run this tool as often as you like, but it will only download new content if there is new content to download. If you somehow manage to download too frequently (eg: by using cvd clean all and cvd update repeatedly), then the official database server may refuse your download request, and one or more databases may go on cool-down until it's safe to try again.

Requirements

  • Python 3.6 or newer.
  • An internet connection with DNS enabled.
  • The following Python packages. These will be installed automatically if you use pip, but may need to be installed manually otherwise:
    • click v7.0 or newer
    • colorlog v6.7 or newer
    • colorama
    • requests
    • dnspython v2.1.0 or newer
    • rangehttpserver

Installation

You may install cvdupdate from PyPI using pip, or you may clone the project Git repository and use pip to install it locally.

Install cvdupdate from PyPI:

python3 -m pip install --user cvdupdate

Updating Your Installation

When running cvd update to update the databases, it will also check if there is a new version of the cvdupdate package on Python's PyPI package repository. If there is a newer version of cvdupdate, you will see a message prompting you to upgrade. It will look someething like this:

WARNING You are running cvdupdate version: 1.1.0.
WARNING There is a newer version on PyPI: 1.1.1. Please update!

To upgrade the cvdupdate package through PyPI, run:

python3 -m pip install --user --upgrade cvdupdate

Basic Usage

Use the --help option with any cvd command to get help.

cvd --help

Tip: You may not be able to run the cvd or cvdupdate shortcut directly if your Python Scripts directory is not in your PATH environment variable. If you run into this issue, and do not wish to add the Python Scripts directory to your path, you can run CVD-Update like this:

python -m cvdupdate --help

(optional) You may wish to customize where the databases are stored:

cvd config set --dbs-directory <your www path>

Run this to download the latest database and associated CDIFF patch files:

cvd update

Downloaded databases will be placed in ~/.cvdupdate/database unless you customized it to use a different directory.

Newly downloaded databases will replace the previous database version, but the CDIFF patch files will accumulate up to a configured maximum before it starts deleting old CDIFFs (default: 30 CDIFFs). You can configure it to keep more CDIFFs by manually editing the config (default: ~/.cvdupdate/config.json). The same behavior applies for CVD-Update log rotation.

Run this to serve up the database directory on http://localhost:8000 so you can test it with FreshClam.

cvd serve

Tip: cvd serve listens on port 8000 by default. Pass a port number to change it (e.g. cvd serve 9000), or pass 0 to have the OS pick a random available port (the chosen port is logged after binding).

Disclaimer: The cvd serve feature is not intended for production use, just for testing. You probably want to use a more robust HTTP server for production work.

Install ClamAV if you don't already have it and, in another terminal window, modify your freshclam.conf file. Replace:

DatabaseMirror database.clamav.net

... with:

DatabaseMirror http://localhost:8000

Tip: A default install on Linux/Unix places freshclam.conf in /usr/local/etc/freshclam.conf. If one does not exist, you may need to create it using freshclam.conf.sample as a template.

Now, run freshclam -v or freshclam.exe -v to see what happens. You should see FreshClam successfully update it's own database directory from your private database server.

Run cvd update as often as you need. Maybe put it in a cron job.

Tip: Each command supports a --verbose (-V) mode, which often provides more details about what's going on under the hood.

Cron Example

On Linux/Unix you can schedule updates with cron. Edit the crontab of the user CVD-Update should run as:

crontab -e

Add a line such as:

30 */4 * * * /home/username/.local/bin/cvd update >/dev/null 2>&1

This runs cvd update at minute 30 of every 4th hour. Use the full path to cvd (run which cvd to find it), since cron does not load your shell's PATH.

Like FreshClam, CVD-Update first does a DNS version check and only downloads when something changed, so running it a few times a day is fine.

The example discards output with >/dev/null 2>&1; drop that to send output to cron's mail, or redirect to a file to keep it. For separate daily log files in ~/.cvdupdate/logs, enable file logging with cvd config set --logs-enabled (use --logs-directory to change the location). These are rotated automatically, keeping the last 30 days by default (--logs-to-keep).

Optional Functionality

Using a custom DNS server

DNS is required for CVD-Update to function properly (to gather the TXT record containing the current definition database version). You can select a specific nameserver to ensure said nameserver is used when querying the TXT record containing the current database definition version available

  1. Set the nameservers in the config. Eg:

    cvd config set --nameservers 208.67.222.222
  2. Set the environment variable CVDUPDATE_NAMESERVERS. Eg:

    CVDUPDATE_NAMESERVERS="208.67.222.222" cvd update

The environment variable will take precedence over the nameserver config setting.

Note: Both options can be used to provide a comma-delimited list of nameservers to utilize for resolution.

Note: The --nameserver flag and the CVDUPDATE_NAMESERVER environment variable (singular) from CVD-Update ≤ 1.2.0 are still accepted as deprecated aliases for --nameservers / CVDUPDATE_NAMESERVERS, but will be removed in a future release.

Using a proxy

Depending on your type of proxy, you may be able to use CVD-Update with your proxy by running CVD-Update like this:

First, set a custom domain name server to use the proxy:

cvd config set --nameservers <proxy_ip>

Then run CVD-Update like this:

http_proxy=http://<proxy_ip>:<proxy_port> https_proxy=http://<proxy_ip>:<proxy_port> cvd update -V

Or create a script to wrap the CVD-Update call. Something like:

#!/bin/bash
http_proxy=http://<proxy_ip>:<proxy_port>
export http_proxy
https_proxy=http://<proxy_ip>:<proxy_port>
export https_proxy
cvd update -V

Disclaimer: CVD-Update doesn't support proxies that require authentication at this time. If your network admin allows it, you may be able to work around it by updating your proxy to allow HTTP requests through unauthenticated if the User-Agent matches your specific CVD-Update user agent. The CVD-Update User-Agent follows the form CVDUPDATE/<version> (<uuid>) where the uuid is unique to your installation and can be found in the ~/.cvdupdate/state.json file (or ~/.cvdupdate/config.json for cvdupdate <=1.0.2). See #9 for more details.

Adding support for proxy authentication is a ripe opportunity for a community contribution to the project.

Files and directories created by CVD-Update

This tool is to creates the following directories:

  • ~/.cvdupdate
  • ~/.cvdupdate/logs
  • ~/.cvdupdate/databases

This tool creates the following files:

  • ~/.cvdupdate/config.json
  • ~/.cvdupdate/state.json
  • ~/.cvdupdate/databases/<database>.cvd
  • ~/.cvdupdate/databases/<database>-<version>.cdiff
  • ~/.cvdupdate/logs/<date>.log

Tip: You can set custom database and logs directories with the cvd config set command. It is likely you will want to customize the database directory to point to your HTTP server's www directory (or equivalent). Bare in mind that if you already downloaded the databases to the old directory, you may want to move them to the new directory.

Important: If you want to use a custom config path, you'll have to use it in every command. If you're fine with having it go in ~/.cvdupdate/config.json, don't worry about it.

Additional Usage

Get familiar with the tool

Familiarize yourself with the various commands using the --help option.

cvd --help
cvd config --help
cvd update --help
cvd add --help
cvd clean --help

Print out the current list of database names.

cvd list

Print out the status (versions, last-checked times, URLs) of all databases, or a single one.

cvd status
cvd status daily.cvd

Note: status replaces the old show command. show still works as a deprecated alias and will be removed in a future release. Add --json to status (and list) for machine-readable output.

Print out the config to see what it looks like.

cvd config show

Command aliases and JSON output

The common commands have short aliases:

Command Alias
status s
update u
list ls
remove rm
config cf
clean cl

list, status, and config show accept --json to emit machine-readable output for scripting:

cvd list --json                # JSON array of database names
cvd status --json              # full state for all databases
cvd status daily.cvd --json    # state for a single database
cvd config show --json         # current configuration

Configuration options

cvd config set exposes every configuration option. Run with no options to see the help. Booleans use a --flag / --no-flag pair.

Option Description
--nameservers, -n Comma-separated DNS nameservers used for the version check.
--max-retries Download retries, 15 (default 3).
--logs-enabled / --no-logs-enabled Write log files to the logs directory (default: off).
--logs-directory, -l Log directory path.
--logs-rotate / --no-logs-rotate Rotate (delete) old log files (default: on).
--logs-to-keep Number of log files to keep when rotating (default 30).
--dbs-directory, -d Database directory path (your HTTP server's www root).
--cdiffs-rotate / --no-cdiffs-rotate Rotate (delete) old CDIFF files (default: on).
--cdiffs-to-keep Number of CDIFFs to keep per database when rotating (default 30).
--state-file Path to the state file (stores versions, UUID, and per-database metadata).
# e.g. point databases at your web root and keep the state file alongside it
cvd config set --dbs-directory /var/www/html/clamav --logs-enabled

Do an update

Do an update, use "verbose mode" to so you can get a feel for how it works.

cvd update -V

List out the databases again:

cvd status

The print out the config again so you can see what's changed.

cvd config show

And maybe take a peek in the database directory as well to see it for yourself.

ls ~/.cvdupdate/database

Have a look at the logs if you wish.

ls ~/.cvdupdate/logs

cat ~/.cvdupdate/logs/*

Add an additional database

Maybe add an additional database that is not part of the default set of databases.

cvd add linux.cvd https://database.clamav.net/linux.cvd

To change the URL of a database that is already in the list, pass --override:

cvd add --override linux.cvd https://mirror.example.com/linux.cvd

List out the databases again:

cvd status

Serve it up, Test out FreshClam

Test out your mirror with FreshClam on the same computer.

This tool includes a --serve feature that will host the current database directory on http://localhost (default port: 8000).

You can test it by running freshclam or freshclam.exe locally, where you've configured freshclam.conf with:

DatabaseMirror http://localhost:8000

Use docker

Build the image:

docker build . --tag cvdupdate:latest

Run it to keep the databases in a local ./database directory updated on a schedule:

docker run -d \
  -v "$(pwd)/database:/cvdupdate/database" \
  cvdupdate:latest

The container is configured with environment variables:

Variable Default Description
CRON 30 */4 * * * Update schedule (see Cron Example).
USER_ID 0 UID that owns the files and runs the updater; set non-zero to avoid running as root.
ENABLE_LOGS unset Set to any value other than false to write log files to /cvdupdate/logs.
LOGS_TO_KEEP 30 Number of daily log files to keep (positive integer).
EXTRA_DATABASES unset Comma-separated <db_name>:<db_url> entries to add on startup.
REMOVE_DATABASES unset Comma-separated database names to remove on startup.

File logging is off by default — the container writes to stdout/stderr, which you can view with docker logs. If you also want log files on the host, enable file logging and mount the logs directory:

docker run -d \
  -v "$(pwd)/database:/cvdupdate/database" \
  -v "$(pwd)/logs:/cvdupdate/logs" \
  -e ENABLE_LOGS=true \
  cvdupdate:latest

Run as a non-root user (UID 1000) and update once a day at midnight:

docker run -d \
  -v "$(pwd)/database:/cvdupdate/database" \
  -e USER_ID=1000 \
  -e CRON='0 0 * * *' \
  cvdupdate:latest

Pass a command as arguments to run it once and exit, instead of starting the update cron. For example, a single update:

docker run --rm \
  -v "$(pwd)/database:/cvdupdate/database" \
  cvdupdate:latest cvdupdate update

Any cvdupdate command works this way (e.g. cvdupdate status, etc).

Use Docker Compose

Example docker compose.yaml is provided to:

  1. Regularly update a Docker volume with the latest ClamAV databases.
  2. Serve a database mirror on port 8000 using the Apache webserver.

Build

docker compose build

Start

docker compose up -d

Stop

docker compose down

Volumes

Volumes are defined in compose.yaml and will be auto-created when you run docker compose up

DRIVER    VOLUME NAME
local     cvdupdate_database
local     cvdupdate_log

Contribute

We'd love your help. There are many ways to contribute!

Community

Join the ClamAV community on the ClamAV Discord chat server.

Report issues

If you find an issue with CVD-Update or the CVD-Update documentation, please submit an issue to our GitHub issue tracker. Before you submit, please check to if someone else has already reported the issue.

Development

If you find a bug and you're able to craft a fix yourself, consider submitting the fix in a pull request. Your help will be greatly appreciated.

If you want to contribute to the project and don't have anything specific in mind, please check out our issue tracker. Perhaps you'll be able to fix a bug or add a cool new feature.

By submitting a contribution to the project, you acknowledge and agree to assign Cisco Systems, Inc the copyright for the contribution. If you submit a significant contribution such as a new feature or capability or a large amount of code, you may be asked to sign a contributors license agreement comfirming that Cisco will have copyright license and patent license and that you are authorized to contribute the code.

Development Set-up

The following steps are intended to help users that wish to contribute to development of the CVD-Update project get started.

  1. Create a fork of the CVD-Update git repository, and then clone your fork to a local directory.

    For example:

    git clone https://github.com/<your username>/cvdupdate.git
  2. Make sure CVD-Update is not already installed. If it is, remove it.

    python3 -m pip uninstall cvdupdate
  3. Use pip to install CVD-Update in "edit" mode.

    python3 -m pip install -e --user ./cvdupdate

Once installed in "edit" mode, any changes you make to your clone of the CVD-Update code will be immediately usable simply by running the cvdupdate / cvd commands.

Conduct

This project has not selected a specific Code-of-Conduct document at this time. However, contributors are expected to behave in professional and respectful manner. Disrespectful or inappropriate behavior will not be tolerated.

License

CVD-Update is licensed under the Apache License, Version 2.0 (the "License"). You may not use the CVD-Update project except in compliance with the License.

A copy of the license is located here, and is also available online at apache.org.

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

About

ClamAV Private Database Mirror Updater Tool

Resources

Stars

118 stars

Watchers

12 watching

Forks

Releases

Packages

Used by

Contributors

Languages