commit c88afc78712e433668b3cbde00a7ad632876c76f Author: Vassiliy Yegorov Date: Thu Mar 12 16:24:25 2026 +0700 init diff --git a/.env b/.env new file mode 100644 index 0000000..048cf75 --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +HOST=clamav.realmanual.ru +CRONTAB_TIME="* * */1 * *" diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml new file mode 100644 index 0000000..e446a88 --- /dev/null +++ b/.gitea/workflows/build.yaml @@ -0,0 +1,38 @@ +name: Build Backend +on: + push: + branches: [main] + +env: + REGISTRY: git.realmanual.ru + IMAGE_PREFIX: ${{ gitea.repository }} + +permissions: + contents: read + packages: write + +jobs: + build: + name: Build image + runs-on: ubuntu-22.04 + container: catthehacker/ubuntu:act-latest + steps: + - uses: actions/checkout@v3 + - name: Read Version + id: version + run: echo "VERSION=$(cat ./VERSION)" >> $GITHUB_OUTPUT + - name: Log in to Gitea Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.TOKEN }} + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: ./ + file: ./Dockerfile + push: true + tags: | + ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/clamav-mirror:${{ steps.version.outputs.VERSION }} + ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/clamav-mirror:latest diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a9d8b68 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +data/cvdupdate/*.json +data/cvdupdate/databases/* +data/cvdupdate/logs/* + +!.gitkeep diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f0dd4b8 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +ARG DOCKER_BASEIMAGE +FROM ${DOCKER_BASEIMAGE} + +ENV PYTHONUNBUFFERED 1 +WORKDIR /opt/app-root/src + +# Install Bash and Caddy +RUN apk add --no-cache bash caddy \ + && rm -rf /var/cache/apk/* + +# Install CVD-Update +RUN pip install --no-cache-dir cvdupdate + +# Copy Scripts +COPY src/ $WORKDIR +RUN chmod +x ./entrypoint.sh + +# Start Server +EXPOSE 8080 +CMD [ "./entrypoint.sh", "serve" ] diff --git a/README.md b/README.md new file mode 100644 index 0000000..1e7785e --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +# ClamAV-Mirror + +This is a Docker Image for a lightweight containerized ClamAV Mirror using [CVD-Update](https://github.com/Cisco-Talos/cvdupdate) and [Caddy](https://github.com/caddyserver/caddy). This image uses Alpine to minimize the image size and unnecessary bloat. + +## Dependencies + +- Docker + +## Quick Start Guide + +Run the following commands to build and run the clamav-mirror Docker image locally. + +### Build + +```sh +docker build . --file Dockerfile --tag clamav-mirror:latest +``` + +### Run (Ephemeral) + +```sh +docker compose up -d +``` + +### Manual update ClamAV Database definitions + +```sh +docker exec -it clamav-mirror ./entrypoint.sh update +``` + +### Cron + +Docker update automate and run always one day, but you may change it in .env file + +## ClamAV Configuration + +Once you have the mirror running, you can visit to see what files are hosted by this server. You can then point any of your ClamAV instances to use this mirror instead by changing the following in your `freshclam.conf` file: + +```txt +DatabaseMirror http://localhost:8080 +``` + +##### Author +- **Vassiliy Yegorov** [vasyakrg](https://github.com/vasyakrg) +- [site](https://realmanual.ru) +- [youtube](https://youtube.com/realmanual) +- [telegram](https://t.me/realmanual_group) diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..6e8bf73 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.1.0 diff --git a/data/.gitkeep b/data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/data/cvdupdate/databases/.gitkeep b/data/cvdupdate/databases/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/data/cvdupdate/logs/.gitkeep b/data/cvdupdate/logs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docker-build.sh b/docker-build.sh new file mode 100755 index 0000000..e40c77b --- /dev/null +++ b/docker-build.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +DOCKER_BASEIMAGE=docker.io/python:3.9-alpine + +docker buildx build --platform linux/amd64,linux/arm64 --push -t hub.realmanual.ru/pub/clamav-mirror \ + --build-arg DOCKER_BASEIMAGE=${DOCKER_BASEIMAGE} . diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7e782ab --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,29 @@ +version: '3.9' +services: + clamav-mirror: + image: hub.realmanual.ru/pub/clamav-mirror:latest + container_name: clamav-mirror + restart: always + labels: + - "traefik.enable=true" + - "traefik.http.routers.clamav-mirror.entrypoints=https" + - "traefik.http.routers.clamav-mirror.rule=Host(`${HOST}`)" + - "traefik.http.routers.clamav-mirror.tls=true" + - "traefik.http.routers.clamav-mirror.tls.certresolver=letsEncrypt" + - "traefik.http.services.clamav-mirror-service.loadbalancer.server.port=8080" + - "traefik.docker.network=webproxy" + environment: + - CRONTAB_TIME + expose: + - 8080 + volumes: + - ./data/cvdupdate:/mnt/cvdupdate + networks: + - clamav-net + - webproxy + +networks: + clamav-net: + name: clamav-net + webproxy: + external: true diff --git a/src/Caddyfile b/src/Caddyfile new file mode 100644 index 0000000..5220b3d --- /dev/null +++ b/src/Caddyfile @@ -0,0 +1,11 @@ +{ + admin off + auto_https off + http_port 8080 + https_port 8433 +} + +:8080 { + file_server browse + root * /mnt/cvdupdate/databases +} diff --git a/src/entrypoint.sh b/src/entrypoint.sh new file mode 100644 index 0000000..d6eac1a --- /dev/null +++ b/src/entrypoint.sh @@ -0,0 +1,77 @@ +#!/bin/bash +set -eo pipefail + +CVD_DIR="${CVD_DIR:=/mnt/cvdupdate}" + +# Configuration Functions +check_config() { + if [ ! -e $CVD_DIR/config.json ]; then + echo "Missing CVD configuration. Creating..." + cvd config set --config $CVD_DIR/config.json --dbdir $CVD_DIR/databases --logdir $CVD_DIR/logs + echo "CVD configuration created..." + fi +} + +show_config() { + echo "CVD-Update configuration..." + cvd config show --config $CVD_DIR/config.json + echo "Current contents in $CVD_DIR/databases directory..." + ls -al $CVD_DIR/databases +} + +# CVD Database Functions +check_database() { + if [ ! -e $CVD_DIR/databases ]; then + echo "Missing CVD database directory. Attempting to update..." + check_config + show_config + update_database + fi +} + +serve_database() { + if [ -e $CVD_DIR/databases ]; then + echo "Hosting ClamAV Database..." + if [ -e /mnt/Caddyfile ]; then + echo "Add cron with ${CRONTAB_TIME}" + echo "${CRONTAB_TIME} /opt/app-root/src/entrypoint.sh update >> /var/log/clamv-update.log" | /usr/bin/crontab - + echo "Using mounted Caddyfile config..." + crond -f & + exec caddy run --config ./Caddyfile --adapter caddyfile + else + echo "Add cron with ${CRONTAB_TIME}" + echo "${CRONTAB_TIME} /opt/app-root/src/entrypoint.sh update >> /var/log/clamv-update.log" | /usr/bin/crontab - + echo "Using default Caddyfile config..." + crond -f & + exec caddy run --config ./Caddyfile --adapter caddyfile + fi + else + echo "CVD database is missing..." + exit 1 + fi +} + +update_database() { + echo "Updating ClamAV Database..." + cvd update --config $CVD_DIR/config.json + echo "ClamAV Database updated..." +} + +# Argument Handler +case "$1" in + status) + check_config + show_config + ;; + + update) + check_config + show_config + update_database + ;; + + serve|*) + check_database + serve_database + ;; +esac