Skip to content

Commit

Permalink
refactor: use S6 and alpine (#10)
Browse files Browse the repository at this point in the history
* use `s6-overlay` as service manger
* use Alpine Linux as base image
  • Loading branch information
chrisgacsal authored Nov 30, 2023
1 parent 48340e4 commit b56b96c
Show file tree
Hide file tree
Showing 14 changed files with 319 additions and 43 deletions.
72 changes: 48 additions & 24 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,33 +1,57 @@
FROM nginx:latest
FROM nginx:1.25.3-alpine-slim

RUN apt-get update && \
apt-get install -y clamav clamav-freshclam cron
RUN apk add --no-cache -X http://dl-cdn.alpinelinux.org/alpine/edge/community freshclam

RUN mkdir -p /usr/share/nginx/html/clamav
ADD --link --chmod=644 clamav/freshclam.conf /etc/clamav/freshclam.conf

# Change ownership of the clamav directory to the clamav user and group
RUN chown clamav:clamav /usr/share/nginx/html/clamav
# Fail the build if downloading updates gets rate-limited
RUN freshclam --stdout --verbose --on-update-execute=/bin/false

# Download the initial signature files so they're present once already when the container is up
RUN freshclam --datadir=/usr/share/nginx/html/clamav
ADD --link nginx/default.conf /etc/nginx/conf.d/default.conf

# Update the Nginx configuration to serve the signature files
RUN echo 'server {' > /etc/nginx/conf.d/clamav.conf && \
echo ' listen 80;' >> /etc/nginx/conf.d/clamav.conf && \
echo ' location /clamav/ {' >> /etc/nginx/conf.d/clamav.conf && \
echo ' alias /usr/share/nginx/html/clamav/;' >> /etc/nginx/conf.d/clamav.conf && \
echo ' autoindex on;' >> /etc/nginx/conf.d/clamav.conf && \
echo ' }' >> /etc/nginx/conf.d/clamav.conf && \
echo '}' >> /etc/nginx/conf.d/clamav.conf
RUN nginx -t

# Set up a cron job to update the database files every 3 hours
RUN echo "0 */3 * * * root freshclam --datadir=/usr/share/nginx/html/clamav --quiet" > /etc/cron.d/freshclam-mirror
ARG TARGETPLATFORM

# Make sure the cron job file has proper permissions
RUN chmod 0644 /etc/cron.d/freshclam-mirror
RUN <<EOT
set -e

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
version=3.1.6.2
url=
checksum=

# Use the entrypoint script to start freshclam, cron, and Nginx
ENTRYPOINT ["/entrypoint.sh"]
## Install s6-overlay scripts
url=https://github.com/just-containers/s6-overlay/releases/download/v${version}/s6-overlay-noarch.tar.xz
checksum=05af2536ec4fb23f087a43ce305f8962512890d7c71572ed88852ab91d1434e3

archive="$(basename ${url})"
wget -q -O "${archive}" "${url}"
printf "%s %s" "${checksum}" "${archive}" | sha256sum -c -
tar -C / -Jxpf "${archive}"

## Install s6-overlay binaries
case "$TARGETPLATFORM" in
"linux/amd64")
url=https://github.com/just-containers/s6-overlay/releases/download/v${version}/s6-overlay-x86_64.tar.xz
checksum=95081f11c56e5a351e9ccab4e70c2b1c3d7d056d82b72502b942762112c03d1c
;;
"linux/arm64")
url=https://github.com/just-containers/s6-overlay/releases/download/v${version}/s6-overlay-aarch64.tar.xz
checksum=3fc0bae418a0e3811b3deeadfca9cc2f0869fb2f4787ab8a53f6944067d140ee
;;
*)
printf "ERROR: %s" "invalid architecture"
exit 1
esac

archive="$(basename ${url})"
wget -q -O "${archive}" "${url}"
printf "%s %s" "${checksum}" "${archive}" | sha256sum -c -
tar -C / -Jxpf "${archive}"
EOT

