Code Monkey home page Code Monkey logo

ansible-clamav's Introduction

clamav

Ansible role which helps to install and configure ClamAV.

The configuration of the role is done in such way that it should not be necessary to change the role for any kind of configuration. All can be done either by changing role parameters or by declaring completely new configuration as a variable. That makes this role absolutely universal. See the examples below for more details.

Please report any issues or send PR.

Examples

---

- name: Example of how to install ClamAV in the default configuration
  hosts: all
  roles:
    - clamav

- name: Example of how change the configuration
  hosts: all
  vars:
    # Disable mail scanning for Clamd
    clamav_clamd_scan_mail: "no"
    # Add new options into the Clamd config file
    clamav_clamd_config__custom:
      Debug: "yes"
      ScanXMLDOCS: "yes"
    # Disable syslog for the FreshClam
    clamav_freshclam_log_syslog: "no"
    # Add new options into the FreshClam config file
    clamav_freshclam_config__custom:
      LogVerbose: "yes"
      LogRotate: "yes"
  # In order to run correctly on systems with SELinux enabled, the
  # 'libsemanage-python' package must also be installed before this role is
  # executed...
  pre_tasks:
    - package:
        name: libsemanage-python # for SELinux-enabled systems...
  roles:
    - clamav

Role variables

# Whether to install EPEL YUM repo
clamav_epel_install: "{{ yumrepo_epel_install | default(true) }}"

# EPEL YUM repo URL
clamav_epel_yumrepo_url: "{{ yumrepo_epel_url | default('https://dl.fedoraproject.org/pub/epel/$releasever/$basearch/') }}"

# EPEL YUM repo GPG key
clamav_epel_yumrepo_gpgkey: "{{ yumrepo_epel_gpgkey | default('https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-$releasever') }}"

# Additional EPEL YUM repo params
clamav_epel_yumrepo_params: "{{ yumrepo_epel_params | default({}) }}"

# Package to be installed (explicit version can be specified here)
clamav_pkgs: "{{
  ['clamav', 'clamav-update', 'clamav-scanner-systemd']
    if ansible_os_family == 'RedHat' and ansible_distribution_major_version | int >= 7
    else
  ['clamd'] }}"

# Clamav service name
clamav_service: "{{
  'clamd@scan'
    if ansible_os_family == 'RedHat' and ansible_distribution_major_version | int >= 7
    else
  'clamd' }}"


# Max age of the ClamAV DB before update (in days)
clamav_db_age: 7

# Whether to run ClamAV DB update if it's too old
clamav_db_update_run: yes

# Force ClamAV to update the DB
clamav_db_update_force: no

# Default ClamAV DB update command options
clamav_db_update_command_options__default:
  - --quiet
  - --no-warnings

# Custom ClamAV DB update command options
clamav_db_update_command_options__custom: []

# Final ClamAV DB update command options
clamav_db_update_command_options: "{{
  clamav_db_update_command_options__default +
  clamav_db_update_command_options__custom }}"

# ClamAV DB update command
clamav_db_update_command: /usr/bin/freshclam {{ clamav_db_update_command_options | join(' ') }}


# Path to the ClamScan file
clamav_scan_log_file: "{{ clamav_log_dir }}/clamscan_{{ clamav_scan_cron_time }}.log"

# Root path where to start to scan
clamav_scan_root: /

# Default ClamAV scan command options
clamav_scan_command_options__default:
  - --config-file={{ clamav_clamd_file }}
  - --log={{ clamav_scan_log_file }}
  - --fdpass
  - --infected

# Default ClamAV scan command options
clamav_scan_command_options__custom: []

# Default ClamAV scan command options
clamav_scan_command_options: "{{
  clamav_scan_command_options__default +
  clamav_scan_command_options__custom }}"

# ClamAV scan command
clamav_scan_command: /usr/bin/clamdscan {{ clamav_scan_command_options | join(' ') }} {{ clamav_scan_root }}

# Whether to setup Clamd Scan cron job
clamav_scan_cron: yes

# How often to run the Clamd Scan [hourly|daily|weekly]
clamav_scan_cron_time: daily

# Random delay before the Clamd Scan runs from the cron job
clamav_scan_cron_job_delay: 45

