diff --git a/docs/.vuepress/public/images/notifications-event-fields.png b/docs/.vuepress/public/images/notifications-event-fields.png
new file mode 100644
index 00000000..94fe29f2
Binary files /dev/null and b/docs/.vuepress/public/images/notifications-event-fields.png differ
diff --git a/docs/.vuepress/public/images/notifications-settings-av-plesk.png b/docs/.vuepress/public/images/notifications-settings-av-plesk.png
new file mode 100644
index 00000000..e2a39f45
Binary files /dev/null and b/docs/.vuepress/public/images/notifications-settings-av-plesk.png differ
diff --git a/docs/.vuepress/public/images/notifications-settings-i360.png b/docs/.vuepress/public/images/notifications-settings-i360.png
new file mode 100644
index 00000000..04b9853d
Binary files /dev/null and b/docs/.vuepress/public/images/notifications-settings-i360.png differ
diff --git a/docs/.vuepress/public/images/panel-email-notifications-dialog-off.png b/docs/.vuepress/public/images/panel-email-notifications-dialog-off.png
new file mode 100644
index 00000000..5ed30ca9
Binary files /dev/null and b/docs/.vuepress/public/images/panel-email-notifications-dialog-off.png differ
diff --git a/docs/.vuepress/public/images/panel-email-notifications-dialog.png b/docs/.vuepress/public/images/panel-email-notifications-dialog.png
new file mode 100644
index 00000000..8ca34176
Binary files /dev/null and b/docs/.vuepress/public/images/panel-email-notifications-dialog.png differ
diff --git a/docs/command_line_interface/README.md b/docs/command_line_interface/README.md
index f46ddb02..ccc1c883 100644
--- a/docs/command_line_interface/README.md
+++ b/docs/command_line_interface/README.md
@@ -1610,6 +1610,25 @@ Allows administrators to do the following:
* configure email addresses to submit reports on events execution
* execute custom scripts on events execution
+The settings are stored in _/etc/sysconfig/imunify360/hooks.yaml_.
+**Every event is disabled by default**, and on every panel except Plesk the file does not exist
+until something is configured, so an absent file is the normal state of a fresh installation. On
+Plesk the agent creates the file and enables a SCRIPT target on
+CUSTOM_SCAN_MALWARE_FOUND,
+USER_SCAN_MALWARE_FOUND and
+REALTIME_MALWARE_FOUND for the Imunify extension's
+_send-notifications_ script — see
+[Plesk: managing delivery with Plesk Notifications](/features/panel_notifications/#plesk-managing-delivery-with-plesk-notifications).
+The same settings are available in
+the UI — see [Notifications](/features/#notifications) for what each event means, when it fires
+and how the messages are delivered.
+
+::::tip Note
+These are *event* notifications, sent by the server itself. They are not the same thing as the
+security digests that the hosting panel delivers — those are configured separately, see
+[Panel notifications (iContact)](/features/panel_notifications/).
+::::
+
**Usage:**
@@ -1728,10 +1747,20 @@ Rules:
*
CUSTOM_SCAN_MALWARE_FOUND – occurs when the on-demand scanning process has finished and malware found.
+::::tip Note
+The event name says which *scan type* produced the event, not who started the scan. A scheduled
+background scan (
`MALWARE_SCAN_SCHEDULE`) reports itself as a
+**user scan**, so it triggers
`USER_SCAN_*`, while
+
`CUSTOM_SCAN_*` covers on-demand scans started from the admin UI or
+with
`malware scan`. See
+[Which scan produces which event](/features/#which-scan-produces-which-event).
+::::
+
Admin:
-*
default_emails – specify the default list of emails used for all enabled admin email notifications.
+*
default_emails – specify the default list of emails used for all enabled admin email notifications. Only plain addresses are accepted here; the keyword
`default` is not.
*
notify_from_email – specify a sender of all emails sent by the Hooks.
+*
locale – the language of the admin emails, for example
`en` or
`ru`. When it is not set, the template default is used. A locale is available only if the corresponding file exists in the template directory of the event (see [Adding custom email template](/command_line_interface/#adding-custom-email-template)).
Let's review all options for a specific event on the
REALTIME_MALWARE_FOUND example:
@@ -1761,10 +1790,18 @@ Let's review all options for a specific event on the
R
**ADMIN**:
-* period – set a notification interval in minutes. The data for all events that happened within the interval will be accumulated and sent altogether.
+* period – set a notification interval in seconds. The data for all events that happened within the interval will be accumulated and sent altogether.
* admin_emails – set `default` to use the default administrator emails and/or specify your emails for notifications.
* enabled – notify (`True`) the administrator and a custom user list via email upon event occurrence.
+:::warning Note
+* `period` is in **seconds** for both targets. The UI labels the admin interval _Notify every (mins)_ and converts the value for display, but the config and the CLI always use seconds. Aggregated events are dispatched by a cron job whose interval is the smallest configured period rounded to whole minutes, so a period below 60 seconds behaves like one minute.
+* Only REALTIME_MALWARE_FOUND and SCRIPT_BLOCKED accept `period`. The other events are sent as they occur and have no interval.
+* Email addresses are validated against `^.+@(.+\.)+.+`, so the domain part must contain a dot: `root@localhost` is rejected, `root@localhost.localdomain` is accepted.
+* Script paths must be absolute, and the script must be executable by the `_imunify` user — which also has to be able to traverse every directory on the way to it. A script under _/root_ will never run.
+* `update` merges the JSON you pass into the current configuration, so you only need to send the keys you want to change.
+:::
+
**Examples**:
1. Update admin default emails:
diff --git a/docs/config_file_description/README.md b/docs/config_file_description/README.md
index ac3045e4..12a4cebb 100644
--- a/docs/config_file_description/README.md
+++ b/docs/config_file_description/README.md
@@ -405,6 +405,23 @@ systemctl restart imunify360
# your email to receive reports about critical issues, security alerts or system misconfigurations detected on your servers. |
| enable_icontact_notifications: True |
# enable/disable delivery of generic (iContact) messages via hosting panel notifications (cPanel iContact / Plesk Notifications). Messages are provided by the Imunify backend (subject + HTML body) and throttled by a per-message period limit. Default value is True. See Panel notifications (iContact). |
+
| DASHBOARD: |
|---|
+
# notifications holds one switch per panel notification message type. Every switch defaults to True; setting one to False stops the Imunify cloud from generating that message type for this server. These switches are also available in the UI as Settings → Notifications → Panel notifications. |
+
| notifications: | |
+
| malware_found: True |
+# a user or background scan found malicious files. Generated for ImunifyAV/AV+ servers only. |
+
| malware_detected: True |
+# the Malware Database Scanner detected malware in a database. |
+
| malicious_redirect_detected: True |
+# a malicious redirect was detected on a website. |
+
| aibolit_vulnerable: True |
+# a vulnerable script was detected. |
+
| insecure_wp_core: True |
+# an installed WordPress core has known vulnerabilities. |
+
| outdated_wp_core: True |
+# an installed WordPress core version is outdated. |
+
| scan_not_scheduled: True |
+# no scheduled malware scan is configured (MALWARE_SCAN_SCHEDULE.interval is none) and no user or background scan has run in the last 30 days. |
| SMTP_BLOCKING: |
| enable: False |
# enable (True) or disable (False) (default value) SMTP Traffic Management. When enabled, the outgoing SMTP traffic would be blocked according to the settings. |
diff --git a/docs/dashboard/README.md b/docs/dashboard/README.md
index b57b45e2..a6071838 100644
--- a/docs/dashboard/README.md
+++ b/docs/dashboard/README.md
@@ -1217,9 +1217,10 @@ The following tabs are available:
*
[General](/dashboard/#general)
*
[Malware](/dashboard/#malware)
*
[Backups](/dashboard/#backups)
-*
[Disables Rules](/dashboard/#disabled-rules)
+*
[Disabled Rules](/dashboard/#disabled-rules)
+*
[Features Management](/dashboard/#features-management)
*
[Attributions](/dashboard/#attributions)
-*
[Notifications](/features/#notifications)
+*
[Notifications](/dashboard/#notifications)
### General
@@ -2234,3 +2235,16 @@ It is possible to enable the Service Status checker for Imunify360. Perform the
If succeeded, the status of the Imunify360 service will be displayed at the Service Status section of Server Status.

+
+### Notifications
+
+Click
_Settings_ and choose the
_Notifications_
+tab to configure who is told about scan and
Proactive Defense events on
+this server, and which security emails the hosting panel delivers.
+
+
+
+The tab controls two separate things:
+
+*
**Event notifications** — an email and/or a script hook per event, fired by the server itself. Every event is disabled by default, except the malware hook the agent enables on Plesk. See [Notifications](/features/#notifications) for the event reference, the delivery mechanics and troubleshooting, or [`notifications-config`](/command_line_interface/#notifications-config) to configure the same settings from the command line.
+*
**Panel notifications** — the security digests that the Imunify cloud generates and the hosting panel delivers. The
_Manage panel notifications_ button opens a dialog with a switch per message type; all of them are enabled by default. See [Panel notifications (iContact)](/features/panel_notifications/). The row is shown only on cPanel and Plesk.
diff --git a/docs/features/README.md b/docs/features/README.md
index 7728cf06..f8ebcdb5 100644
--- a/docs/features/README.md
+++ b/docs/features/README.md
@@ -304,80 +304,300 @@ Disable (default):
## Notifications
-::::tip Note
-This section describes Imunify event notifications (emails/scripts) configured in Imunify UI and via `notifications-config`. For panel notifications (iContact messages) delivered via cPanel iContact or Plesk Notifications, see [Panel notifications (iContact)](/features/panel_notifications/).
-::::
+Imunify sends three different kinds of messages, and each one is configured in a
+different place. When a notification you expected does not arrive, first check which of the
+three channels it belongs to:
-Starting from version 4.10, an administrator is able to configure email addresses to submit reports and execute custom scripts. Go to
_Settings_ and choose
_Notifications_ tab.
+
+
+| Channel | What it reports | Where you configure it | Enabled by default |
+
+
+
+Event notifications (emails and script hooks) |
+Scan and Proactive Defense events that happen on this server, sent by the server itself |
+Settings → Notifications, or notifications-config |
+No — off until you turn a target on; the one exception is the malware hook the agent installs on Plesk (see below) |
+
+
+Panel notifications (iContact messages) |
+Security recommendations and digests generated in the Imunify cloud and delivered through the hosting panel |
+Settings → Notifications → Panel notifications, ADMIN_CONTACTS.enable_icontact_notifications, DASHBOARD.notifications |
+Yes — all message types are on |
+
+
+| Admin contacts |
+Critical issues, license and configuration problems, sent by the Imunify cloud |
+Settings → General, ADMIN_CONTACTS.emails |
+Yes, once an address is set |
+
+
+
-
+This section describes **event notifications**. Panel notifications have their own page:
+[Panel notifications (iContact)](/features/panel_notifications/).
-*
**Default admin emails**: specify the default list of emails used for all enabled admin email notifications.
-*
**From**: specify a sender of all emails sent by the Hooks.
+### Configuring event notifications
-The following events are available.
+Go to
_Settings_ and choose the
_Notifications_ tab.
-#### Real-Time scan: malware detected
+
-Occurs when malware is detected during the real-time scanning.
+*
**Default admin emails**: the default list of emails used for all enabled admin email notifications. Plain addresses only — the keyword `default` is not accepted here.
+*
**From**: the sender address of all emails sent by the notification subsystem.
+*
**Panel notifications**: opens the [Panel email notifications](/features/panel_notifications/#choosing-which-message-types-to-receive) dialog. This row belongs to the second channel from the table above and is shown only on cPanel and Plesk.
-
+Every event is collapsed into its own row. Expand a row to configure its targets, then
+click
_Save changes_ at the bottom of the page — nothing is
+applied until you do.
-*
**Enable email notifications for admin**: move the slider to
ON to notify the administrator and a custom user list via email upon event occurrence. To notify the administrator on the default admin email, tick the
_Default admin emails_ checkbox.
-*
**Notify every (mins)**: set a notification interval in minutes. The data for all events that happened within the interval will be accumulated and sent altogether.
-*
**Admin emails**: tick the
_Default admin emails_ and/or specify your emails for notifications.
-*
**Enable script execution**: move the slide to
ON to run a script (event handler) upon event occurrence.
-*
**Notify every (sec)**: set a notification interval in seconds. The data for all events that happened within the interval will be accumulated and sent altogether.
-*
**Run a script**: specify the full path to the script(s) or any other Linux executable to be launched on event occurrence. Make sure that the script has an executable bit (+x) on. A line-separated list of scripts is supported.
+The settings are stored in
_/etc/sysconfig/imunify360/hooks.yaml_.
+On every panel except Plesk the file does not exist until you save the form (or run
+
`notifications-config update`) for the first time; an absent file
+means "no event notifications configured", which is the default state. **On Plesk the agent creates
+the file itself** and enables a
SCRIPT target on
+
CUSTOM_SCAN_MALWARE_FOUND,
+
USER_SCAN_MALWARE_FOUND and
+
REALTIME_MALWARE_FOUND, pointing at the Imunify extension's
+
_send-notifications_ script, so that malware notifications reach
+Plesk administrators and customers through Plesk Notifications — see
+[Plesk: managing delivery with Plesk Notifications](/features/panel_notifications/#plesk-managing-delivery-with-plesk-notifications).
+Everything else stays off until you turn it on.
-#### User scan: started
+### Which events exist, and what can they do
-Occurs immediately after the user scanning has started.
+An event can have up to two targets:
**ADMIN** (an email) and
+
**SCRIPT** (your own executable). The two are independent — you can
+enable either, both, or neither.
-
+
+
+| Event | Occurs when | Imunify360 | ImunifyAV / AV+ |
+
+
+| REALTIME_MALWARE_FOUND | malware is detected during real-time scanning (file upload, ModSecurity, FTP) | email, script aggregated | — |
+| USER_SCAN_MALWARE_FOUND | a user or scheduled background scan has finished and malware was found | email, script | script |
+| CUSTOM_SCAN_MALWARE_FOUND | an on-demand (manual) scan has finished and malware was found | email, script | script |
+| SCRIPT_BLOCKED | Proactive Defense has blocked a malicious script | email, script aggregated | — |
+| USER_SCAN_STARTED | a user or scheduled background scan has started | script | script |
+| USER_SCAN_FINISHED | a user or scheduled background scan has finished, whether or not malware was found | script | script |
+| CUSTOM_SCAN_STARTED | an on-demand (manual) scan has started | script | script |
+| CUSTOM_SCAN_FINISHED | an on-demand (manual) scan has finished, whether or not malware was found | script | script |
+
+
+::::tip Note
+In
ImunifyAV and
ImunifyAV+ the
+
**ADMIN** email target does not exist at all: the six events
+above are script-only, and there are no
_Default admin emails_ or
+
_From_ fields on the page. The real-time and
+
Proactive Defense events are Imunify360-only features and are not
+listed either.
+
+
+
+If you need an email on an
ImunifyAV/AV+ server, either send it
+from your own script hook, or use [panel notifications](/features/panel_notifications/), which do
+deliver email on both products.
+::::
-#### Custom scan: started
+#### Which scan produces which event
-
+The
`USER_SCAN_*` and
`CUSTOM_SCAN_*`
+names do not map to "started by a user" versus "started by the admin" — they map to the internal
+scan type:
-Occurs immediately after on-demand (manual) scanning has started.
+
+
+| How the scan was started | Scan type | Event family |
+
+
+Scheduled background scan (MALWARE_SCAN_SCHEDULE) | background | USER_SCAN_* |
+| An end user scanning their own account from the Imunify UI | user | USER_SCAN_* |
+Start scanning in the admin UI, or imunify360-agent malware scan | on-demand | CUSTOM_SCAN_* |
+| Rescan requested by the cloud, or a rescan of a file modified after the previous scan | rescan, rescan-outdated | CUSTOM_SCAN_MALWARE_FOUND only |
+| Real-time scanning of an uploaded file | realtime | REALTIME_MALWARE_FOUND |
+
+
+So a **scheduled nightly scan reports itself as a "user scan"**: to be notified about it, enable
+
USER_SCAN_MALWARE_FOUND, not
+
CUSTOM_SCAN_MALWARE_FOUND. Rescans emit only the malware-found
+event — they produce no "started" or "finished" event.
-#### User scan: finished
+### Event fields
-Occurs immediately after the user scanning has finished, regardless the malware has found or not.
+An expanded event shows the fields of both targets — the email one first, the script one below:
-
+
-#### Custom scan: finished
+*
**Enable email notifications for admin**: send an email when the event occurs. It goes to the addresses listed below and, when the
_Default admin emails_ checkbox is on, to the default list as well.
+*
**Notify every (mins)**: aggregation interval. All events that happen within the interval are accumulated and sent in one message. Only
REALTIME_MALWARE_FOUND and
SCRIPT_BLOCKED have this field; the other events are sent as they happen.
+*
**Admin emails**: the custom list of addresses for this event. Tick
_Default admin emails_ to add the default list as well.
+*
**Enable script execution**: run an executable when the event occurs.
+*
**Notify every (sec)**: the same aggregation interval for the script target.
+*
**Run a script**: full path to the script (or any Linux executable) to launch. One path per line; several scripts are allowed.
-
+:::warning Note
+The interval shown in the UI is minutes for the email target and seconds for the script target,
+but in
_hooks.yaml_ and in the
+
`notifications-config` CLI the
+
`period` value is **always in seconds** for both targets. The UI
+converts it for display.
+
+The two aggregated events are not sent the moment they happen. A cron job runs at the smallest
+configured period rounded to whole minutes (one minute at least) and deliberately collects only
+events **older than five minutes**, so that a burst of detections is reported once and in full.
+With a one-minute period the first message about a real-time detection therefore arrives five to
+six minutes after the event; with longer periods, correspondingly later. All other events are
+dispatched immediately.
+:::
-Occurs immediately after on-demand (manual) scanning has finished, regardless the malware has found or not.
+### Malware notifications and cleanup
+
+A malware-found notification is built from the infected files that the finished scan recorded, and
+that list has two exclusions worth knowing about, because both of them produce a scan that
+*reports* malware without an accompanying notification.
+
+**Files already being cleaned are excluded.** Files whose cleanup has already started or completed
+(
`cleanup_pending`,
+
`cleanup_started`,
`cleanup_done`,
+
`cleanup_removed`) are not counted when the event is assembled. With
+
`MALWARE_SCANNING.default_action: cleanup` the cleanup is queued
+*after* the scan has finished, so the event is assembled before any file changes state: the
+notification fires and lists the files, and the cleanup follows a few seconds later. The exclusion
+applies when a scan finishes while an earlier cleanup of the same files is still running — for
+example a rescan overlapping a cleanup — in which case those files are left out of the
+notification.
+
+**Files eliminated by the default action are never recorded at all.** When
+
`MALWARE_SCANNING.try_restore_from_backup_first` is enabled and a
+clean copy of the file is restored from a backup, the infected file is not stored as a malware hit.
+The scan summary still counts it in
`total_malicious`, but there is
+no hit behind that number, so **no malware-found event is generated and no email is sent**. The same
+applies to any file the default action removes outright.
+
+If you want to be notified about every detection regardless of what happens to the file afterwards,
+enable the script target for
USER_SCAN_FINISHED and
+
CUSTOM_SCAN_FINISHED as well: those events fire on every scan and
+carry the scan summary, including
+
`total_malicious`.
+
+### How messages are delivered
+
+**Email.** The
`imunify-notifier` service renders the message from
+a template and submits it to the local MTA — first over SMTP to
+
`localhost:25`, falling back to
+
`/usr/sbin/sendmail -t -oi` if that fails. Imunify's
+responsibility ends there; whether the message is then delivered, queued or bounced is up to your
+MTA, and its log is the place to look. Templates live in
+
_/usr/share/imunify-notifier/templates/<event>/_ and can be
+overridden per event — see
+[Adding custom email template](/command_line_interface/#adding-custom-email-template).
+
+**Scripts.** Script hooks run as the unprivileged
+
`_imunify` user and receive the event as a single JSON object on
+standard input. Every payload carries
`event_id`; the rest
+depends on the event, because the notifier enriches most events from the agent database before
+running the script:
+
+
+| Event | Payload fields besides event_id |
+
+
+| CUSTOM_SCAN_STARTED | scan_id, path, started — no enrichment |
+| USER_SCAN_STARTED | the above plus the scan record: type, resource_type, initiator, total_resources, total_malicious, completed, error (the totals are still 0 at this point) |
+| USER_SCAN_FINISHED, CUSTOM_SCAN_FINISHED, USER_SCAN_MALWARE_FOUND, CUSTOM_SCAN_MALWARE_FOUND | the scan record as above plus malicious_files, the list of infected paths |
+| REALTIME_MALWARE_FOUND | period_started, period_finished, malicious_total, malicious_files for the aggregated period |
+| SCRIPT_BLOCKED | period_started, period_finished, events_total, blocked_scripts (objects with a path) for the aggregated period |
+
+
-#### Custom scan: malware detected
+Reference scripts that parse these payloads are linked from
+[Example of scripts to create custom notifications](/command_line_interface/#example-of-scripts-to-create-custom-notifications).
-Occurs when the on-demand scanning process has finished and malware found.
+:::warning Note
+Because the script runs as
`_imunify`, that user must be able to
+both traverse the directory and execute the file. A script placed under
+
_/root_ will never run — the notifier logs
+
`fork/exec …: permission denied` and the event is dropped
+silently. Put your scripts somewhere readable, for example:
-
+
+```
+mkdir -p /opt/imunify-hooks
+mv /root/my-handler.sh /opt/imunify-hooks/
+chown root:_imunify /opt/imunify-hooks /opt/imunify-hooks/my-handler.sh
+chmod 750 /opt/imunify-hooks /opt/imunify-hooks/my-handler.sh
+```
+
+:::
-#### User scan: malware detected
+**The notifier service.**
`imunify-notifier` is socket-activated
+and exits after one minute without work, so a normal, healthy state looks like this:
-Occurs when the malware scanning process of a user account has finished and malware found.
+
-
+```
+# systemctl is-active imunify-notifier.socket imunify-notifier.service
+active
+inactive
+```
+
+
`imunify-notifier.socket` must be
+
`active (listening)`;
+
`imunify-notifier.service` being
+
`inactive` between events is expected and is not a fault. Its log
+is in the journal:
-#### Script blocked
+
-Occurs when the Proactive Defense has blocked malicious script.
+```
+journalctl -u imunify-notifier --since "1 hour ago"
+```
+
-
+### Troubleshooting
+
+
+
+| Symptom | What to check |
+
+
+
+| No notifications at all, for any event |
+Event notifications are off by default. Run imunify360-agent notifications-config show and confirm that the target you expect has "enabled": true. If /etc/sysconfig/imunify360/hooks.yaml does not exist, nothing has been configured yet. |
+
+
+| Malware was found and cleaned, but no email arrived |
+See Malware notifications and cleanup. Check whether MALWARE_SCANNING.try_restore_from_backup_first is enabled, and whether the scan was a background scan (which needs USER_SCAN_MALWARE_FOUND, not CUSTOM_SCAN_MALWARE_FOUND). |
+
+
+| No email on an ImunifyAV/AV+ server |
+There is no email target on those products. Use a script hook or panel notifications. |
+
+
+value does not match regex '^.+@(.+\.)+.+' when adding an address |
+The address must contain a dot in the domain part. root@localhost is rejected; root@localhost.localdomain is accepted. |
+
+
+| The script never runs |
+Look for fork/exec …: permission denied in journalctl -u imunify-notifier, and check the ownership and permissions as described above. |
+
+
+| The email is generated but never arrives |
+Check your MTA log (/var/log/maillog, /var/log/exim_mainlog). A line handing the message to /usr/sbin/sendmail means the notifier did its part. |
+
+
+error while getting scan info: scan not found in the notifier journal after every scheduled scan |
+Expected on Imunify360 with MALWARE_DATABASE_SCAN.enable: True. Each background run also enqueues a database scan, and the notifier can only enrich file scans, so it logs this once per user per run. File-scan notifications are unaffected. |
+
+
+
-Click
_Save changes_ at the bottom to apply all changes.
## Malware Database Scanner (MDS)
diff --git a/docs/features/panel_notifications/README.md b/docs/features/panel_notifications/README.md
index 7b4b21d5..e3407f53 100644
--- a/docs/features/panel_notifications/README.md
+++ b/docs/features/panel_notifications/README.md
@@ -4,93 +4,230 @@
## Overview
-Imunify can deliver **generic panel notifications** (also referred to as **iContact messages**) through the hosting panel’s native notification mechanism. These notifications are generated by Imunify and delivered by the panel:
+Besides the [event notifications](/features/#notifications) that the server sends by itself,
+Imunify delivers **generic panel notifications** (also referred to as **iContact messages**)
+through the hosting panel's own notification mechanism:
- **cPanel/WHM**: delivered via **cPanel iContact** (WHM → *Contact Manager*)
- **Plesk**: delivered by the **Imunify** Plesk extension via **Plesk Notifications** (*Tools & Settings → Notifications* / Notification Center)
-This mechanism is **separate** from Imunify’s event notifications configured in Imunify UI (**Settings → Notifications**) or via `imunify360-agent notifications-config`. See also: [Notifications](/features/#notifications).
+The two channels are entirely separate, and the difference matters when you are deciding where to
+look for a missing message:
+
+
+
+ | Event notifications | Panel notifications |
+
+
+| Generated by | the server, from its own events | the Imunify cloud, from telemetry the server uploads |
+| Delivered by | the local MTA, or your script | the hosting panel |
+| Configured in | Settings → Notifications (per event), notifications-config | Settings → Notifications → Panel notifications (per message type), config update |
+| Default state | off, except the malware hook the agent installs on Plesk | everything on |
+| Timing | immediately for scan events; five minutes or more for the aggregated real-time and Proactive Defense events | up to a day after the event |
+| Available on | any supported panel | cPanel/WHM and Plesk only |
+
+
+
+::::tip Note
+Panel notifications are produced only when the control panel is cPanel/WHM or Plesk. On any other
+panel, and in stand-alone mode, the agent does not request them and the
+
_Panel notifications_ row is not shown in the UI.
+::::
-## What gets reported
+## How they are produced and delivered
+
+1. The agent uploads server telemetry (scan results, detected applications, configuration) to the Imunify cloud.
+2. The cloud evaluates that telemetry and prepares a notification with a ready-made subject and HTML body, together with a **period limit** for that message type.
+3. The agent asks the cloud for pending notifications **no more than once every 24 hours**.
+4. Before delivering, the agent applies the period limit it received, so the same message type is not repeated more often than the cloud allows.
+5. The message is handed to cPanel iContact or to the Plesk Notification Center, which decides the actual recipients and channels.
+
+Two consequences follow from this design and account for most support questions:
+
+* **There is no "send me a test notification" action.** The content is generated in the cloud, not on the server, so it cannot be triggered locally.
+* **A configuration change is not reflected immediately.** It reaches the cloud with the next telemetry upload, the cloud evaluates telemetry from the last few days, and the server asks for messages once a day — so a change can take more than a day to show, in either direction.
+
+## Message types
+
+The dialog lets you switch off seven message types individually. Each one is generated
+independently and has its own cooldown.
+
+
+
+| UI label | Configuration key | Sent when | Cooldown | Scope |
+
+
+
+| Malware found | malware_found |
+a user or background scan found malicious files on the server within the last 24 hours |
+24 hours |
+ImunifyAV / ImunifyAV+ only; agent 6.7 or later |
+
+
+| Malware detected in databases | malware_detected |
+the Malware Database Scanner detected malware in a database |
+24 hours | all products |
+
+
+| Malicious redirect detected | malicious_redirect_detected |
+a malicious redirect was detected on a website |
+24 hours | all products |
+
+
+| Vulnerable script detected | aibolit_vulnerable |
+the scanner detected a vulnerable script |
+24 hours | all products |
+
+
+| Insecure WordPress version | insecure_wp_core |
+an installed WordPress core has known vulnerabilities |
+7 days | all products |
+
+
+| Outdated WordPress version | outdated_wp_core |
+an installed WordPress core version is outdated |
+7 days | all products |
+
+
+| Malware scan is not scheduled | scan_not_scheduled |
+MALWARE_SCAN_SCHEDULE.interval is set to none and no user or background scan has run in the last 30 days |
+7 days | all products; agent 6.7 or later |
+
+
+
+
+::::tip Note
+These seven are not the only messages that arrive through this channel. The Imunify cloud also
+sends, for example, a warning when the agent version is outdated, PCI compliance notices, or a
+report about compromised accounts. Those have no individual switch and are governed by the master
+switch alone — turning all seven types off is **not** the same as turning panel notifications off.
+::::
-Generic (iContact) notifications are **HTML-capable messages** with a subject and body provided by the Imunify backend. They typically include security alerts and recommendations, for example:
+:::warning Important
+
**Malware found** is an upgrade prompt addressed to
+
ImunifyAV and
ImunifyAV+
+administrators, and it is **never generated for an Imunify360 server** — Imunify360 already includes
+everything the message recommends.
-- malware detected / suspicious activity
-- scan not scheduled / scan not running
-- CMS security signals (for example, insecure WordPress core or vulnerable themes/plugins)
+If you run Imunify360 and want an email whenever a scan finds malware, that is what
+[event notifications](/features/#notifications) are for: enable the
+
ADMIN target on
+
USER_SCAN_MALWARE_FOUND (scheduled and user scans),
+
CUSTOM_SCAN_MALWARE_FOUND (on-demand scans) and
+
REALTIME_MALWARE_FOUND (uploads).
+:::
-Each notification has its own backend-defined cooldown (period limit), and the agent enforces it.
+## Choosing which message types to receive
-## Who receives these messages
+Go to
_Settings → Notifications_ and click
+
_Manage panel notifications_ in the
+
_Panel notifications_ row.
-A notification can be addressed either:
+
-- to the **server administrator** (panel admin) — when no specific user is provided, or
-- to a **specific panel user** (customer/reseller) — when a target user login is provided by the backend.
+*
**Enable panel notifications** is the master switch. Turning it off stops all panel notifications at once and greys out the individual types, which keep their own values.
+* Each of the seven types below has its own toggle. All of them are **on** by default.
-User-targeted delivery is controlled by `CONTROL_PANEL.generic_user_notifications` (default: `True`).
+
-## Licensing
+Click
_Apply_ to save. The dialog writes both
+
`ADMIN_CONTACTS.enable_icontact_notifications` (the master switch)
+and
`DASHBOARD.notifications` (the individual types) in a single
+configuration update.
-Panel notifications do **not** require an additional add-on license. They are controlled by a configuration option and are available on supported panels where the delivery channel exists (cPanel/WHM, Plesk).
+::::tip Note
+The dialog ships with Imunify UI **8.13.1**; the configuration keys behind it come with
+imunify-antivirus **8.8.2** (the antivirus component is part of both products). The
+
_Panel notifications_ row appears only when both conditions hold:
+the control panel is cPanel/WHM or Plesk, **and** the agent reports a
+
`DASHBOARD.notifications` section in its configuration. If the row
+is missing on a cPanel or Plesk server, check both versions; the agent side can be verified with:
-## Requirements
+
-- **Imunify360 or ImunifyAV/AV+** installed and running.
-- **For Plesk delivery**: Plesk installed, and the Imunify extension installed/enabled in Plesk.
-- **For cPanel delivery**: cPanel/WHM installed, and WHM Contact Manager configured with at least one destination.
+```
+imunify360-agent config show | grep -A8 DASHBOARD
+```
+
+::::
-## Configuration (Imunify)
+## Configuration keys
-The feature is controlled by Imunify configuration keys:
+Panel notifications are controlled by three keys in
+
_/etc/sysconfig/imunify360/imunify360.config_ (or a file in
+
_/etc/sysconfig/imunify360/imunify360.config.d/_):
-- **Config path**: `/etc/sysconfig/imunify360/imunify360.config` (or a file in `/etc/sysconfig/imunify360/imunify360.config.d/`)
-- **Keys**:
- - `ADMIN_CONTACTS.enable_icontact_notifications` (**default:** `True`)
- - `CONTROL_PANEL.generic_user_notifications` (**default:** `True`, controls user-targeted delivery)
+
+
+| Key | Default | Effect |
+
+
+ADMIN_CONTACTS.enable_icontact_notifications | True | master switch for delivering generic messages through the panel |
+DASHBOARD.notifications.<type> | True | whether the cloud generates this message type for this server |
+CONTROL_PANEL.generic_user_notifications | True | whether user-targeted messages may be delivered to panel end users |
+
+
-### Enable/disable in YAML
+### In YAML
```
ADMIN_CONTACTS:
enable_icontact_notifications: True
+DASHBOARD:
+ notifications:
+ malware_found: True
+ malware_detected: True
+ malicious_redirect_detected: True
+ aibolit_vulnerable: True
+ insecure_wp_core: True
+ outdated_wp_core: True
+ scan_not_scheduled: True
```
-### Enable/disable via CLI
+### Via CLI
-**Imunify360:**
+Turn everything off (**Imunify360**):
```
-imunify360-agent config update '{"ADMIN_CONTACTS": {"enable_icontact_notifications": true}}'
+imunify360-agent config update '{"ADMIN_CONTACTS": {"enable_icontact_notifications": false}}'
```
-Disable:
+Turn off individual message types and keep the rest:
```
-imunify360-agent config update '{"ADMIN_CONTACTS": {"enable_icontact_notifications": false}}'
+imunify360-agent config update '{"DASHBOARD": {"notifications": {"outdated_wp_core": false, "insecure_wp_core": false}}}'
```
-**ImunifyAV/AV+:**
+The same commands on **ImunifyAV/AV+** use the
`imunify-antivirus`
+binary:
```
-imunify-antivirus config update '{"ADMIN_CONTACTS": {"enable_icontact_notifications": true}}'
+imunify-antivirus config update '{"DASHBOARD": {"notifications": {"scan_not_scheduled": false}}}'
```
-### (Optional) Disable user-targeted delivery
+::::tip Note
+Turning a type off in
`DASHBOARD.notifications` stops the message
+at the source: the cloud stops generating it for this server as soon as the change reaches the
+cloud. Because the change travels with the next telemetry upload and the cloud query looks back two
+days, a message that was already prepared can still arrive shortly after you disable the type.
+::::
+
+### Disabling user-targeted delivery
-If you want these notifications to go **only to the server administrator** and never to end users, disable `CONTROL_PANEL.generic_user_notifications`.
+If these notifications should go only to the server administrator and never to end users, disable
+
`CONTROL_PANEL.generic_user_notifications`.
**Imunify360 (global):**
@@ -119,13 +256,61 @@ imunify-antivirus config update '{"CONTROL_PANEL": {"generic_user_notifications"
```
+## Who receives these messages
+
+A notification is addressed either:
+
+- to the **server administrator** (panel admin) — when no specific user is provided, or
+- to a **specific panel user** (customer/reseller) — when a target user login is provided.
+
+User-targeted delivery is controlled by
+
+
+```
+imunify360-agent config show | grep -A8 DASHBOARD
+imunify360-agent config show | grep -A3 ADMIN_CONTACTS
+```
+
+
+**See what the agent handed to the panel.** Each message the agent passes to cPanel or Plesk is
+logged to
+
+```
+grep -E "cPanel.notify|Plesk.notify" /var/log/imunify360/console.log | tail
+```
+
+These lines are written *before* the panel handler runs, so they show that a message reached the
+server and was handed over — not that the panel delivered it. On Plesk the extension records the
+outcome in