Deploy a distributed ClamAV antivirus cluster on Kubernetes with persistent storage, load balancing, and monitoring for enterprise-grade threat detection and scanning.
Prerequisites
- Kubernetes cluster with at least 3 nodes
- kubectl configured with cluster access
- NFS or similar shared storage for persistent volumes
- Helm 3.x installed
- Prometheus Operator for monitoring (optional)
What this solves
ClamAV cluster deployment on Kubernetes provides distributed antivirus scanning with high availability and automatic failover. This setup handles high-volume file scanning across multiple nodes, ensuring continuous threat detection without single points of failure. You'll configure persistent volumes for signature updates, implement load balancing for scan requests, and establish monitoring with alerting for cluster health.
Prerequisites and environment setup
Verify Kubernetes cluster requirements
Ensure your Kubernetes cluster meets the minimum requirements for ClamAV deployment with persistent storage and networking.
kubectl version --client --short
kubectl cluster-info
kubectl get nodes -o wide
Install required Kubernetes components
Install kubectl and Helm for managing the ClamAV cluster deployment and configuration.
sudo apt update
sudo apt install -y kubectl helm
curl https://get.helm.sh/helm-v3.13.0-linux-amd64.tar.gz | tar -xzf -
sudo mv linux-amd64/helm /usr/local/bin/
Create ClamAV namespace and RBAC
Set up dedicated namespace and service accounts for secure ClamAV cluster operation.
kubectl create namespace clamav-cluster
kubectl config set-context --current --namespace=clamav-cluster
Install and configure ClamAV components
Install ClamAV on cluster nodes
Install ClamAV daemon and command-line tools on all Kubernetes nodes for container image building.
sudo apt update
sudo apt install -y clamav clamav-daemon clamav-freshclam clamav-base
sudo systemctl stop clamav-freshclam
sudo systemctl stop clamav-daemon
Create ClamAV configuration ConfigMaps
Configure ClamAV daemon settings optimized for cluster deployment with TCP socket listening.
apiVersion: v1
kind: ConfigMap
metadata:
name: clamav-config
namespace: clamav-cluster
data:
clamd.conf: |
LogFile /var/log/clamav/clamd.log
LogFileMaxSize 10M
LogTime yes
DatabaseDirectory /var/lib/clamav
LocalSocket /var/run/clamav/clamd.sock
TCPSocket 3310
TCPAddr 0.0.0.0
MaxConnectionQueueLength 30
MaxThreads 20
ReadTimeout 300
CommandReadTimeout 30
SendBufTimeout 500
MaxQueue 200
IdleTimeout 60
ExcludePath ^/proc
ExcludePath ^/sys
User clamav
AllowSupplementaryGroups yes
ScanPE yes
ScanELF yes
ScanOLE2 yes
ScanPDF yes
ScanSWF yes
ScanMail yes
ScanPartialMessages yes
ScanArchive yes
MaxScanSize 500M
MaxFileSize 100M
MaxRecursion 20
MaxFiles 15000
MaxEmbeddedPE 40M
MaxHTMLNormalize 40M
MaxHTMLNoTags 8M
MaxScriptNormalize 20M
MaxZipTypeRcg 1M
SelfCheck 600
VirusEvent /usr/local/bin/virus-event.sh
freshclam.conf: |
DatabaseDirectory /var/lib/clamav
UpdateLogFile /var/log/clamav/freshclam.log
LogFileMaxSize 10M
LogTime yes
DatabaseOwner clamav
DNSDatabaseInfo current.cvd.clamav.net
DatabaseMirror db.local.clamav.net
DatabaseMirror database.clamav.net
MaxAttempts 3
Checks 2
ConnectTimeout 60
ReceiveTimeout 60
TestDatabases yes
CompressLocalDatabase no
Create virus event handler script
Configure alert script for virus detection events with logging and notification capabilities.
apiVersion: v1
kind: ConfigMap
metadata:
name: virus-event-script
namespace: clamav-cluster
data:
virus-event.sh: |
#!/bin/bash
ALERT_EMAIL="security@example.com"
INFECTED_FILE="$CLAM_VIRUSEVENT_FILENAME"
VIRUS_NAME="$CLAM_VIRUSEVENT_VIRUSNAME"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
HOSTNAME=$(hostname)
echo "[$TIMESTAMP] VIRUS DETECTED on $HOSTNAME: $VIRUS_NAME in $INFECTED_FILE" | tee -a /var/log/clamav/virus-alerts.log
# Send alert to monitoring system
curl -X POST http://alertmanager:9093/api/v1/alerts \
-H "Content-Type: application/json" \
-d '[{
"labels": {
"alertname": "VirusDetected",
"severity": "critical",
"instance": "'$HOSTNAME'",
"virus": "'$VIRUS_NAME'",
"file": "'$INFECTED_FILE'"
},
"annotations": {
"summary": "Virus detected by ClamAV",
"description": "ClamAV detected virus '$VIRUS_NAME' in file '$INFECTED_FILE' on host '$HOSTNAME'"
}
}]' 2>/dev/null || true
Set up Kubernetes persistent volumes
Create persistent volume claims for ClamAV data
Configure persistent storage for virus signatures and logs with appropriate sizing for cluster operations.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: clamav-data-pvc
namespace: clamav-cluster
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-client
resources:
requests:
storage: 5Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: clamav-logs-pvc
namespace: clamav-cluster
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-client
resources:
requests:
storage: 2Gi
Apply storage configuration
Create the persistent volume claims and verify their binding status.
kubectl apply -f clamav-storage.yaml
kubectl get pvc -n clamav-cluster
kubectl describe pvc clamav-data-pvc -n clamav-cluster
Deploy ClamAV cluster with high availability
Create ClamAV Deployment configuration
Deploy ClamAV with multiple replicas, health checks, and resource limits for production workloads.
apiVersion: apps/v1
kind: Deployment
metadata:
name: clamav-cluster
namespace: clamav-cluster
labels:
app: clamav
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: clamav
template:
metadata:
labels:
app: clamav
spec:
initContainers:
- name: clamav-init
image: clamav/clamav:1.3.1
command: ["sh", "-c"]
args:
- |
cp /etc/clamav/clamd.conf.template /etc/clamav/clamd.conf
cp /etc/clamav/freshclam.conf.template /etc/clamav/freshclam.conf
chown -R clamav:clamav /var/lib/clamav /var/log/clamav
chmod 755 /usr/local/bin/virus-event.sh
freshclam --foreground --config-file=/etc/clamav/freshclam.conf
volumeMounts:
- name: clamav-config
mountPath: /etc/clamav/clamd.conf
subPath: clamd.conf
- name: clamav-config
mountPath: /etc/clamav/freshclam.conf
subPath: freshclam.conf
- name: virus-event-script
mountPath: /usr/local/bin/virus-event.sh
subPath: virus-event.sh
- name: clamav-data
mountPath: /var/lib/clamav
- name: clamav-logs
mountPath: /var/log/clamav
containers:
- name: clamav
image: clamav/clamav:1.3.1
ports:
- containerPort: 3310
name: clamav-tcp
protocol: TCP
resources:
requests:
memory: "2Gi"
cpu: "1000m"
limits:
memory: "4Gi"
cpu: "2000m"
livenessProbe:
exec:
command:
- sh
- -c
- "echo 'PING' | nc -w 5 localhost 3310 | grep -q PONG"
initialDelaySeconds: 120
periodSeconds: 60
timeoutSeconds: 10
failureThreshold: 3
readinessProbe:
exec:
command:
- sh
- -c
- "echo 'PING' | nc -w 5 localhost 3310 | grep -q PONG"
initialDelaySeconds: 30
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 3
volumeMounts:
- name: clamav-config
mountPath: /etc/clamav/clamd.conf
subPath: clamd.conf
- name: clamav-config
mountPath: /etc/clamav/freshclam.conf
subPath: freshclam.conf
- name: virus-event-script
mountPath: /usr/local/bin/virus-event.sh
subPath: virus-event.sh
- name: clamav-data
mountPath: /var/lib/clamav
- name: clamav-logs
mountPath: /var/log/clamav
env:
- name: CLAMD_CONF_DatabaseDirectory
value: "/var/lib/clamav"
- name: CLAMD_CONF_TCPSocket
value: "3310"
- name: CLAMD_CONF_TCPAddr
value: "0.0.0.0"
- name: freshclam-updater
image: clamav/clamav:1.3.1
command: ["/bin/sh"]
args:
- -c
- |
while true; do
sleep 3600
freshclam --config-file=/etc/clamav/freshclam.conf --daemon-notify
done
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "200m"
volumeMounts:
- name: clamav-config
mountPath: /etc/clamav/freshclam.conf
subPath: freshclam.conf
- name: clamav-data
mountPath: /var/lib/clamav
- name: clamav-logs
mountPath: /var/log/clamav
volumes:
- name: clamav-config
configMap:
name: clamav-config
- name: virus-event-script
configMap:
name: virus-event-script
defaultMode: 0755
- name: clamav-data
persistentVolumeClaim:
claimName: clamav-data-pvc
- name: clamav-logs
persistentVolumeClaim:
claimName: clamav-logs-pvc
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- clamav
topologyKey: kubernetes.io/hostname
Apply ClamAV deployment
Deploy the ClamAV cluster and verify pod startup with proper resource allocation.
kubectl apply -f clamav-config.yaml
kubectl apply -f virus-event-configmap.yaml
kubectl apply -f clamav-deployment.yaml
kubectl get pods -n clamav-cluster -w
Configure high availability and load balancing
Create ClamAV Service for load balancing
Configure Kubernetes service to distribute scan requests across ClamAV cluster nodes with session affinity.
apiVersion: v1
kind: Service
metadata:
name: clamav-service
namespace: clamav-cluster
labels:
app: clamav
spec:
type: ClusterIP
sessionAffinity: None
ports:
- port: 3310
targetPort: 3310
protocol: TCP
name: clamav-tcp
selector:
app: clamav
---
apiVersion: v1
kind: Service
metadata:
name: clamav-headless
namespace: clamav-cluster
labels:
app: clamav
spec:
type: ClusterIP
clusterIP: None
ports:
- port: 3310
targetPort: 3310
protocol: TCP
name: clamav-tcp
selector:
app: clamav
Configure horizontal pod autoscaler
Enable automatic scaling based on CPU and memory utilization for handling variable scanning loads.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: clamav-hpa
namespace: clamav-cluster
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: clamav-cluster
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Percent
value: 50
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
Apply load balancing configuration
Deploy services and autoscaling configuration for high availability cluster operation.
kubectl apply -f clamav-service.yaml
kubectl apply -f clamav-hpa.yaml
kubectl get svc,hpa -n clamav-cluster
kubectl describe hpa clamav-hpa -n clamav-cluster
Implement monitoring and alerting
Deploy Prometheus monitoring for ClamAV
Configure Prometheus ServiceMonitor to collect ClamAV metrics and cluster health data.
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: clamav-metrics
namespace: clamav-cluster
labels:
app: clamav
spec:
selector:
matchLabels:
app: clamav
endpoints:
- port: metrics
interval: 30s
path: /metrics
---
apiVersion: v1
kind: Service
metadata:
name: clamav-metrics
namespace: clamav-cluster
labels:
app: clamav
spec:
type: ClusterIP
ports:
- port: 9090
targetPort: 9090
protocol: TCP
name: metrics
selector:
app: clamav-exporter
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: clamav-exporter
namespace: clamav-cluster
spec:
replicas: 1
selector:
matchLabels:
app: clamav-exporter
template:
metadata:
labels:
app: clamav-exporter
spec:
containers:
- name: clamav-exporter
image: solsson/clamav-exporter:latest
ports:
- containerPort: 9090
name: metrics
env:
- name: CLAMAV_HOST
value: "clamav-service"
- name: CLAMAV_PORT
value: "3310"
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "100m"
Configure ClamAV alert rules
Set up Prometheus alerting rules for cluster health monitoring and virus detection events.
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: clamav-alerts
namespace: clamav-cluster
labels:
app: clamav
spec:
groups:
- name: clamav.rules
rules:
- alert: ClamAVPodDown
expr: up{job="clamav-service"} == 0
for: 2m
labels:
severity: critical
annotations:
summary: "ClamAV pod is down"
description: "ClamAV pod {{ $labels.instance }} has been down for more than 2 minutes"
- alert: ClamAVHighMemoryUsage
expr: container_memory_usage_bytes{pod=~"clamav-cluster-.*"} / container_spec_memory_limit_bytes > 0.9
for: 5m
labels:
severity: warning
annotations:
summary: "ClamAV high memory usage"
description: "ClamAV pod {{ $labels.pod }} is using more than 90% of allocated memory"
- alert: ClamAVDatabaseOutdated
expr: (time() - clamav_database_last_update_timestamp) > 86400
for: 1m
labels:
severity: warning
annotations:
summary: "ClamAV virus database outdated"
description: "ClamAV database on {{ $labels.instance }} hasn't been updated in over 24 hours"
- alert: ClamAVVirusDetected
expr: increase(clamav_virus_detected_total[5m]) > 0
for: 0m
labels:
severity: critical
annotations:
summary: "Virus detected by ClamAV"
description: "ClamAV detected {{ $value }} virus(es) in the last 5 minutes on {{ $labels.instance }}"
- alert: ClamAVClusterUnhealthy
expr: count(up{job="clamav-service"} == 1) < 2
for: 3m
labels:
severity: critical
annotations:
summary: "ClamAV cluster unhealthy"
description: "Less than 2 ClamAV pods are healthy, cluster availability at risk"
Apply monitoring configuration
Deploy monitoring and alerting components for comprehensive ClamAV cluster observability.
kubectl apply -f clamav-monitoring.yaml
kubectl apply -f clamav-alerts.yaml
kubectl get servicemonitor,prometheusrule -n clamav-cluster
Security hardening and network policies
Create network policies for ClamAV isolation
Implement network segmentation to restrict traffic to ClamAV pods and prevent lateral movement.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: clamav-network-policy
namespace: clamav-cluster
spec:
podSelector:
matchLabels:
app: clamav
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: default
- namespaceSelector:
matchLabels:
name: monitoring
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: TCP
port: 3310
- protocol: TCP
port: 9090
egress:
- to: []
ports:
- protocol: TCP
port: 53
- protocol: UDP
port: 53
- to: []
ports:
- protocol: TCP
port: 80
- protocol: TCP
port: 443
- to:
- namespaceSelector:
matchLabels:
name: monitoring
ports:
- protocol: TCP
port: 9093
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-default
namespace: clamav-cluster
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Configure Pod Security Standards
Apply security contexts and pod security standards for hardened container execution.
apiVersion: v1
kind: LimitRange
metadata:
name: clamav-limits
namespace: clamav-cluster
spec:
limits:
- default:
memory: "4Gi"
cpu: "2000m"
defaultRequest:
memory: "2Gi"
cpu: "1000m"
type: Container
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: clamav-quota
namespace: clamav-cluster
spec:
hard:
requests.cpu: "10"
requests.memory: 20Gi
limits.cpu: "20"
limits.memory: 40Gi
persistentvolumeclaims: "4"
pods: "15"
Apply security hardening
Deploy network policies and resource constraints for secure cluster operation. For more advanced Kubernetes security, see our guide on configuring Kubernetes network policies for enhanced security.
kubectl apply -f clamav-network-policy.yaml
kubectl apply -f clamav-security-policy.yaml
kubectl get networkpolicy,limitrange,resourcequota -n clamav-cluster
Verify your setup
Test ClamAV cluster functionality
Verify that all ClamAV pods are running and responding to scan requests through the load balancer.
kubectl get pods -n clamav-cluster -o wide
kubectl logs -l app=clamav -n clamav-cluster --tail=50
kubectl exec -it deployment/clamav-cluster -n clamav-cluster -- clamdscan --version
Test virus scanning through service
Create a test file and scan it through the ClamAV service to verify cluster load balancing.
kubectl run clamav-test --image=busybox --rm -it --restart=Never -n clamav-cluster -- sh -c "
echo 'Testing ClamAV cluster' > /tmp/testfile.txt
echo 'PING' | nc clamav-service 3310
echo 'SCAN /tmp/testfile.txt' | nc clamav-service 3310
"
Verify monitoring and metrics
Check that monitoring components are collecting ClamAV metrics and alerting rules are active.
kubectl port-forward service/clamav-metrics 9090:9090 -n clamav-cluster &
curl -s http://localhost:9090/metrics | grep clamav
kubectl get servicemonitor,prometheusrule -n clamav-cluster
Test high availability failover
Simulate pod failure to verify cluster resilience and automatic recovery.
kubectl delete pod -l app=clamav --timeout=0s --grace-period=0 -n clamav-cluster
kubectl get pods -n clamav-cluster -w
kubectl get hpa clamav-hpa -n clamav-cluster
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Pods stuck in Init state | FreshClam database download failure | kubectl logs POD_NAME -c clamav-init -n clamav-cluster and check internet connectivity |
| High memory usage warnings | Large virus database or scan files | Increase memory limits in deployment and adjust MaxScanSize in config |
| Service connection refused | ClamAV not listening on TCP socket | Check TCPSocket and TCPAddr settings in clamd.conf ConfigMap |
| Persistent volume mount fails | Storage class not available | kubectl get storageclass and update storageClassName in PVC |
| Network policy blocks scanning | Overly restrictive ingress rules | Add source namespace labels to network policy ingress rules |
| Autoscaler not working | Metrics server not installed | kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml |
| Virus detection alerts not firing | Prometheus not scraping metrics | Check ServiceMonitor labels match Prometheus configuration |
Next steps
- Configure ClamAV integration with web servers and email systems for automated threat detection
- Set up centralized security monitoring with ClamAV and Elasticsearch for log aggregation
- Implement Kubernetes network policies for pod-to-pod security and traffic isolation
- Configure Kubernetes secrets management with Vault integration for secure container orchestration
- Set up Kubernetes monitoring with Prometheus Operator and custom metrics
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Global variables
NAMESPACE="clamav-cluster"
ALERT_EMAIL="${ALERT_EMAIL:-security@example.com}"
# Error handling
cleanup_on_error() {
echo -e "${RED}[ERROR] Installation failed. Cleaning up...${NC}"
kubectl delete namespace "$NAMESPACE" --ignore-not-found=true 2>/dev/null || true
}
trap cleanup_on_error ERR
usage() {
echo "Usage: $0 [OPTIONS]"
echo "Options:"
echo " -e EMAIL Alert email address (default: security@example.com)"
echo " -h Show this help message"
exit 1
}
# Parse command line arguments
while getopts "e:h" opt; do
case $opt in
e) ALERT_EMAIL="$OPTARG" ;;
h) usage ;;
*) usage ;;
esac
done
# Check if running as root or with sudo
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}This script must be run as root or with sudo${NC}"
exit 1
fi
echo -e "${BLUE}ClamAV Kubernetes Cluster Installation${NC}"
echo "========================================"
# Detect distribution
echo -e "${YELLOW}[1/9] Detecting distribution...${NC}"
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_UPDATE="apt update"
PKG_INSTALL="apt install -y"
CLAMAV_DAEMON_SERVICE="clamav-daemon"
FRESHCLAM_SERVICE="clamav-freshclam"
EPEL_INSTALL=""
;;
almalinux|rocky|centos|rhel|ol)
PKG_MGR="dnf"
PKG_UPDATE="dnf update -y"
PKG_INSTALL="dnf install -y"
CLAMAV_DAEMON_SERVICE="clamd@scan"
FRESHCLAM_SERVICE="clamav-freshclam"
EPEL_INSTALL="dnf install -y epel-release &&"
;;
fedora)
PKG_MGR="dnf"
PKG_UPDATE="dnf update -y"
PKG_INSTALL="dnf install -y"
CLAMAV_DAEMON_SERVICE="clamd@scan"
FRESHCLAM_SERVICE="clamav-freshclam"
EPEL_INSTALL=""
;;
amzn)
PKG_MGR="yum"
PKG_UPDATE="yum update -y"
PKG_INSTALL="yum install -y"
CLAMAV_DAEMON_SERVICE="clamd@scan"
FRESHCLAM_SERVICE="clamav-freshclam"
EPEL_INSTALL="yum install -y epel-release &&"
;;
*)
echo -e "${RED}Unsupported distribution: $ID${NC}"
exit 1
;;
esac
echo -e "${GREEN}Detected: $PRETTY_NAME${NC}"
else
echo -e "${RED}Cannot detect distribution${NC}"
exit 1
fi
# Verify Kubernetes cluster
echo -e "${YELLOW}[2/9] Verifying Kubernetes cluster...${NC}"
if ! command -v kubectl &> /dev/null; then
echo -e "${RED}kubectl not found. Installing...${NC}"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod 755 kubectl
mv kubectl /usr/local/bin/
fi
kubectl version --client --short
kubectl cluster-info
kubectl get nodes -o wide
# Install required tools
echo -e "${YELLOW}[3/9] Installing required tools...${NC}"
$PKG_UPDATE
if [ -n "$EPEL_INSTALL" ]; then
eval $EPEL_INSTALL
fi
# Install Helm if not present
if ! command -v helm &> /dev/null; then
echo -e "${YELLOW}Installing Helm...${NC}"
curl -fsSL https://get.helm.sh/helm-v3.13.0-linux-amd64.tar.gz | tar -xzf -
chmod 755 linux-amd64/helm
mv linux-amd64/helm /usr/local/bin/
rm -rf linux-amd64/
fi
# Install ClamAV packages based on distribution
echo -e "${YELLOW}[4/9] Installing ClamAV packages...${NC}"
case "$ID" in
ubuntu|debian)
$PKG_INSTALL clamav clamav-daemon clamav-freshclam clamav-base
;;
*)
$PKG_INSTALL clamav clamav-update clamav-scanner-systemd
;;
esac
# Stop ClamAV services
echo -e "${YELLOW}[5/9] Stopping ClamAV services...${NC}"
systemctl stop $CLAMAV_DAEMON_SERVICE 2>/dev/null || true
systemctl stop $FRESHCLAM_SERVICE 2>/dev/null || true
# Create namespace
echo -e "${YELLOW}[6/9] Creating Kubernetes namespace...${NC}"
kubectl create namespace "$NAMESPACE" --dry-run=client -o yaml | kubectl apply -f -
kubectl config set-context --current --namespace="$NAMESPACE"
# Create ClamAV configuration ConfigMap
echo -e "${YELLOW}[7/9] Creating ClamAV configuration...${NC}"
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: clamav-config
namespace: $NAMESPACE
data:
clamd.conf: |
LogFile /var/log/clamav/clamd.log
LogFileMaxSize 10M
LogTime yes
DatabaseDirectory /var/lib/clamav
LocalSocket /var/run/clamav/clamd.sock
TCPSocket 3310
TCPAddr 0.0.0.0
MaxConnectionQueueLength 30
MaxThreads 20
ReadTimeout 300
CommandReadTimeout 30
SendBufTimeout 500
MaxQueue 200
IdleTimeout 60
ExcludePath ^/proc
ExcludePath ^/sys
User clamav
AllowSupplementaryGroups yes
ScanPE yes
ScanELF yes
ScanOLE2 yes
ScanPDF yes
ScanSWF yes
ScanMail yes
ScanPartialMessages yes
ScanArchive yes
MaxScanSize 500M
MaxFileSize 100M
MaxRecursion 20
MaxFiles 15000
MaxEmbeddedPE 40M
MaxHTMLNormalize 40M
MaxHTMLNoTags 8M
MaxScriptNormalize 20M
MaxZipTypeRcg 1M
SelfCheck 600
VirusEvent /usr/local/bin/virus-event.sh
freshclam.conf: |
DatabaseDirectory /var/lib/clamav
UpdateLogFile /var/log/clamav/freshclam.log
LogFileMaxSize 10M
LogTime yes
DatabaseOwner clamav
DNSDatabaseInfo current.cvd.clamav.net
DatabaseMirror db.local.clamav.net
DatabaseMirror database.clamav.net
MaxAttempts 3
Checks 2
ConnectTimeout 60
ReceiveTimeout 60
TestDatabases yes
CompressLocalDatabase no
EOF
# Create virus event handler script
echo -e "${YELLOW}[8/9] Creating virus event handler...${NC}"
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: virus-event-script
namespace: $NAMESPACE
data:
virus-event.sh: |
#!/bin/bash
ALERT_EMAIL="$ALERT_EMAIL"
INFECTED_FILE="\$CLAM_VIRUSEVENT_FILENAME"
VIRUS_NAME="\$CLAM_VIRUSEVENT_VIRUSNAME"
TIMESTAMP=\$(date '+%Y-%m-%d %H:%M:%S')
HOSTNAME=\$(hostname)
# Log the event
echo "[\$TIMESTAMP] VIRUS DETECTED: \$VIRUS_NAME in \$INFECTED_FILE on \$HOSTNAME" >> /var/log/clamav/virus-events.log
# Send alert (requires mail command or SMTP configuration)
if command -v mail &> /dev/null; then
echo "VIRUS ALERT: \$VIRUS_NAME detected in \$INFECTED_FILE on \$HOSTNAME at \$TIMESTAMP" | mail -s "ClamAV Virus Alert" "\$ALERT_EMAIL"
fi
EOF
# Verification
echo -e "${YELLOW}[9/9] Verifying installation...${NC}"
echo -e "${GREEN}Checking namespace...${NC}"
kubectl get namespace "$NAMESPACE"
echo -e "${GREEN}Checking ConfigMaps...${NC}"
kubectl get configmaps -n "$NAMESPACE"
echo -e "${GREEN}Checking ClamAV installation...${NC}"
clamscan --version
echo -e "${GREEN}Installation completed successfully!${NC}"
echo ""
echo "Next steps:"
echo "1. Deploy ClamAV pods using the created ConfigMaps"
echo "2. Create persistent volumes for virus definitions"
echo "3. Set up service and ingress for load balancing"
echo "4. Configure monitoring and alerting"
echo ""
echo "Current namespace: $NAMESPACE"
echo "Alert email: $ALERT_EMAIL"
Review the script before running. Execute with: bash install.sh