Many believe Linux servers are immune to malware, but that's not entirely accurate.

While infecting Linux servers itself is tough, sharing files with Windows users or hosting CMSs like WordPress can open doors to malware.

In this comprehensive guide, I'll walk you through the steps to protect your Linux server from Malware using ClamAV (Clam AntiVirus) and Maldet (Linux Malware Detect).

Preparation

To make the most of this guide, ensure you have a properly set up Ubuntu server.

👉
Check out my guide on preparing Ubuntu servers to ensure your server is properly set up.

If you don’t have one, consider getting a free VPS server to follow along.

Maldet & ClamAV Combo

I always prefer to provide context before delving into technical details, so I'll start by explaining what these two software are and how they combine to form a powerful combo.

ClamAV is a free, powerful and efficient open-source software as it excels in detecting, quarantining, and removing various types of malware.

It includes the freshclam utility, which ensures regular updates to the ClamAV database. This database is continuously refreshed with the latest threats as they are discovered.

Maldet is similar to ClamAV but is specifically tailored for hosting environments.

It includes a live monitoring feature that works with the Linux kernel's inotify capability, detecting changes in files and scanning them promptly.

One of its great features is automatic creation of malware detection signatures when it detects malware on intrusion detection systems at the network's edge.

Maldet updates both its malware signatures and the program itself on a daily basis.

Now, the most interesting part is why using both of them together.

The ClamAV scan engine performs better than Maldet. When Maldet sees that ClamAV is installed, it uses ClamAV's scan engine automatically, making things run smoother.

Together, Maldet monitors specified paths for malware using ClamAV's scan engine and uses both malware signature databases.

This combined approach enhances their effectiveness compared to using either alone.

Key Considerations

Before we start, it’s crucial to be aware that ClamAV and Maldet can be resource-intensive.

Make sure your server has enough CPU and memory to handle them smoothly. Not having sufficient resources could slow down your server and affect its performance.

For a smoother experience, aim for a server with at least 2 dedicated CPU cores and 8 GB of memory.

It's a good idea to test ClamAV and Maldet on a separate server first to see how much resources they need and plan accordingly.

I've had no performance issues with them on a dedicated vCPU server from Hetzner. Their CPUs are powerful, and their memory is high-speed.

👉
New to Hetzner? Use my link to get free credits!

Lastly, it's crucial to understand that these two software aren't malware cleaners.

They detect malware, can quarantine infected files, and warn you, but they don't clean the files themselves.

Maldet will attempt to clean the files, but it's not something you can always count on. You'll need to handle file cleaning yourself.

We'll discuss this in more detail later on.

Installing ClamAV

We won't interact much with ClamAV directly when using both together.

Maldet automatically uses the ClamAV scan engine, so all we need to do is install ClamAV without any additional configuration.

However, I still want to demonstrate how to use ClamAV because there might be situations where you'll need to use it alone.

So, it's useful to know more than just how to install it.

Use the following command for installation:

sudo apt install clamav

The ClamAV database is updated automatically during the installation.

This installation adds one new service: the clamav-freshclam service, which is enabled and running by default.

As I mentioned before, this service regularly checks for database updates.

🙆‍♂️
If you're not interested in learning more about ClamAV, feel free to skip ahead to the Maldet section. Since you've already installed ClamAV, you're all set.

Running a Scan

To run a scan, use the clamscan command on the directory you want to scan.

I will scan my WordPress files for any malware or viruses:

sudo clamscan -r /var/www/webapps/wordpress/public_html

Output:

----------- SCAN SUMMARY -----------
Known viruses: 8680618
Engine version: 0.103.9
Scanned directories: 1151
Scanned files: 6323
Infected files: 0
Data scanned: 361.83 MB
Data read: 145.92 MB (ratio 2.48:1)
Time: 69.349 sec (1 m 9 s)
Start Date: 2024:02:28 13:33:46
End Date:   2024:02:28 13:34:55

ClamAV scanned my WordPress files and found no malware.

The -r option stands for recursive scan. When you include this option in your command, ClamAV will not only scan the specified directory but also all of its subdirectories.

This is particularly useful when you want to thoroughly check an entire directory tree for malware, ensuring that no part of the directory structure is overlooked.

Resource Insights

You'll notice that when you scan with ClamAV, it uses about a one GB of memory just to get started. This happens because it loads the database into memory.

Now, rerun the scan but keep an eye on your resource usage.

After running the clamscan command, you’ll notice a short wait before the scan begins, and the memory usage on your server will increase by around one GB or more.

ClamAV needs this one GB of free memory for the database, plus additional resources for the scanning process itself.

That's why, as I mentioned earlier, I recommend having a server with sufficient resources, or only scanning when you have enough resources available.

Some people suggest stopping the clamav-freshclam service and preventing it from starting on reboot to save resources. They recommend manually updating the database only when needed for a scan.

However, I don’t completely agree with this approach.