# Command to run as a cron job for the Clamd Scan
clamav_scan_cron_job: sleep $[RANDOM\%{{ clamav_scan_cron_job_delay }}]m ; {{ clamav_scan_command }}


# Whether to setup FreshClam cron job
clamav_freshclam_cron: "{{ clamav_scan_cron }}"

# How often to run the Clamd Scan [hourly|daily|weekly]
clamav_freshclam_cron_time: "{{ clamav_scan_cron_time }}"

# Random delay before the Clamd Scan runs from the cron job
clamav_freshclam_cron_job_delay: "{{ clamav_scan_cron_job_delay }}"

# Command to run as a cron job for the Clamd Scan
clamav_freshclam_cron_job: sleep $[RANDOM\%{{ clamav_freshclam_cron_job_delay }}]m ; {{ clamav_db_update_command }}


# ClamAV user and group
clamav_user: "{{
  'clamscan'
    if ansible_os_family == 'RedHat' and ansible_distribution_major_version | int >= 7
    else
  'clam' }}"
clamav_group: "{{ clamav_user }}"


# Log dir permissions (if not /var/log)
clamav_log_dir_mode: 0770

# Log file permissions
clamav_log_file_mode: 0660

# DB dir permissions
clamav_db_dir_mode: 0770


# ClamAV directories
clamav_log_dir: /var/log/clamav
clamav_run_dir: "{{
  '/var/run/clamd.scan'
    if ansible_os_family == 'RedHat' and ansible_distribution_major_version | int >= 7
    else
  '/var/run/clamav' }}"


# Clamd's Deamon nice level
clamav_clamd_daemon_nicelevel: 0

# Location of the Clamd daemon service config
clamav_clamd_daemon_file: "{{
  '/etc/systemd/system/[email protected]/override.conf'
    if ansible_service_mgr == 'systemd'
    else
  '/etc/sysconfig/clamd'
    if ansible_os_family == 'RedHat'
    else
  '/etc/default/clamd' }}"

# Default Clamd Daemon sysv config
clamav_clamd_daemon_sysv_config__default:
  NICELEVEL: "{{ clamav_clamd_daemon_nicelevel | int }}"

# Custom Clamd Daemon sysv init config
clamav_clamd_daemon_sysv_config__custom: {}

# Final Clamd Daemon sysv init config
clamav_clamd_daemon_sysv_config: "{{
  clamav_clamd_daemon_sysv_config__default.update(clamav_clamd_daemon_sysv_config__custom) }}{{
  clamav_clamd_daemon_sysv_config__default }}"

# Default Clamd Daemon systemd config
clamav_clamd_daemon_systemd_config__default:
  Service:
    Nice: "{{ clamav_clamd_daemon_nicelevel | int }}"

# Custom Clamd Daemon systemd config
clamav_clamd_daemon_systemd_config__custom: {}

# Final Clamd Daemon systemd config
clamav_clamd_daemon_systemd_config: "{{
  clamav_clamd_daemon_systemd_config__default.update(clamav_clamd_daemon_systemd_config__custom) }}{{
  clamav_clamd_daemon_systemd_config__default }}"

# Select the generated configuration from above to deploy
clamav_clamd_daemon_config: "{{
  clamav_clamd_daemon_systemd_config
    if ansible_service_mgr == 'systemd'
    else
  clamav_clamd_daemon_sysv_config }}"


# Location of the Clamd config
clamav_clamd_file: "{{
  '/etc/clamd.d/scan.conf'
    if ansible_os_family == 'RedHat' and ansible_distribution_major_version | int >= 7
    else
  '/etc/clamd.conf' }}"

