Quarkus Antivirus
A Quarkus extension that lets you scan files for viruses using a pluggable engine architecture.
Out of the box these engines are supported by this extension:
-
ClamAV which is a Linux Native antivirus server
-
VirusTotal which is a REST API to check the Hash of a file to see if it has already been reported for viruses
Installation
If you want to use this extension, you need to add the io.quarkiverse.antivirus:quarkus-antivirus
extension first to your build file.
For instance, with Maven, add the following dependency to your POM file:
<dependency>
<groupId>io.quarkiverse.antivirus</groupId>
<artifactId>quarkus-antivirus</artifactId>
<version>1.1.0</version>
</dependency>
Configuration
Now that you configured your POM to use the service, now you need to configure which scanner(s) you want to use in application.properties
:
ClamAV
ClamAV is an open source Linux based virus scanning engine. In development mode a DevService will start a ClamAV instance for you on TCP port 3310, so you can test locally during development.
If you override with your own host
and port
the DevService will not start.
quarkus.antivirus.clamav.enabled=true
quarkus.antivirus.clamav.health.enabled=true
%prod.quarkus.antivirus.clamav.host=192.168.7.72
%prod.quarkus.antivirus.clamav.port=3310
If you want to disable ClamAV health check at run-time and not build-time you can use the following configuration: |
quarkus.smallrye-health.check."io.quarkiverse.antivirus.runtime.ClamAVHealthCheck".enabled=false
VirusTotal
VirusTotal is a REST API that analyses suspicious files to detect malware using over 70 antivirus scanners. VirusTotal checks the hash of a file to see if it has been scanned and what the results are. You can set the threshold of how many of the 70+ engines you want to report the file as malicious before you consider it a malicious file using the minimum-votes
property.
quarkus.antivirus.virustotal.enabled=true
quarkus.antivirus.virustotal.key=<YOUR API KEY>
quarkus.antivirus.virustotal.minimum-votes=1
Usage
Simply inject the Antivirus
service, and it will run the scan against all configured services. It works against InputStream
so it can be used in any Quarkus application it is not constrained to REST applications only.
@Path("/antivirus")
@ApplicationScoped
public class AntivirusResource {
@Inject
Antivirus antivirus;
@PUT
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.TEXT_PLAIN)
@Path("/upload")
public Response upload(@MultipartForm @Valid final UploadRequest fileUploadRequest) {
final String fileName = fileUploadRequest.getFileName();
final InputStream data = fileUploadRequest.getData();
try {
// copy the stream to make it resettable
final ByteArrayInputStream inputStream = new ByteArrayInputStream(
IOUtils.toBufferedInputStream(data).readAllBytes());
// scan the file and check the results
List<AntivirusScanResult> results = antivirus.scan(fileName, inputStream);
for (AntivirusScanResult result : results) {
if (result.getStatus() != Response.Status.OK.getStatusCode()) {
throw new WebApplicationException(result.getMessage(), result.getStatus());
}
}
// reset the stream
inputStream.reset();
// write the file out to disk
final File tempFile = File.createTempFile("fileName", "tmp");
IOUtils.copy(inputStream, new FileOutputStream(tempFile));
} catch (AntivirusException | IOException e) {
throw new BadRequestException(e);
}
return Response.ok().build();
}
}
Pluggable
We can’t anticipate every antivirus engine out there and some may be proprietary. However, the architecture is designed to be pluggable, so you can plug your own engine in. Simply produce a bean that extends the AntivirusEngine
interface, and it will be picked up and used.
@ApplicationScoped
public class MyCustomEngine implements AntivirusEngine {
@Override
public boolean isEnabled() {
return true;
}
@Override
public AntivirusScanResult scan(final String filename, final InputStream inputStream) {
// scan your file here
}
}
Dev UI
The Dev UI will let you inspect the running ClamAV Dev Service.
You can also inspect the container image that was started under Dev Services:
You can view all of ClamAV’s container logs right in the DevUI log.
Extension Configuration Reference
Configuration property fixed at build time - All other configuration properties are overridable at runtime
Configuration property |
Type |
Default |
---|---|---|
If Dev Services for ClamAV has been explicitly enabled or disabled. Dev Services are generally enabled by default, unless there is an existing configuration present. Environment variable: |
boolean |
|
The ClamAV container image to use. Environment variable: |
string |
|
Indicates if the ClamAV server managed by Quarkus Dev Services is shared. When shared, Quarkus looks for running containers using label-based service discovery. If a matching container is found, it is used, and so a second one is not started. Otherwise, Dev Services for ClamAV starts a new container. The discovery uses the Container sharing is only used in dev mode. Environment variable: |
boolean |
|
The value of the This property is used when you need multiple shared ClamAV servers. Environment variable: |
string |
|
The ClamAV container image to use. Environment variable: |
int |
|
Flag to enable the FreshClam daemon to update the virus database daily. Default it is disabled. Environment variable: |
boolean |
|
Enable or disable ClamAV container logging Environment variable: |
boolean |
|
If ClamAv registers in the health check by pinging the service. Environment variable: |
boolean |
|
Property to enable or disable the virus scanner. Useful for developers who don’t want to scan files locally. Environment variable: |
boolean |
|
The API endpoint for VirusTotal. Environment variable: |
string |
|
The API key for VirusTotal. Environment variable: |
string |
|
VirusTotal checks over 70+ different engine for virus and collates a count of how many of those 70 reported a file as malicious. This number lets you control how many engines have to report a file is malicious to raise an exception. Environment variable: |
int |
|
Property to enable or disable the virus scanner. Useful for developers who don’t want to scan files locally. Environment variable: |
boolean |
|
The IP Address of the machine where ClamAV is running. Environment variable: |
string |
|
The Port of the machine where ClamAV is running. Environment variable: |
int |
|
The timeout of how much time to give CLamAV to scan the virus before failing. Environment variable: |
int |
|
Size in bytes of the chunks of data to stream to the scanner at a time. Environment variable: |
int |
|
The timeout of how much time to give CLamAV to scan the virus before failing. Environment variable: |
int |
|