Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BC-8023 remove virustotal entirely #60

Merged
merged 2 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 2 additions & 47 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Antivirus Check Service

The __Antivirus Check Service__ provides the ability to scan files with a locally installed clamav daemon. In addition, the service offers a URL scan using [virustotal](https://www.virustotal.com).
The __Antivirus Check Service__ provides the ability to scan files with a locally installed clamav daemon.
The __Antivirus Check Service__ processes incoming scan requests and sends the scan result to a specified web hook.

## Usage
Expand All @@ -27,21 +27,6 @@ A GET request to `https://<antivirus-check-service>/` gives a detailed usage api
},
}
},
"scan url request": {
"description": "Scan Url (using virustotal), report back to given webhook Uri",
"path": "/scan/url",
"method": "POST",
"params": {
"url": {
"type": "string",
"description": "Url to scan using virustotal"
},
"callback_uri": {
"type": "string",
"description": "Complete Uri to the callback uri"
},
}
},
"clamav daemon version": {
"description": "Get clamav daemon version and last database update",
"path": "/antivirus-version",
Expand Down Expand Up @@ -71,16 +56,6 @@ Authenticate and publish a message to the regarding queue using the routing_key:
}
~~~

#### scan url:
- routing key: `scan_url`
- message:
~~~json
{
"url": "https://<url-to-be-scanned>",
"callback_uri": "https://<uri-to-report-endpoint>"
}
~~~

### Reports
The reports are PUT requests to the given webhook Uri. The payload differs reagrding the scan type.

Expand All @@ -89,11 +64,6 @@ The reports are PUT requests to the given webhook Uri. The payload differs reagr
{"virus_detected": "<true|false>", "virus_signature": "<null|signature name>"}
~~~

#### scan url payload
~~~json
{"blacklisted": "<true|false>", "full_report": "<virustotal's full report>"}
~~~

### Error
If an error occures the __Antivirus Check Service__ will try to send an error page (500) with the error message as json:
~~~json
Expand All @@ -102,21 +72,6 @@ If an error occures the __Antivirus Check Service__ will try to send an error pa

## CONFIGURATION

The configurate is taken via env vars.

### VirusTotal
An API-Key is needed to use virustotal. To get this, an account on virustotal has to be created. The API-Key can be found in the account's settings.
The configurate is taken via env vars.

### Docker-Compose
- To start all services, you only have to to run `docker-compose up -d`
This will start all docker container:
- clamav
- rabbitmq
- webserver
- scanfile
- scanurl

The last three container will restart until rabbitmq is running properly (ca. 10 seconds)

- __BE PATIENT!__ At the first run, freshclam has to download all signatures, which can take a
while and prevent clamav-daemon from working.
8 changes: 0 additions & 8 deletions antivirus_service/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ def __init__(self, env, debug):
with env.prefixed(param.upper() + "_"):
self.config[self.env][param] = {}
self.config[self.env][param]['auth_users'] = env.list("AUTH_USERS")
param = "virustotal"
with env.prefixed(param.upper() + "_"):
self.config[self.env][param] = {}
self.config[self.env][param]['api_key'] = env.list("API_KEY")
param = "amqp"
with env.prefixed(param.upper() + "_"):
self.config[self.env][param] = {}
Expand All @@ -44,10 +40,6 @@ def __init__(self, env, debug):
self.config[self.env][param]['scan_file'] = {}
self.config[self.env][param]['scan_file']['queue'] = env("QUEUE", "scan_file_v2")
self.config[self.env][param]['scan_file']['routing_key'] = env("ROUTING_KEY", "scan_file_v2")
with env.prefixed("SCAN_URL_"):
self.config[self.env][param]['scan_url'] = {}
self.config[self.env][param]['scan_url']['queue'] = env("QUEUE", "scan_url")
self.config[self.env][param]['scan_url']['routing_key'] = env("ROUTING_KEY", "scan_url")

loglevel = logging.INFO if debug else logging.ERROR
logging.basicConfig(level=loglevel)
Expand Down
37 changes: 0 additions & 37 deletions antivirus_service/webserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ def __init__(self, settings):
app = web.Application()
app.router.add_get('/', self.index)
app.router.add_post('/scan/file', self.handle_file)
app.router.add_post('/scan/url', self.handle_uri)
app.router.add_get('/antivirus-version', self.handle_version)
self.app = app

Expand All @@ -64,21 +63,6 @@ async def index(self, request):
},
}
},
"scan url request": {
"description": "Scan Url (using virustotal), report back to given webhook Uri",
"path": "/scan/url",
"method": "POST",
"params": {
"url": {
"type": "string",
"description": "Url to scan using virustotal"
},
"callback_uri": {
"type": "string",
"description": "Complete Uri to the callback uri"
},
}
},
"clamav daemon version": {
"description": "Get clamav daemon version and last database update",
"path": "/antivirus-version",
Expand All @@ -105,30 +89,9 @@ async def handle_file(self, request):
logging.error('error', exc_info=True)
return web.Response(status=500, text=str(e))

@auth_required
async def handle_uri(self, request):
body = await request.read()
try:
payload = json.loads(bytes(body).decode('utf-8'))
assert 'url' in payload
assert 'callback_uri' in payload

self.enqueue_scan_url_request(body)
return web.Response(status=202,
text='The request has been accepted for processing, but the processing has not been completed.')

except AssertionError:
return web.Response(status=422, text='Unprocessable Entity: missing parameter')
except Exception as e:
logging.error('error', exc_info=True)
return web.Response(status=500, text=str(e))

def enqueue_scan_file_request(self, body):
self.send(body, self.amqp_config['scan_file']['routing_key'])

def enqueue_scan_url_request(self, body):
self.send(body, routing_key=self.amqp_config['scan_url']['routing_key'])

def send(self, body, routing_key):
params = pika.URLParameters(self.amqp_config['url'])
with pika.BlockingConnection(params) as con:
Expand Down
38 changes: 0 additions & 38 deletions docker-compose.yml

This file was deleted.

3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ aiohttp==3.9.3
PyYAML==6.0.1
pika==1.3.2
aio_pika==9.3.1
environs==9.5.0
environs==9.5.0
setuptools==74.1.2
Loading