# Values of the default options in the Clamd config
clamav_clamd_log_file: "{{ clamav_log_dir ~ '/clamd.log' }}"
clamav_clamd_log_file_max_size: 0
clamav_clamd_log_time: "yes"
clamav_clamd_log_syslog: "yes"
clamav_clamd_pid_file: "{{ clamav_run_dir ~ '/clamd.pid' }}"
clamav_clamd_temporary_directory: /var/tmp
clamav_clamd_database_directory: /var/lib/clamav
clamav_clamd_local_socket: "{{ clamav_run_dir ~ '/clamd.sock' }}"
clamav_clamd_fix_stale_socket: "yes"
clamav_clamd_tcp_socket: 3310
clamav_clamd_tcp_addr: 127.0.0.1
clamav_clamd_max_connection_queue_length: 30
clamav_clamd_max_threads: 50
clamav_clamd_read_timeout: 300
clamav_clamd_user: "{{ clamav_user }}"
clamav_clamd_allow_supplementary_groups: "yes"
clamav_clamd_scan_pe: "yes"
clamav_clamd_scan_elf: "yes"
clamav_clamd_detect_broken_executables: "yes"
clamav_clamd_scan_ole2: "yes"
clamav_clamd_scan_mail: "yes"
clamav_clamd_scan_archive: "yes"
clamav_clamd_archive_block_encrypted: "no"
clamav_clamd_exclude_path__default:
  - ^/(proc|sys|dev)/
clamav_clamd_exclude_path__custom: []
clamav_clamd_exclude_path: "{{
  clamav_clamd_exclude_path__default +
  clamav_clamd_exclude_path__custom }}"

# Default Clamd config
clamav_clamd_config__default:
  LogFile: "{{ clamav_clamd_log_file }}"
  LogFileMaxSize: "{{ clamav_clamd_log_file_max_size }}"
  LogTime: "{{ clamav_clamd_log_time }}"
  LogSyslog: "{{ clamav_clamd_log_syslog }}"
  PidFile: "{{ clamav_clamd_pid_file }}"
  TemporaryDirectory: "{{ clamav_clamd_temporary_directory }}"
  DatabaseDirectory: "{{ clamav_clamd_database_directory }}"
  LocalSocket: "{{ clamav_clamd_local_socket }}"
  FixStaleSocket: "{{ clamav_clamd_fix_stale_socket }}"
  TCPSocket: "{{ clamav_clamd_tcp_socket }}"
  TCPAddr: "{{ clamav_clamd_tcp_addr }}"
  MaxConnectionQueueLength: "{{ clamav_clamd_max_connection_queue_length }}"
  MaxThreads: "{{ clamav_clamd_max_threads }}"
  ReadTimeout: "{{ clamav_clamd_read_timeout }}"
  User: "{{ clamav_clamd_user }}"
  AllowSupplementaryGroups: "{{ clamav_clamd_allow_supplementary_groups }}"
  ScanPE: "{{ clamav_clamd_scan_pe }}"
  ScanELF: "{{ clamav_clamd_scan_elf }}"
  DetectBrokenExecutables: "{{ clamav_clamd_detect_broken_executables }}"
  ScanOLE2: "{{ clamav_clamd_scan_ole2 }}"
  ScanMail: "{{ clamav_clamd_scan_mail }}"
  ScanArchive: "{{ clamav_clamd_scan_archive }}"
  ArchiveBlockEncrypted: "{{ clamav_clamd_archive_block_encrypted }}"
  ExcludePath: "{{ clamav_clamd_exclude_path }}"

# Custom Clamd config
clamav_clamd_config__custom: {}

# Final Clamd config
clamav_clamd_config: "{{
  clamav_clamd_config__default.update(clamav_clamd_config__custom) }}{{
  clamav_clamd_config__default }}"


# Location of the FreshClam config
clamav_freshclam_file: /etc/freshclam.conf

# Values of options in the FreshClam config
clamav_freshclam_update_log_file: "{{ clamav_log_dir ~ '/freshclam.log' }}"
clamav_freshclam_log_syslog: "{{ clamav_clamd_log_syslog }}"
clamav_freshclam_database_directory: "{{ clamav_clamd_database_directory }}"
clamav_freshclam_database_owner: "{{ clamav_user }}"
clamav_freshclam_database_mirror:
  - database.clamav.net
  - database.clamav.net

# Default FreshClam config
clamav_freshclam_config__default:
  UpdateLogFile: "{{ clamav_freshclam_update_log_file }}"
  LogSyslog: "{{ clamav_freshclam_log_syslog }}"
  DatabaseDirectory: "{{ clamav_freshclam_database_directory }}"
  DatabaseOwner: "{{ clamav_freshclam_database_owner }}"
  DatabaseMirror: "{{ clamav_freshclam_database_mirror }}"

