README.md#1693
Open
dianecloud wants to merge 1 commit into
Open
Conversation
# cdk-serverless-clamscan [](https://badge.fury.io/js/cdk-serverless-clamscan) [](https://badge.fury.io/py/cdk-serverless-clamscan) An [aws-cdk](https://github.com/aws/aws-cdk) construct that uses [ClamAV®](https://www.clamav.net/) 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](https://aws.amazon.com/blogs/developer/virus-scan-s3-buckets-with-a-serverless-clamav-based-cdk-construct/) for a guided walkthrough.  ## Pre-Requisites **Docker:** The ClamAV Lambda functions utilizes a [container image](https://aws.amazon.com/blogs/aws/new-for-aws-lambda-container-image-support/) that is built locally using [docker bundling](https://aws.amazon.com/blogs/devops/building-apps-with-aws-cdk/) ## Examples This project uses [projen](https://github.com/projen/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](https://docs.aws.amazon.com/cdk/latest/guide/multiple_languages.html) ### Example 1. (Default destinations with rule target) <details><summary>typescript</summary> <p> ```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', ), }), ); } } ``` </p> </details> <details><summary>python</summary> <p> ```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'), ) ) ``` </p> </details> ### Example 2. (Bring your own destinations) <details><summary>typescript</summary> <p> ```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); } } ``` </p> </details> <details><summary>python</summary> <p> ```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) ``` </p> </details> ## 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) <details><summary>python/boto</summary> <p> ```python boto3.client('s3').upload_file( Filename=file_path, Bucket=bucket_name, Key=object_key, ExtraArgs={'Tagging': 'scan-status=N/A'} ) ``` </p></details> <details><summary>typscript/aws-sdk</summary> <p> ```typescript 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); ``` </p> </details> ## API Reference See [API.md](./API.md). ## Contributing See [CONTRIBUTING](./CONTRIBUTING.md) for more information. ## License This project is licensed under the Apache-2.0 License.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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