ModSecurity is a toolkit for real-time web application monitoring, logging, and access control.
CustomBuild allows you to install ModSecurity together with desired rulesets. The comodo ruleset will also install a plugin where you may manage rules from the DirectAdmin panel itself. The owasp is another rule provider available for automatic installation.
cd /usr/local/directadmin/custombuild
./build update
./build set modsecurity yes
./build set modsecurity_ruleset "comodo"
./build modsecurity
./build modsecurity_rules
./build rewrite_confsModSecurity Log Locations
/var/log/httpd
or:
/var/log/nginx
Log files contained therein include:
modsec_audit.logmodsec_debug.log
The following directadmin.conf default setting specifies the modsecurity audit log location like so:
modsec_audit_dir=/var/log/modsec_auditUser controlled per-domain ModSecurity flags
This feature enables Users to skip some mod_security rules, or fully disable them when needed. Users can also view the per-domain logs via this interface and/or completely disable ModSecurity altogether.
How to disable the User’s ability to use per-domain ModSecurity feature
Disabling the feature for all Users globally
Should you want to disable all Users’ ability to use this feature, use the never commands feature, eg:
/usr/local/directadmin/direcadmin set never_commands CMD_MODSECURITY
service directadmin restartDisabling the feature for a Single User
Should you want to disable only one single User’s ability to use this feature, use commands.deny like so, but replace USERNAME with the actual username to be denied access to CMD_MODSECURITY:
echo 'CMD_MODSECURITY' >> /usr/local/directadmin/data/users/USERNAME/commands.denyCustomizing ModSecurity Rules
A User or Admin can fully disable ModSecurity rules as needed via SecRuleRemoveById.
Syntax rules for SecRuleRemoveById include:
- must be a positive integer
1234- ranges are allowed, as long as they’re “quoted”, eg:
"1234-1239"The following describes how to use this with DirectAdmin.
Globally – The Old Method
To customize ModSecurity Rules globally, you can add custom rules to /usr/local/directadmin/custombuild/custom/modsecurity/conf/, and they’ll be added automatically to /etc/modsecurity.d after ./build modsecurity or ./build modsecurity_rules is ran. This method still works in addition to the new method.
An example for “MYCUSTOMRULES”:
cd /usr/local/directadmin/custombuild
mkdir -p custom/modsecurity/conf
nano -w /usr/local/directadmin/custombuild/custom/modsecurity/conf/MYCUSTOMRULES.conf
./build modsecurity_rulesBuilding the custom rules with CustomBuild will result in a copy of them being placed in /etc/modsecurity.d/, which is included in the webserver configs via a series of Includes dependent on the type of webserver you use.
Globally – The New Method
Log into DirectAdmin and use the global ModSecurity interface located at Server Manager >> ModSecurity (https://hostname:2222/admin/modsecurity) to manage the status of ModSecurity, customize rules, and view logs.
Adding rule IDs in this interface will add them to the following global file:
/usr/local/directadmin/data/admin/modsecurity_rulesThis file is included by directly by the webserver configs.
Per domain
You can modify the per domain ModSecurity rules either via CustomBuild as described above, or as the Admin or User as described below.
As Admin
Log into DirectAdmin and use the global ModSecurity interface located at Server Manager >> ModSecurity (https://hostname:2222/admin/modsecurity)
If an Admin is making a call to CMD_MODSECURITY, they are allowed to either pass the domain of some other User, or no domain at all. Admin can view rules and logs as well as manage rules for a User via CMD_MODSECURITY by passing the domain=DOMAIN parameter. Without this, the global rules will be returned.
As the User
Log into DirectAdmin and use the User ModSecurity interface located at Advanced Features >> ModSecurity (https://hostname:2222/user/modsecurity)
The rules will be stored in the following files:
- for domains:
/usr/local/directadmin/data/users/USER/domains/DOMAIN.COM.modsecurity_rules- for subdomains:
/usr/local/directadmin/data/users/USER/domains/DOMAIN.COM.subdomains_modsecurity_rules/SUB.modsecurity_rulesBased off of the following template:
/usr/local/directadmin/data/templates/mod_security_rules.confCustomizing the ModSecurity Configuration
Methods exist in CustomBuild to permit one to customize the ModSecurity configuration as described below. We will use a common example requiring ModSecurity config changes.
Request body no files data length is larger than the configured limit
If you see the following error in the Apache error log, you can increase the limit via the Apache configuration, however, you must do so in a manner that will allow CustomBuild to preserve the change:
ModSecurity: Request body no files data length is larger than the configured limit (131072).This limit (SecRequestBodyNoFilesLimit) is set via the following files:
/usr/local/directadmin/custombuild/configure/ap2/conf/extra/httpd-modsecurity.conf/usr/local/directadmin/custombuild/configure/openlitespeed/conf/httpd-modsecurity.conf/usr/local/directadmin/custombuild/configure/nginx_reverse/conf/nginx-modsecurity.conf/usr/local/directadmin/custombuild/configure/nginx/conf/nginx-modsecurity.conf
Steps for adjusting this value so that it is not overwritten with the next CustomBuild rebuild of your webserver configuration are defined below. Alternatively, you might try specifying a new setting via the /etc/httpd/conf/extra/httpd-includes.conf file (or the includes file for your chosen webserver) since it is not touched by CustomBuild.
Apache
- Make sure the custom Apache directory exists:
mkdir -p /usr/local/directadmin/custombuild/custom/ap2/conf/extra
cp -a /usr/local/directadmin/custombuild/configure/ap2/conf/extra/httpd-modsecurity.conf /usr/local/directadmin/custombuild/custom/ap2/conf/extra/httpd-modsecurity.conf - Edit the value in the custom file as desired:
nano /usr/local/directadmin/custombuild/custom/ap2/conf/extra/httpd-modsecurity.confor
vim /usr/local/directadmin/custombuild/custom/ap2/conf/extra/httpd-modsecurity.confor use whatever your preferred editor happens to be.
- Rebuild the configuration:
/usr/local/directadmin/custombuild/build rewrite_confsThe process is quite similar for other webservers.
OpenLiteSpeed
mkdir -p /usr/local/directadmin/custombuild/custom/openlitespeed/conf/
cp -a /usr/local/directadmin/custombuild/configure/openlitespeed/conf/httpd-modsecurity.conf /usr/local/directadmin/custombuild/custom/openlitespeed/conf/httpd-modsecurity.conf
nano /usr/local/directadmin/custombuild/custom/openlitespeed/conf/httpd-modsecurity.conf
/usr/local/directadmin/custombuild/build rewrite_confsNginx Reverse Proxy
mkdir -p /usr/local/directadmin/custombuild/custom/nginx_reverse/conf/
cp -a /usr/local/directadmin/custombuild/configure/nginx_reverse/conf/nginx-modsecurity.conf /usr/local/directadmin/custombuild/custom/nginx_reverse/conf/nginx-modsecurity.conf
nano /usr/local/directadmin/custombuild/custom/nginx_reverse/conf/nginx-modsecurity.conf
/usr/local/directadmin/custombuild/build rewrite_confsNginx
mkdir -p /usr/local/directadmin/custombuild/custom/nginx/conf/
cp -a /usr/local/directadmin/custombuild/configure/nginx/conf/nginx-modsecurity.conf /usr/local/directadmin/custombuild/custom/nginx/conf/nginx-modsecurity.conf
nano /usr/local/directadmin/custombuild/custom/nginx/conf/nginx-modsecurity.conf
/usr/local/directadmin/custombuild/build rewrite_confsEnabling ModSecurity Uploadscan
This feature requires ClamAV, so ensure this is enabled first or at least set to ‘yes’ in the CustomBuild options.conf. Then, run the following CustomBuild commands:
cd /usr/local/directadmin/custombuild
./build set modsecurity_uploadscan yes
./build modsecurity
./build rewrite_confsHow can I confirm that ModSecurity is working
Testing browser-based requests to the site
Just load your domain like so in the browser:
yourdomain.com/?page=../../etc/passwdAnd then check the domain’s error logs. This should trigger File Inclusion protections in ModSecurity and result in an error. You should see something like this logged:
ModSecurity: Access denied with code 406 (phase 2). Matched "Operator `Rx' with parameter `(?i)(?:\x5c|(?:%(?:c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|2(?:5(?:c(?:0%25af|1%259c)|2f|5c)|%46|f)|(?:(?:f(?:8%8)?0%8|e)0%80%a|bg%q)f|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|u(?:221[56]|002f|EFC8|F025)|1u|5 (400 characters omitted)' against variable `ARGS:page' (Value: `../../etc/passwd' ) [file "/etc/modsecurity.d/REQUEST-930-APPLICATION-ATTACK-LFI.conf"] [line "29"] [id "930100"] [rev ""] [msg "Path Traversal Attack (/../)"] [data "Matched Data: /../ found within ARGS:page: ../../etc/passwd"] [severity "2"] [ver "OWASP_CRS/3.3.0"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-lfi"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/255/153/126"] [hostname "108.160.151.160"] [uri "/"] [unique_id "161575949767.714205"] [ref "o9,4v4,23o2,4v11,16"], client: X.X.X.X, server: yourdomain.com, request: "GET /?page=../../etc/passwd HTTP/1.1", host: "yourdomain.com"
Error logs are located here, depending on webserver and domain, respectively:
/var/log/*/domains/*.error.logTesting ModSecurity Uploadscan
If you need to test ModSecurity Uploadscan, you can try uploading the EICAR test files located at the following links to ensure that the upload is blocked:
CMD_MODSECURITY
This section describes the CMD_MODSECURITY command and required/optional GET/POST parameters.
VIEW RULES
Viewing global rules as admin
CMD_MODSECURITYViewing a User’s per-domain rules
CMD_MODSECURITY?domain=domain.comCMD_MODSECURITY?domain=domain.com&subdomain=sub
Viewing json output
The following:
CMD_MODSECURITY?domain=domain.com&json=yesreturns 2 arrays, one for On/Off flags, and the other for skip IDs, eg:
{
"SecRuleRemoveById" :
[
"1234"
],
"flags":
{
"SecFilterScanPOST": "On",
"SecRuleEngine": "On"
}
}Viewing the options.conf Modsecurity setting value
You can learn if modsecurity=yes is set in the options.conf via:
CMD_ADDITIONAL_DOMAINS?action=view&domain=domain.com.com&json=yeswith the added value:
modsecurity=yes|noWhen called by an Admin, absence of the domain will return the global modsecurity_rules file.
You’ll also get a “subdomain_select” array, which is a standard select-box for the available subdomains.
Save flags
- action: CMD_MODSECURITY
- method: POST
- domain=domain.com
- action=save
- SecFilterScanPOST=On|Off
- SecRuleEngine=On|Off
- optional, can also include to save a call if saving and skipping in 1 request:
SecRuleRemoveById=<ID>
When called by an Admin, absence of the domain will save to the global modsecurity_rules file. This also applies to the rule skips below.
Add rule skip
action: CMD_MODSECURITYmethod: POSTdomain=domain.comaction=addSecRuleRemoveById=<ID>
Remove rule skip
action: CMD_MODSECURITYmethod: POSTdomain=domain.comaction=selectSecRuleRemoveById=<ID>AND/ORselect0=<ID>(select1)=<ID>
View logs
JSON output is only of the modsec_audit.log. This requires the modsec_audit.log to use the new one-json-per-line format.
Users/Admins
CMD_MODSECURITY?action=log&domain=domain.comOnly show entries matching this domain.
For Users, the domain must be in the domains.list.
For Admins, can be any host value they want.
Sub-domains will be included in the output.
Blank hosts are not included.
Admins
CMD_MODSECURITY?action=logShows entries with any Host value (or no Host).
To reduce the log output, you should include the following, specifying your desired value:
&lines=1000DA starts from the end of the log, parsing lines backwards.
It stops after this number of ENTRIES has been added to the log (was a tail, but it’s now entries).
There is also an internal max_time=15 (which is dynamic, timeout / 4, assuming timeout=60).
You can pass &max_time=5 or any other number of seconds, to have the parser stop after this number of seconds, that is if you wish to speed up the display at the cost of losing some older entries.
For very large logs, there is no point in parsing the entire thing if a timeout will happen.
The logs will be output in a “logs” array, filled with a list of transaction arrays.
The top-level json also includes a “summary” array, giving info on how the parser actually went, eg:
"summary":
{
"max_time": "15",
"requested_lines": "500",
"returned_lines": "375",
"time_abort": "yes"
}If you see "time_abort" ; "yes", it would mean that time ran out before actually finding that number of lines/entries.
ModSecurity Templates and Skins
TEMPLATE
/usr/local/directadmin/data/templates/mod_security_rules.confWhere flags are stored into |FLAGS| and the multi-line SecRuleRemoveById values are saved into |DISABLEDRULES|
There template starts with |CUSTOM1| and ends with |CUSTOM2|, but these tokens are currently blank for possible future expansion.
In the virtual_host2*.conf, we’ve added a new token:
|MOD_SECURITY_RULES|within the <Directory> context.
Also, this token is available in the nginx_server*.conf and the openlitespeed_vhost.conf.
SKINS
New file:
/usr/local/directadmin/data/skins/enhanced/user/mod_security.htmlModified:
/usr/local/directadmin/data/skins/enhanced/user/modify_domain.htmlto include a button when:
|*if HAS_MOD_SECURITY="yes"|pointing to:
/CMD_MODSECURITY?domain=|domain|