# Custom FreshClam config
clamav_freshclam_config__custom: {}

# Final FreshClam config
clamav_freshclam_config: "{{
  clamav_freshclam_config__default.update(clamav_freshclam_config__custom) }}{{
  clamav_freshclam_config__default }}"

Dependencies

License

MIT

Author

Jiri Tyr

ansible-clamav's People

Contributors

jtyr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

ansible-clamav's Issues

OnAccessIncludePath only permits one value

The ClamAV documentation suggests using multiple OnAccessIncludePath declarations in order to include multiple paths. For example:

OnAccessIncludePath /home
OnAccessIncludePath /mnt

Both of those lines would be required in order to watch both directories, however if lines are written for both of them in the custom config section, only the last one is entered into the config. Is there a better way to do this?

How to exclude a setting?

In order to use a remote clamd tcp server, LocalSocket has to be excluded. While you have support to override values with clamav_clamd_config__custom, I see no way within your role to remove such a config setting. Suggestions?

ClamAV does an update at each run

There is a mistake in the tasks/main.yaml file:

- name: Check the age of the ClamAV DB
  shell: >
    if (( $(date "+%s") - $(date -d "$(sigtool -i {{ clamav_clamd_database_directory }}/daily.cvd 2>/dev/null | grep -Po '(?<=^Build time: ).*' || echo '2016-01-01')" "+%s") > {{ clamav_db_age }} * 86400 )); then
      exit 1;
    else
      exit 0;
    fi
  register: clamav_db_age_check_result
  failed_when: false
  changed_when: false
  tags:
    - clamav_db

The above part will always return false on CentOS 7.3.1611 as the file is not called daily.cvd but daily.lvd on my systems with clamav version: 0.99.2-1

# ll /var/lib/clamav/
total 210008
-rw-r--r-- 1 clamscan clamscan    103987 Feb  8 11:01 bytecode.cvd
-rw-r--r-- 1 clamscan clamscan 105791488 Feb  8 10:31 daily.cld
-rw-r--r-- 1 clamscan clamscan 109143933 Feb  8 11:01 main.cvd
-rw------- 1 clamscan clamscan       208 Feb  7 18:30 mirrors.dat

The fix for this would be:
if (( $(date "+%s") - $(date -d "$(sigtool -i {{ clamav_clamd_database_directory }}/daily.cld 2>/dev/null | grep -Po '(?<=^Build time: ).*' || echo '2016-01-01')" "+%s") > {{ clamav_db_age }} * 86400 )); then

Next to this issue there is a simmular issue with this part of the playbook code:

- name: Update ClamAV DB
  # First delete all DBs if the daily DB is older than 90 days because the
  # mirror server keeps only last 90 daily files.
  shell: >
    if (( $(date "+%s") - $(date -d "$(sigtool -i {{ clamav_clamd_database_directory }}/daily.cvd 2>/dev/null | grep -Po '(?<=^Build time: ).*' || echo '2016-01-01')" "+%s") > 90 )); then
      rm -f {{ clamav_clamd_database_directory }}/*.cvd;
    fi;
    {{ clamav_db_update_command }}
  when: >
    clamav_db_update_run and
    clamav_db_age_check_result.rc or
    clamav_db_update_force
  tags:
    - clamav_db

On my systems the above code will always delete the files if an update is required (speaking in terms when the first part of the code has been patched). The reason is because of:

  1. daily.cvd is called daily.cld thus it will parse 2016-01-01.
  2. the calculated number is always greater then 90 as the date output is in seconds and the comparison number is in days.

I fixed this on my systems with:
if (( $(date "+%s") - $(date -d "$(sigtool -i {{ clamav_clamd_database_directory }}/daily.cld 2>/dev/null | grep -Po '(?<=^Build time: ).*' || echo '2016-01-01')" "+%s") > 90 * 86400 )); then

Could you be so kind to check this on your development environment and if this is also the case please update the git repo? The issue could be more complex then I've stated I've not checked any further. I've already patched mine so there is no pressure at all :-)

Thank you for the great playbook!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.