Imunify360 can be installed directly on the server, independent of any panel, regardless of the administrative interface.
It is also called stand-alone, non-panel, generic panel integration).
Operating system
Web servers
mod_security
configurationWarning
Imunify Web-UI PHP code has to be executed under a non-root user which has access to /var/run/defence360agent/non_root_simple_rpc.sock
. If it runs in CageFS, you'll need to configure it accordingly.
To allow non-root user in CageFS access to the socket, this workaround should be applied:
# create directory for moun-point
mkdir /imunify-ui-shared
# add symlink for user which belong to UI backend `imunify-web` in this example)
ln -s /var/run/defence360agent /imunify-ui-shared/imunify-web
# add symlink to cagefs skeleton
rm -f /usr/share/cagefs-skeleton/var/run/defence360agent
ln -s /imunify-ui-shared/imunify-web /usr/share/cagefs-skeleton/var/run/defence360agent
# add mount point to cagefs
echo "%/imunify-ui-shared" >> /etc/cagefs/cagefs.mp
# remount all
cagefsctl --remount-all
Imunify360 Stand-alone version requires the following components installed or enabled at the server:
mod_remoteip
or nginx module ngx_http_realip_module
json
extension loaded and proc_open
function enabled (remove it from the disable_functions
list in php.ini
)Warning
We recommend using the stable versions of ModSecurity3 (i.e. 3.0.4), because developing versions (i.e. master) can have stability issues (see https://github.com/SpiderLabs/ModSecurity/issues/2381 for example).
Imunify360 Stand-alone version require the following integrations before installation:
All integrations set in the integration config file like /etc/sysconfig/imunify360/integration.conf
. You can find more details on config file here.
Imunify360 UI is implemented as a single-page application (SPA) and requires a web server to serve it. It’s required to specify a path to the web server directory, where the Imunify360 UI SPA application will be installed and served.
Example
[paths]
ui_path = /var/www/vhosts/imunify360/imunify360.hosting.example.com/html/im360
Ensure that the domain you are going to use for the Imunify360 web-based UI refers to this path and that there are no other scripts or files under ui_path
, as they might be overridden by Imunify360 installation.
Configure ModSecurity configuration directives (so that it can block):
SecAuditEngine RelevantOnly
SecConnEngine Off
SecRuleEngine On
Create the empty file /etc/sysconfig/imunify360/generic/modsec.conf
and include it into the web server config as IncludeOptional
. The file would be replaced with the actual config during the first Imunify360 installation or you can fill it via calling the Imunify360 ModSec ruleset installation imunify360-agent install-vendors
.
Note
ModSecurity has different syntax comparing to Nginx configuration, thus ModSecurity directives can not be directly included to the Nginx config files.
Create a separate file (i.e. /etc/nginx/modsec.conf
) and set the following ModSecurity directives in it:
SecAuditEngine RelevantOnly
SecConnEngine Off
SecRuleEngine On
SecAuditLogFormat JSON
# should match modsec_audit_log option in integration.conf (see below)
SecAuditLog /var/log/nginx/modsec_audit_log
Warning
ModSecurity on Nginx does not properly re-opens audit log on SIGHUP/SIGUSR1, which can cause logrotate to break integration with Imunify360. See https://github.com/SpiderLabs/ModSecurity-nginx/issues/121 for details.
Create an empty file /etc/sysconfig/imunify360/generic/modsec.conf
. The file would be replaced with the actual config during the first Imunify360 installation or you can fill it via calling the Imunify360 ModSec ruleset installation imunify360-agent install-vendors
.
Then enable ModSecurity and include both files into Nginx configuration using the modsecurity_rules_file
directive:
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec.conf;
modsecurity_rules_file /etc/sysconfig/imunify360/generic/modsec.conf;
Set the path and graceful restart script in the integration.conf
[web_server].graceful_restart_script
– a script that restarts the web server to be called after any changes in web server config or ModSecurity rules[web_server].modsec_audit_log
– a path to ModSecurity audit log file[web_server].modsec_audit_logdir
– a path to ModSecurity audit log directory (required when the SecAuditLogType
set to the Concurrent
)Example
[web_server]
server_type = apache
graceful_restart_script = /usr/sbin/apachectl restart
modsec_audit_log = /var/log/httpd/modsec_audit.log
modsec_audit_logdir = /var/log/modsec_audit
To enable domain-specific ModSecurity configuration, specify the modsec_domain_config_script
in the integration.conf
.
[integration_scripts]
modsec_domain_config_script = /path/to/inject/domain/specific/config/script.sh
It should point to an executable file that accepts as an input a list of domain-specific web server settings and injects them into the server config. The standard input (stdin) is given in the JSON Lines format similar to the following:
{"user": "username", "domain": "example.com", "content": "modsec config text"}
{"user": "another", "domain": "another.example.com", "content": "..."}
Each line contains config for a single domain e.g., it may contain rule tags excluded for the domain. The script should also restart the web server to apply the configuration. This should be done so that the script could implement the check that web server comes up after config change, and reset configuration if it doesn't.
If configuration change failed, the script should return 1, and in the standard error stream (stderr) it should return the reason for failure. On success, the script should return 0. In a single run of the script, we might update a single domain/user, as well as multiple users (all users) on the system.
WebShield consists of four services:
The configuration of WebShield is done by an agent, and direct editing of WebShield configuration files is generally not recommended. This is mainly because after the next reconfiguration all custom changes would be lost. However, a host administrator is allowed to set a certificate as the default one for WebShield to return.
When Imunify360 stand-alone is installed, WebShield is disabled by default.
You can enable it only via CLI. To do so, run the following commands:
imunify360-agent config update '{"WEBSHIELD": {"enable": true, "known_proxies_support": true}}'
systemctl enable imunify360-webshield
systemctl restart imunify360-webshield
/etc/imunify360-webshield/ssl_certs
folder/etc/imunify360-webshield/ssl.conf
file, change the following directives according to your changes:ssl_certificate ssl_certs/dummy.pem;
ssl_certificate_key ssl_certs/dummy.pem;
If you want to provide intermediate certificates, they are to be appended to the certificate file.
These settings require WebShield to be restarted/reloaded.
To manually manage the certificate cache, use the /usr/sbin/im360-ssl-cache
utility.
To add certificates to the cache, a user would run the command:
im360-ssl-cache --add /path/to/certs.json
The --add
parameter accepts exactly one value. If the parameter value is not -
, it is taken as a path to a file in JSON format with a list of certificates and private keys to be added. Otherwise, if the parameter value is -
, data is expected to be sent in JSON format to STDIN as in the following example:
cat certs.json | im360-ssl-cache --add -
Format of JSON file:
[
{
"domain": "john.example.com",
"key": "-----BEGIN PRIVATE KEY-----\nM...O\n-----END PRIVATE KEY-----\n",
"certificate": "-----BEGIN CERTIFICATE-----\nMI...Y=\n-----END CERTIFICATE-----\n",
"chain": "-----BEGIN CERTIFICATE-----\nM...I=\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nM...U=\n-----END CERTIFICATE-----\n"
},
{
"domain": "bob.example.com",
"key": "...",
"certificate": "...",
"chain": "..."
}
]
Note
As JSON text is not allowed to have line breaks, all newline symbols must be escaped as in the example above.
To remove certificate(s) from the cache, a user is expected to run the command:
im360-ssl-cache --remove example.org example.com …
The --remove
parameter expects one or more space-separated domain names, for which certificates are to be removed from the cache.
When no parameters are passed, the im360-ssl-cache
simply lists all domain names of certificates in the cache.
Note
Passing certificates data in JSON format is done to put data flow in good order, to avoid excessive checks of data. No certificate checks are made.
When a request without Server Name Indication (SNI) comes, WebShield has to guess what certificate from the cache to serve.
To allow WebShield to handle non-SNI requests properly, include an ip
field in the JSON that you pass to the im360-ssl-cache
.
[
{
"domain": "...",
"key": "...",
"certificate": "...",
"chain": "...",
"ip": "..." // NEW, optional, NOT UNIQUE
},..
]
WebShield will use this data to decide which certificate to serve if a request without Server Name Indication (SNI) arrives. If there are several domains with the specified IPs, WebShield will use the first one alphabetically.
To ensure WebShield and Graylist are working correctly (e.g. a correct IP is passed to ModSecurity), the server must recognize WebShield as an internal proxy. For example, for Apache, mod_remoteip
must be installed and configured like this:
<IfModule remoteip_module>
RemoteIPInternalProxy 127.0.0.1
RemoteIPInternalProxy ::1
RemoteIPHeader X-Forwarded-For
</IfModule>
For Nginx, the ngx_http_realip_module
module should be configured in the following way:
real_ip_header X-Forwarded-For;
set_real_ip_from 127.0.0.1;
set_real_ip_from ::1;
WebShield passes the real client IP in the X-Forwarded-For
header.
Note
In the Apache LogFormat configuration strings for correct representation of a remote host IP address it is required using:
%a Client IP address of the request
instead of
%h Remote hostname
You can find more details at http://httpd.apache.org/docs/current/mod/mod_log_config.html.
To scan files uploaded via FTP, configure PureFTPd. Write in the pure-ftp.conf
:
CallUploadScript yes
To scan files for changes (to detect malware) using inotify, configure which directories to watch and which to ignore in the integration.conf
file:
[malware].basedir
– a root directory to watch (recursively)[malware].pattern_to_watch
– only directories that match this (Python) regex in the basedir are actually going to be watchedExample
[malware]
basedir = /home
pattern_to_watch = ^/home/.+?/(public_html|public_ftp|private_html)(/.*)?$
Imunify360 Stand-alone version can use PAM service to authenticate users for the Imunify360 UI application.
You can specify which PAM service Imunify360 should use with the service_name
option:
[pam]
service_name = system-auth
You can get a token which can be used for authentication using the login
command.
The administrators have full access to Imunify360 UI and its settings.
By default, root
is considered to be the only admin
user.
To add more administrators, list them in the /etc/sysconfig/imunify360/auth.admin
file
or specify the admins option in the /etc/sysconfig/imunify360/integration.conf
Admin users will be merged from three sources: /etc/sysconfig/imunify360/auth.admin
list and scripts defined in the
/etc/sysconfig/imunify360/integration.conf
or /opt/cpvendor/etc/integration.ini
that return user lists.
[integration_scripts]
admins = /path/to/get-admins-script.sh
It should point to an executable file that generates a JSON file similar to the following:
{
"data": [
{
"name": "admin1",
"unix_user": "admin",
"locale_code": "EN_us",
"email": "admin1@domain.zone",
"is_main": true
},
{
"name": "admin2",
"unix_user": "admin",
"locale_code": "Ru_ru",
"email": "admin2@domain.zone",
"is_main": false
},
],
"metadata": {
"result": "ok"
}
}
The installation instructions are the same as for cPanel/Plesk/DirectAdmin version and can be found in the Imunify360 documentation.
The web-based UI is available via the domain configured in the ui_path
.
Note
No files should be located in the folder configured with ui_path
. We do not recommend using a directory in which any files are stored as a directory for Imunify UI files.
For example, if /var/www/vhosts/imunify360/imunify360.hosting.example.com/html/im360
is the document root folder for the imunify360.hosting.example.com
domain, then you could open Imunify360 with the following URL:
https://imunify360.hosting.example.com/
(when you have TLS certificate configured for the domain) orhttp://imunify360.hosting.example.com/
By default, Imunify360 will use Linux system users, limited by uid_min
and uid_max
from the /etc/login.defs
.
If you want to see a specific list of users (note, that all of them must be real Linux users accessible via PAM), you can specify the users
option in the /etc/sysconfig/imunify360/integration.conf
:
[integration_scripts]
users = /path/to/get-users-script.sh
It should point to an executable file that generates a JSON file similar to the following (see details here):
{
"data": [
{
"id": 1000,
"username": "ins5yo3",
"owner": "root",
"domain": "ins5yo3.com",
"package": {
"name": "package",
"owner": "root"
},
"email": "ins5yo3@ins5yo3.com",
"locale_code": "EN_us"
},
{
"id": 1001,
"username": "ins5yo4",
"owner": "root",
"domain": "ins5yo4.com",
"package": {
"name": "package",
"owner": "root"
},
"email": "ins5yo4@ins5yo4.com",
"locale_code": "EN_us"
}
],
"metadata": {
"result": "ok"
}
}
To provide a list of domains for Imunify360, specify the script that generates a JSON file in the /etc/sysconfig/imunify360/integration.conf
:
[integration_scripts]
domains = /path/to/get-domains-script.sh
A JSON file should be similar to the following:
{
"data": {
"example.com": {
"document_root": "/home/username/public_html/",
"is_main": true,
"owner": "username",
},
"subdomain.example.com": {
"document_root": "/home/username/public_html/subdomain/",
"is_main": false,
"owner": "username",
}
},
"metadata": {
"result": "ok"
}
}
web_server_config_path
should point to a path that is added as IncludeOptional
in this domain's virtual host e.g., /path/to/example.com/specific/config/to/include
path should be added for the example.com
domain.
The documentation for the Imunify360 Stand-alone version integration configuration file format.
Location /etc/sysconfig/imunify360/integration.conf
Parameters
[paths]
ui_path = /var/www/vhosts/imunify360/imunify360.hosting.example.com/html/im360
The path to the web server directory, where Imunify360 will be installed and served by web server. Need to be defined before Imunify360 installation.
[paths]
ui_path_owner = panel_user:web_server_group
Allows executing chown
to that owner for files after installation. The parameter is optional, if it is absent, chown
doesn't execute.
[pam]
service_name = system-auth
The PAM service is used for user authentication in the Imunify360 UI application.
By default the system-auth
service is used.
[integration_scripts]
admins = /path/to/get-admins-script.sh
The path to the executable script that generates a JSON file with the list of admin accounts.
{
"data": [
{
"name": "admin1",
"unix_user": "admin",
"locale_code": "EN_us",
"email": "admin1@domain.zone",
"is_main": true
},
{
"name": "admin2",
"unix_user": "admin",
"locale_code": "Ru_ru",
"email": "admin2@domain.zone",
"is_main": false
}
],
"metadata": {
"result": "ok"
}
}
[integration_scripts]
users = /path/to/get-users-script.sh
The script to provide the specific list of users used by Imunify360.
It should point to an executable file that generates a JSON file similar to the following (domains are optional):
{
"data": [
{
"id": 1000,
"username": "ins5yo3",
"owner": "root",
"domain": "ins5yo3.com",
"package": {
"name": "package",
"owner": "root"
},
"email": "ins5yo3@ins5yo3.com",
"locale_code": "EN_us"
},
{
"id": 1001,
"username": "ins5yo4",
"owner": "root",
"domain": "ins5yo4.com",
"package": {
"name": "package",
"owner": "root"
},
"email": "ins5yo4@ins5yo4.com",
"locale_code": "EN_us"
}
],
"metadata": {
"result": "ok"
}
}
Key | Nullable | Description |
id | False | ID of the UNIX account in the system. |
username | False | The name of the UNIX account in the system. |
owner | True | The name of the account owner. The owner can be an administrator (in this case he should be included in the admins() output) or a reseller (in this case he should be included in the resellers() output). |
locale_code | True | The locale selected by a user. |
email | True | Email of the account user. If there is no email, it should return null. |
domain | True | The main domain of a user. |
package | True | Information about the package to which a user belongs to. If the user doesn’t belong to any package, it should return null. |
package.name | False | The name of the package to which a user belongs to. |
package.owner | True | The owner of the package to which a user belongs to (reseller or administrator). |
[integration_sctipts]
domains = /path/to/get-domains-script.sh
It should point to an executable file that generates a JSON file similar to the following
{
"data": {
"example.com": {
"document_root": "/home/username/public_html/",
"is_main": true,
"owner": "username"
},
"subdomain.example.com": {
"document_root": "/home/username/public_html/subdomain/",
"is_main": false,
"owner": "username"
}
},
"metadata": {
"result": "ok"
}
}
web_server_config_path
should point to a path that is added as IncludeOptional
in this domain's virtual host e.g., /path/to/example.com/specific/config/to/include
path should be added for the example.com
domain.