Malware scan of uploads as a separate service¶
Context and Problem Statement¶
People, agents and imports upload files. Other people open them, agents process them. A file should be served only after a malware scan has checked it. How does the server scan without tying its own stability, license and memory planning to a virus scanner?
Decision Drivers¶
- No unchecked byte reaches receivers or agents (fail closed).
- A crash or out-of-memory condition of the scanner must not affect the server.
- The license of the server stays Apache-2.0.
- Runs self-hosted without data flowing out to third parties.
- Replaceable by other engines.
Considered Options¶
- ClamAV daemon (
clamd) as a separate service, addressed over theINSTREAMprotocol, with a small custom client behind a portScanner libclamavvia cgo in the server process- External scan service in the cloud
- ICAP interface to any virus scanner
- No scan
Decision Outcome¶
Chosen option: "ClamAV daemon as a separate service over INSTREAM", because it separates process,
memory and license from the server and no data leaves the premises. Default file.scan.mode =
required: if clamd is not ready, files stay pending and are not served. Hitting the size and
depth limits (AlertExceedsMax yes) counts as error, not as clean.
Details: 12-files.md section 5.
Consequences¶
- Good, because a crash or a reload of the signatures in clamd does not stop the server.
- Good, because the protocol is small (length-framed chunks, end with length 0) [Q1, verified] and a custom client needs no unmaintained library.
- Good, because the port
Scannercan later take ICAP or other engines. - Bad, because ClamAV needs a lot of memory (according to the project at least 3 GiB, better 4 GiB) and takes a long time to load at startup [Q2, verified]; small installations feel this.
- Bad, because clamd on TCP neither authenticates nor encrypts [Q1, verified]; the service must be reachable only in the internal network or over a Unix socket.
- Bad, because encrypted archives are not checked for their content by default
(
AlertEncrypted no); this is a documented residual risk.
Confirmation¶
- Integration test with a real clamd container: EICAR becomes
infectedand is never served. - Test with a stopped clamd: the file stays
pending, a fetch returns409 file_not_ready. - Test with an archive beyond
MaxRecursion: resulterror. - Startup check: the server does not start if
file.max_upload_bytesis larger thanfile.scan.clamd_stream_max_bytesand the scan is required. - Architecture rule: no cgo import of a scanner library in the server.
Pros and Cons of the Options¶
ClamAV daemon as a separate service over INSTREAM¶
- Good, because of process and memory separation.
- Good, because separate programs communicating over sockets normally do not form a combined work according to the GPL FAQ [Q3, verified]; ClamAV itself is under GPL-2.0 [Q4, verified]. The legal assessment stays with the instance operator (no legal advice).
- Neutral, because an official image for amd64 and arm64 exists (
clamav/clamav-debian) [Q5, verified]. - Bad, because another container with a high memory need runs.
libclamav via cgo in the server process¶
- Good, because there is no network path and no serialization.
- Bad, because the memory of the signatures lies in the server process and an error stops the server.
- Bad, because linking against GPL code affects the license of the server.
- Bad, because cgo makes the static binary and multi-arch builds harder.
External scan service in the cloud¶
- Good, because there are no on-site operations.
- Bad, because files go to third parties (data protection, processing by a processor) and the service is not necessarily reachable in private networks.
ICAP interface¶
- Good, because commercial virus scanners in companies often speak ICAP.
- Neutral, because the port
Scannercan take this adapter later. - Bad as the default, because ICAP with ClamAV needs another intermediary service.
No scan¶
- Good, because there is nothing to operate.
- Bad, because malware reaches people and agents unchecked. It remains only as an
explicit mode
offfor development and very small installations, visibly marked.
More Information¶
- Sources (retrieved 2026-10-10): Q1 https://docs.clamav.net/manual/Usage/ClamdProtocol.html [verified]; Q2 https://docs.clamav.net/manual/Installing/Docker.html [verified]; Q3 https://www.gnu.org/licenses/gpl-faq.html [verified]; Q4 https://raw.githubusercontent.com/Cisco-Talos/clamav/main/COPYING.txt [verified]; Q5 https://hub.docker.com/v2/repositories/clamav/clamav-debian/tags/stable [verified]; clamd options https://raw.githubusercontent.com/Cisco-Talos/clamav/main/etc/clamd.conf.sample [verified].
- Required settings for clamd and result mapping: 12-files.md sections 5.2 and 5.4. Compose stack: 16-operations.md.