In my experience, the clamav-freshclam service, which checks for database updates every hour, doesn’t use a lot of resources and helps keep the database updated.

While manually updating is an option and just involves running a command before scanning, it’s not necessary.

If you still choose to stop and disable the service, you can use these two commands to do so:

sudo systemctl stop clamav-freshclam.service
sudo systemctl disable clamav-freshclam.service

Now, you’ll need to manually update the database each time before you scan.

Use this command for manual updates:

sudo freshclam
When using ClamAV and Maldet together, you shouldn't stop and disable the clamav-freshclam service, as it's needed for the monitoring feature. We want to make sure the database is always updated.

Scanning the Root Filesystem

You may consider scanning the entire root filesystem / for malware, but there are critical aspects to consider.

If you’re using ClamAV on a production server, run a scan only if absolutely necessary.

Certain directories like /proc/sys/run/dev, and /snap are special and scanning them may lead to errors. Therefore, it’s essential to exclude these directories from the scan.

Creating a custom directory for moving infected files is advisable, and this directory should also be excluded from the scan.

To begin, create a directory for quarantining infected files:

sudo mkdir /root/quarantine

I created this directory within the root home directory.

To scan the entire root filesystem while excluding special directories, use the following command:

sudo clamscan -r --log=/var/log/clamav/clamscan.log --move=/root/quarantine --exclude='^/(proc|sys|run|dev|snap)/' /

This command performs a recursive scan of the root filesystem, excluding the specified special directories.

It logs the scan results in the clamscan.log file located in the /var/log/clamav/ directory and moves any detected malware to the quarantine directory.

The final recommendation is to avoid setting up automated scans with ClamAV. It’s better to run scans manually.

This approach is due to the unpredictable nature of scan results. There’s a risk that ClamAV might mistakenly identify a normal file as malware and move it, which could break your server.

Therefore, it’s crucial to always run scans manually and carefully examine the results to maintain the integrity of your server.

I've never had to scan the entire root filesystem because the likelihood of infection is extremely low.

However, as mentioned earlier, sharing files with Windows users or hosting CMSs like WordPress can expose your server to malware.

Therefore, it's essential to monitor these areas closely, and that's where Maldet comes into play.

Installing Maldet

After installing ClamAV, we can proceed to install Maldet and begin configuring it.

But, make sure to install it using the root user.

If you install it using sudo, the Maldet files will be owned by the user who performed the installation, rather than by the root user. Installing it as root avoids the need to locate and modify the ownership of those files later on.

Maldet isn't available in the repositories of any Linux distribution, but it's simple to install.

After accessing the server using root, use this command to download the Maldet files:

wget http://www.rfxn.com/downloads/maldetect-current.tar.gz

Extract the archive:

tar xzvf maldetect-current.tar.gz

Now, navigate into the resulting directory and execute the installer like this:

./install.sh

Once Maldet is installed, copy the README file to your home directory so you can examine it if needed. It contains the documentation for Maldet.

The installer automatically creates the symbolic link for the maldet service, and it also automatically downloads and installs the latest malware signatures.

Now, you can access the server again using your sudo user.

There's one more thing we need to install, which is the inotify-tools package. This package is necessary for the monitoring feature and is required for the maldet service to work.

Use this command to install it:

sudo apt install inotify-tools

If we check the status of the maldet service, we'll notice that it's not active by default.

We'll start it after we finish configuring Maldet.

Configuring Maldet

Open the /usr/local/maldetect/conf.maldet file with your favorite editor.

You need to configure Maldet to alert you by email whenever it detects any malware, which is highly recommended.

Find the email_alert and email_addr variables and change them accordingly:

email_alert="1"
email_addr="hello@ivansalloum.com"

There's an option to ignore email alerts for malware that has been cleaned, but I recommend disabling it.

It's enabled by default, so ensure to disable it like this:

email_ignore_clean="0"

It is always better to get notified about everything happening.

💡
Your server needs to be configured to send emails, and this can be done by setting up Postfix for external SMTP relay to ensure you receive alerts.

If you scroll down further, you'll notice the autoupdate_signatures and autoupdate_version variables, which are enabled by default and prompt Maldet to check for updates every day.

Now, we want Maldet to quarantine any infected files and attempt to clean them from any malware.

To do this, locate the quarantine_hits and quarantine_clean variables, and enable them:

quarantine_hits="1"
quarantine_clean="1"

There's an important consideration to keep in mind: quarantining infected files can potentially cause issues.

For instance, if you're hosting WordPress and Maldet moves an infected file to the /usr/local/maldetect/quarantine directory, your site may stop working.

Therefore, you must decide between letting Maldet quarantine and attempt to clean the infected files, and then moving them back to the WordPress directory once you're certain they're safe, or not allowing Maldet to quarantine and clean infected files, and instead immediately cleaning them yourself after receiving an alert.

It's up to you.

Finally, we need to configure Maldet to monitor files in paths we specify.

By default, Maldet scans only files within the /dev/shm//var/tmp/, and /tmp/ directories.

