Skip to main content

cdk-serverless-clamscan

npm version PyPI version

An aws-cdk construct that uses ClamAV® to scan newly uploaded objects to Amazon S3 for viruses. The construct provides a flexible interface for a system to act based on the results of a ClamAV virus scan. Check out this blogpost for a guided walkthrough.

Overview

Pre-Requisites

Docker: The ClamAV Lambda functions utilizes a container image that is built locally using docker bundling

Examples

This project uses projen and thus all the constructs follow language specific standards and naming patterns. For more information on how to translate the following examples into your desired language read the CDK guide on Translating TypeScript AWS CDK code to other languages

Example 1. (Default destinations with rule target)

typescript

import { RuleTargetInput } from 'aws-cdk-lib/aws-events';
import { SnsTopic } from 'aws-cdk-lib/aws-events-targets';
import { Bucket } from 'aws-cdk-lib/aws-s3';
import { Topic } from 'aws-cdk-lib/aws-sns';
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { ServerlessClamscan } from 'cdk-serverless-clamscan';

export class CdkTestStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const bucket_1 = new Bucket(this, 'rBucket1');
    const bucket_2 = new Bucket(this, 'rBucket2');
    const bucketList = [bucket_1, bucket_2];
    const sc = new ServerlessClamscan(this, 'rClamscan', {
      buckets: bucketList,
    });
    const bucket_3 = new Bucket(this, 'rBucket3');
    sc.addSourceBucket(bucket_3);
    const infectedTopic = new Topic(this, 'rInfectedTopic');
    sc.infectedRule?.addTarget(
      new SnsTopic(infectedTopic, {
        message: RuleTargetInput.fromEventPath(
          '$.detail.responsePayload.message',
        ),
      }),
    );
  }
}

python

from aws_cdk import (
  Stack,
  aws_events as events,
  aws_events_targets as events_targets,
  aws_s3 as s3,
  aws_sns as sns
)
from cdk_serverless_clamscan import ServerlessClamscan
from constructs import Construct

class CdkTestStack(Stack):

  def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
    super().__init__(scope, construct_id, **kwargs)

    bucket_1 = s3.Bucket(self, "rBucket1")
    bucket_2 = s3.Bucket(self, "rBucket2")
    bucketList = [ bucket_1, bucket_2 ]
    sc = ServerlessClamscan(self, "rClamScan",
      buckets=bucketList,
    )
    bucket_3 = s3.Bucket(self, "rBucket3")
    sc.add_source_bucket(bucket_3)
    infected_topic = sns.Topic(self, "rInfectedTopic")
    if sc.infected_rule != None:
      sc.infected_rule.add_target(
        events_targets.SnsTopic(
          infected_topic,
          message=events.RuleTargetInput.from_event_path('$.detail.responsePayload.message'),
        )
      )

Example 2. (Bring your own destinations)

typescript

import {
  SqsDestination,
  EventBridgeDestination,
} from 'aws-cdk-lib/aws-lambda-destinations';
import { Bucket } from 'aws-cdk-lib/aws-s3';
import { Queue } from 'aws-cdk-lib/aws-sqs';
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { ServerlessClamscan } from 'cdk-serverless-clamscan';

export class CdkTestStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const bucket_1 = new Bucket(this, 'rBucket1');
    const bucket_2 = new Bucket(this, 'rBucket2');
    const bucketList = [bucket_1, bucket_2];
    const queue = new Queue(this, 'rQueue');
    const sc = new ServerlessClamscan(this, 'default', {
      buckets: bucketList,
      onResult: new EventBridgeDestination(),
      onError: new SqsDestination(queue),
    });
    const bucket_3 = new Bucket(this, 'rBucket3');
    sc.addSourceBucket(bucket_3);
  }
}

python

from aws_cdk import (
  Stack,
  aws_lambda_destinations as lambda_destinations,
  aws_s3 as s3,
  aws_sqs as sqs
)
from cdk_serverless_clamscan import ServerlessClamscan
from constructs import Construct

class CdkTestStack(Stack):

  def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
    super().__init__(scope, construct_id, **kwargs)

    bucket_1 = s3.Bucket(self, "rBucket1")
    bucket_2 = s3.Bucket(self, "rBucket2")
    bucketList = [ bucket_1, bucket_2 ]
    queue = sqs.Queue(self, "rQueue")
    sc = ServerlessClamscan(self, "rClamScan",
      buckets=bucketList,
      on_result=lambda_destinations.EventBridgeDestination(),
      on_error=lambda_destinations.SqsDestination(queue),
    )
    bucket_3 = s3.Bucket(self, "rBucket3")
    sc.add_source_bucket(bucket_3)

Operation and Maintenance

When ClamAV publishes updates to the scanner you will see “Your ClamAV installation is OUTDATED” in your scan results. While the construct creates a system to keep the database definitions up to date, you must update the scanner to detect all the latest Viruses.

Update the docker images of the Lambda functions with the latest version of ClamAV by re-running cdk deploy.

Optionally Skip Files

In certain situations, you may have files which are already scanned and you wish to omit them from ClamAV scanning. In that case, simply tag the s3 object with "scan-status": "N/A" and the file will be automatically skipped.

Example 1. (Upload file to skip)

python/boto

boto3.client('s3').upload_file(
    Filename=file_path,
    Bucket=bucket_name,
    Key=object_key,
    ExtraArgs={'Tagging': 'scan-status=N/A'}
)

typscript/aws-sdk

const params = {
  Bucket: bucketName,
  Key: objectKey,
  Body: fileContent,
  Tagging: 'scan-status=N/A',
};
const command = new PutObjectCommand(params);
const response = await (new S3Client()).send(command);

API Reference

See API.md.

Contributing

See CONTRIBUTING for more information.

License

This project is licensed under the Apache-2.0 License.

Metadata

Release files for cdk-serverless-clamscan 2.13.47

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cdk-serverless-clamscan 2.13.47
File Size Uploaded Provenance Actions
cdk_serverless_clamscan-2.13.47.tar.gz 166.0 kB Without provenance Details for cdk_serverless_clamscan-2.13.47.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for cdk-serverless-clamscan 2.13.47
File Interpreter ABI Platform Actions
cdk_serverless_clamscan-2.13.47-py3-none-any.whl Python 3 none any Details for cdk_serverless_clamscan-2.13.47-py3-none-any.whl

Total release size: 330.2 kB

Release files / cdk_serverless_clamscan-2.13.47.tar.gz

Download URL cdk_serverless_clamscan-2.13.47.tar.gz
Size 166.0 kB
Tags Source
SHA-256 checksum
How to use checksums
1b2b4e9a0228192b5d5d13df7ebdb04840a2069957664aa98b10026796485443
BLAKE2b-256 checksum
How to use checksums
57e873266ce6e5505f16d5039e72f2f189b8790bbe2c7f7f76e8d23e6fd2d051
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.14.2

Release files / cdk_serverless_clamscan-2.13.47-py3-none-any.whl

Download URL cdk_serverless_clamscan-2.13.47-py3-none-any.whl
Size 164.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
345d02c3a4e1d32c2740fac5323cb5596c9fb3909b0c8613c73abcf0bd70dacc
BLAKE2b-256 checksum
How to use checksums
b85c1c97137fd4f490adcfc869e5ac83f310413bb22c243fc1d68edd6d166a31
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.14.2

Security for cdk-serverless-clamscan 2.13.47

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

2.13.47 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page