ADD --link --chmod=755 s6-rc.d/freshclam /etc/s6-overlay/s6-rc.d/freshclam
ADD --link --chmod=755 s6-rc.d/nginx /etc/s6-overlay/s6-rc.d/nginx
ADD --link --chmod=755 s6-rc.d/user/contents.d/* /etc/s6-overlay/s6-rc.d/user/contents.d/

ENTRYPOINT ["/init"]
19 changes: 8 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
# Freshclam Mirror

A private ClamAV freshclam mirror server which periodically syncs signatures
using freshclam.

This is achieved using nginx, freshclam and cron.

The Dockerfile provides the definition for a server that serves the ClamAV signature files and updates them every 3 hours.

Private ClamAV mirror server which periodically syncs signatures using `freshclam`.
The `s6-overlay` is used as process supervisor for running `nginx` and `freshclam` daemons.

## Table of Contents<!-- omit in toc -->

Expand All @@ -21,9 +16,11 @@ The Dockerfile provides the definition for a server that serves the ClamAV signa
# Usage

## Directing freshclam to use this mirror
To direct your freshclam instance to this mirror, configure your freshclam.conf file as such:

Update `freshclam.conf` file with the following settings to make `freshclam` to use this mirror:

```
PrivateMirror http://<ip>:1000
PrivateMirror http://<ip>:<port>
ScriptedUpdates no
```

Expand All @@ -34,12 +31,12 @@ docker build -t <registry-name>/vmclarity-freshclam-mirror .

## Running
```
docker run -d -p 1000:80 --name vmclarity-freshclam-mirror <registry-name>/vmclarity-freshclam-mirror
docker run -d -p <port>:80 --name vmclarity-freshclam-mirror <registry-name>/vmclarity-freshclam-mirror
```

## Manual signatures download
```
curl -X GET http://<ip>:1000/clamav/main.cvd --output main.cvd
curl -X GET http://<ip>:<port>/clamav/main.cvd --output main.cvd
```

## Contributing
Expand Down
197 changes: 197 additions & 0 deletions clamav/freshclam.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
# Path to the database directory.
# WARNING: It must match clamd.conf's directive!
# Default: hardcoded (depends on installation options)
DatabaseDirectory /var/lib/clamav

# Path to the log file (make sure it has proper permissions)
# Default: disabled
#UpdateLogFile /var/log/freshclam.log

# Maximum size of the log file.
# Value of 0 disables the limit.
# You may use 'M' or 'm' for megabytes (1M = 1m = 1048576 bytes)
# and 'K' or 'k' for kilobytes (1K = 1k = 1024 bytes).
# in bytes just don't use modifiers. If LogFileMaxSize is enabled,
# log rotation (the LogRotate option) will always be enabled.
# Default: 1M
#LogFileMaxSize 2M

# Log time with each message.
# Default: no
#LogTime yes

# Enable verbose logging.
# Default: no
LogVerbose no

# Use system logger (can work together with UpdateLogFile).
# Default: no
#LogSyslog yes

# Specify the type of syslog messages - please refer to 'man syslog'
# for facility names.
# Default: LOG_LOCAL6
#LogFacility LOG_MAIL

# Enable log rotation. Always enabled when LogFileMaxSize is enabled.
# Default: no
#LogRotate yes

# Write the daemon's pid to the specified file.
# You must run freshclam with --daemon (-d) for freshclam to run as a daemon.
# This file will be owned by root, as long as freshclam was started by root.
# It is recommended that the directory where this file is stored is
# also owned by root to keep other users from tampering with it.
# Default: disabled
#PidFile /run/clamav/freshclam.pid

# By default when started freshclam drops privileges and switches to the
# "clamav" user. This directive allows you to change the database owner.
# Default: clamav (may depend on installation options)
DatabaseOwner clamav

# Use DNS to verify virus database version. FreshClam uses DNS TXT records
# to verify database and software versions. With this directive you can change
# the database verification domain.
# WARNING: Do not touch it unless you're configuring freshclam to use your
# own database verification domain.
# Default: current.cvd.clamav.net
DNSDatabaseInfo current.cvd.clamav.net

# database.clamav.net is now the primary domain name to be used world-wide.
# Now that CloudFlare is being used as our Content Delivery Network (CDN),
# this one domain name works world-wide to direct freshclam to the closest
# geographic endpoint.
# If the old db.XY.clamav.net domains are set, freshclam will automatically
# use database.clamav.net instead.
DatabaseMirror db.local.clamav.net
DatabaseMirror database.clamav.net

# How many attempts to make before giving up.
# Default: 3 (per mirror)
MaxAttempts 5

# With this option you can control scripted updates. It's highly recommended
# to keep it enabled.
# Default: yes
ScriptedUpdates yes

# By default freshclam will keep the local databases (.cld) uncompressed to
# make their handling faster. With this option you can enable the compression;
# the change will take effect with the next database update.
# Default: no
#CompressLocalDatabase no

# With this option you can provide custom sources for database files.
# This option can be used multiple times. Support for:
# http(s)://, ftp(s)://, or file://
# Default: no custom URLs
#DatabaseCustomURL http://myserver.example.com/mysigs.ndb
#DatabaseCustomURL https://myserver.example.com/mysigs.ndb
#DatabaseCustomURL https://myserver.example.com:4567/allow_list.wdb
#DatabaseCustomURL ftp://myserver.example.com/example.ldb
#DatabaseCustomURL ftps://myserver.example.com:4567/example.ndb
#DatabaseCustomURL file:///mnt/nfs/local.hdb

# This option allows you to easily point freshclam to private mirrors.
# If PrivateMirror is set, freshclam does not attempt to use DNS
# to determine whether its databases are out-of-date, instead it will
# use the If-Modified-Since request or directly check the headers of the
# remote database files. For each database, freshclam first attempts
# to download the CLD file. If that fails, it tries to download the
# CVD file. This option overrides DatabaseMirror, DNSDatabaseInfo
# and ScriptedUpdates. It can be used multiple times to provide
# fall-back mirrors.
# Default: disabled
#PrivateMirror mirror1.example.com
#PrivateMirror mirror2.example.com

# Number of database checks per day.
# Default: 12 (every two hours)
Checks 24

# Proxy settings
# The HTTPProxyServer may be prefixed with [scheme]:// to specify which kind
# of proxy is used.
# http:// HTTP Proxy. Default when no scheme or proxy type is specified.
# https:// HTTPS Proxy. (Added in 7.52.0 for OpenSSL, GnuTLS and NSS)
# socks4:// SOCKS4 Proxy.
# socks4a:// SOCKS4a Proxy. Proxy resolves URL hostname.
# socks5:// SOCKS5 Proxy.
# socks5h:// SOCKS5 Proxy. Proxy resolves URL hostname.
# Default: disabled
#HTTPProxyServer https://proxy.example.com
#HTTPProxyPort 1234
#HTTPProxyUsername myusername
#HTTPProxyPassword mypass

# If your servers are behind a firewall/proxy which applies User-Agent
# filtering you can use this option to force the use of a different
# User-Agent header.
# As of ClamAV 0.103.3, this setting may not be used when updating from the
# clamav.net CDN and can only be used when updating from a private mirror.
# Default: clamav/version_number (OS: ..., ARCH: ..., CPU: ..., UUID: ...)
#HTTPUserAgent SomeUserAgentIdString

# Use aaa.bbb.ccc.ddd as client address for downloading databases. Useful for
# multi-homed systems.
# Default: Use OS'es default outgoing IP address.
#LocalIPAddress aaa.bbb.ccc.ddd

# Send the RELOAD command to clamd.
# Default: no
#NotifyClamd /etc/clamav/clamd.conf

# Run command after successful database update.
# Use EXIT_1 to return 1 after successful database update.
# Default: disabled
#OnUpdateExecute command

# Run command when database update process fails.
# Default: disabled
#OnErrorExecute command

# Run command when freshclam reports outdated version.
# In the command string %v will be replaced by the new version number.
# Default: disabled
#OnOutdatedExecute command

# Don't fork into background.
# Default: no
Foreground yes

# Enable debug messages in libclamav.
# Default: no
#Debug yes

# Timeout in seconds when connecting to database server.
# Default: 30
ConnectTimeout 60

# Timeout in seconds when reading from database server. 0 means no timeout.
# Default: 60
ReceiveTimeout 0

# With this option enabled, freshclam will attempt to load new databases into
# memory to make sure they are properly handled by libclamav before replacing
# the old ones.
# Tip: This feature uses a lot of RAM. If your system has limited RAM and you
# are actively running ClamD or ClamScan during the update, then you may need
# to set `TestDatabases no`.
# Default: yes
TestDatabases yes

# This option enables downloading of bytecode.cvd, which includes additional
# detection mechanisms and improvements to the ClamAV engine.
# Default: yes
#Bytecode no

# Include an optional signature databases (opt-in).
# This option can be used multiple times.
#ExtraDatabase dbname1
#ExtraDatabase dbname2

# Exclude a standard signature database (opt-out).
# This option can be used multiple times.
#ExcludeDatabase dbname1
#ExcludeDatabase dbname2
8 changes: 0 additions & 8 deletions entrypoint.sh

This file was deleted.

28 changes: 28 additions & 0 deletions nginx/default.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
server {
listen 80;
server_name localhost;

server_tokens off;

sendfile on;
sendfile_max_chunk 1m;

location / {
alias /var/lib/clamav/;
autoindex on;
autoindex_exact_size off;
autoindex_format html;
}

location /clamav/ {
absolute_redirect off;
return 301 /;
}


error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

23 changes: 23 additions & 0 deletions s6-rc.d/freshclam/finish
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/command/execlineb -S1


# 0 : Database is up-to-date or successfully updated.
# 40: Unknown option passed.
# 50: Can't change directory.
# 51: Can't check MD5 sum.
# 52: Connection (network) problem.
# 53: Can't unlink file.
# 54: MD5 or digital signature verification error.
# 55: Error reading file.
# 56: Config file error.
# 57: Can't create new file.
# 58: Can't read database from remote server.
# 59: Mirrors are not fully synchronized (try again later).
# 60: Can't get information about '' user from /etc/passwd.
# 61: Can't drop privileges.
# 62: Can't initialize logger.

# Ignore error codes: 0, 52, 58, 59
if { eltest ${1} -ne 0 -a ${1} -ne 52 -a ${1} -ne 58 -a ${1} -ne 59 }

/run/s6/basedir/bin/halt
3 changes: 3 additions & 0 deletions s6-rc.d/freshclam/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/command/execlineb -P

exec freshclam --daemon
1 change: 1 addition & 0 deletions s6-rc.d/freshclam/type
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
longrun
Empty file.
7 changes: 7 additions & 0 deletions s6-rc.d/nginx/finish
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/command/execlineb -S0

foreground {
redirfd -w 1 /run/s6-linux-init-container-results/exitcode echo "$1"
}

/run/s6/basedir/bin/halt
Loading

0 comments on commit b56b96c

Please sign in to comment.