To change this, locate the following two lines:

default_monitor_mode="users"
# default_monitor_mode="/usr/local/maldetect/monitor_paths"

Comment out the first line and uncomment the second line, like this:

# default_monitor_mode="users"
default_monitor_mode="/usr/local/maldetect/monitor_paths"

And that's it for the main configuration file. Save and close it.

Now, the final step before starting the maldet service is to specify the paths we want to monitor.

Open the /usr/local/maldetect/monitor_paths file with your favorite editor and add the directories you want to monitor, like this:

/home
/root
/var/tmp
/tmp

After this, it is time to start the maldet service:

sudo systemctl start maldet

If you check the Maldet logs using the sudo maldet --log command, you will see this:

maldet(33584): {mon} set inotify max_user_watches to 16384
maldet(33584): {mon} added /var/tmp to inotify monitoring array
maldet(33584): {mon} added /tmp to inotify monitoring array
maldet(33584): {mon} added /home to inotify monitoring array
maldet(33584): {mon} added /root to inotify monitoring array
maldet(33584): {mon} added /var/www to inotify monitoring array
maldet(33584): {mon} starting inotify process on 5 paths, this might take awhile...
maldet(33584): {mon} inotify startup successful (pid: 33716)
maldet(33584): {mon} inotify monitoring log: /usr/local/maldetect/logs/inotify_log

This output is sourced from the /usr/local/maldetect/logs/event_log file.

As you can see, Maldet has added the specified paths to the monitoring array, and the monitoring feature is now enabled.

You can also check the /usr/local/maldetect/logs/inotify_log file, as it contains useful information about the changes occurring to the files.

The ClamAV Daemon Warning

If you examine the Maldet logs again, you'll notice this warning:

maldet(33584): {mon} warning clamd service not running; force-set monitor mode file scanning to every 120s

This happens because we only installed the clamav package.

If we don't install the clamav-daemon package, you will always see this warning.

Let me explain why.

When you only install the clamav package, you'll have access to the clamav-freshclam service for updates and the clamscan utility for scans.

As explained in the Resource Insights section on ClamAV, you know that ClamAV requires a certain amount of RAM to load the database before starting a scan, and it does this each time you run a scan.

However, if you install the clamav-daemon package, you'll also have access to the clamav-daemon service. When active, this service keeps the database constantly loaded in memory.

As a result, you'll notice approximately one GB of RAM consistently in use because the database remains in memory.

This setup ensures that ClamAV is always ready to run scans, as the clamav-freshclam service continuously updates the database and the clamav-daemon service keeps it loaded.

Without the clamav-daemon service detected, Maldet won't monitor specified paths in real-time. Instead, it checks them every 120 seconds.

This is because Maldet needs ClamAV to load the database into memory before it can monitor files.

Installing the clamav-daemon package resolves this issue, and Maldet will monitor files every second.

🙆‍♂️
I wanted to address this now because I encountered this problem myself, and after some investigation, I found the solution. I wanted you to see the warning beforehand so you could understand the situation.

Now, the only remaining step is to install the clamav-daemon package and ensure the service remains active.

Use this command for installation:

sudo apt install clamav-daemon

If you check the status of the clamav-daemon service, you'll notice that it's active by default.

If you run the htop command, you'll see that approximately one GB of RAM is being used because the database is loaded into memory.

Now, restart the maldet service:

sudo systemctl restart maldet

Check the logs again, and you won't see the warning anymore.

Now, Maldet is able to monitor in real-time.

Final Testing

Maldet is active and monitoring files, eliminating the need for manual scans.

Since Maldet uses the ClamAV scan engine, there's no need to directly use ClamAV.

Additionally, Maldet creates a file within the /etc/cron.daily/ directory, which conducts a daily scan of standard web directories.

This daily scan is controlled by the cron_daily_scan variable in its main configuration file, which you can disable if desired.

To view what Maldet will scan daily, open the /etc/cron.daily/maldet file and review its contents.

Now, let us test our setup by downloading a simulated virus file from the European Institute for Computer Antivirus Research (EICAR) site.

Download one or all of the EICAR test files inside a directory Maldet is monitoring:

wget https://secure.eicar.org/eicar.com
wget https://secure.eicar.org/eicar.com.txt
wget https://secure.eicar.org/eicar_com.zip
wget https://secure.eicar.org/eicarcom2.zip

After a few seconds, you'll notice that the file is gone and has been moved to the /usr/local/maldetect/quarantine directory if you enabled Maldet to quarantine infected files.

Additionally, you should receive an alert by email.

Conclusion and Final Thoughts

Great job reaching the end!

I hope this guide has been incredibly helpful in showing you how to protect your Linux server from malware.

👉
You can find the full collection of detailed Linux server security guides here.

If you found value in this guide or have any questions or feedback, please don't hesitate to share your thoughts in the discussion section.

Your input is greatly appreciated, and you can also contact me directly if you prefer.