Securing DirectAdmin

Secure DirectAdmin panel port 2222 with SSL

SSL is designed to keep an internet connection secure by safeguarding any sensitive data that is being sent between two systems, thereby preventing a third party from reading and modifying any information transferred, including protected personal information (PPI).

It's important to to use a secure connection for services and for the DirectAdmin panel itself: Secure DirectAdmin panel port 2222 with SSL

Security Questions or Two-Factor authentication after DirectAdmin login for an additional layer of security

To help increase the level of security with a DirectAdmin server, a feature was added which allows you to add questionsopen in new window or enable two-factor authenticationopen in new window after the login is already successful. These questions can be User specified, and any incorrect answer can then notify the User.

To enable the questions, or to add/modify the questions, log in as the user and go to:
Dashboard -> Change your Password -> Manage Security Questions

To enable two-factor authentication, log in as the user and go to:
Dashboard -> Change your Password -> Two-Step Authentication

The page also allows you to disable API access to the account using the same password used to login. Session Keys and Login Keys do not apply to this setting, as they're always allowed.

NOTE: Each failed 2FA/security question is counted in the 'failed_logins' file (where wrong passwords are counted). This means you must get a valid password and valid 2FA/Security Question within the "brutecount" limit, else you'll be put on the ip_blacklist (/usr/local/directadmin/data/admin/ip_blacklist), which is where IPs bruteforcing the DA login are blocked. To remove yourself from the blacklist, edit /usr/local/directadmin/data/admin/ip_blacklist and remove your IP from the list. You can also ensure you never become blocked by adding your IP to the file /usr/local/directadmin/data/admin/ip_whitelist.

Login Trigger changes regarding Two-step Authentication and Security Questions

Login triggers only trigger after both the user/pass login and 2FA are answered correctly. Previously, the trigger would happen after the valid login, before the 2FA answered.

Triggers include:

  • checking to ensure the task.queue is being processed (random)
  • check for old custombuild/versions.txt (random)
  • clear the data/admin/ip_access/ folder
  • add to "login history"

Two-Step Authentication

The feature allows any DirectAdmin account to require the Two-Step Authentication using a time-based code from a smart-phone app (e.g., Google Authenticator, FreeOTP, Authy, etc.)

Access this feature from: Password Icon -> Two-Step Authentication

Once you have a "Secret" created, scan the barcode into your Authenticator App in your smart phone. Enable the feature, and future logins will require the temporary code generated from the App, entered on a 2nd page after a successful user/password login.

You can also optionally create one-time use "Scratch Codes", which can be printed and kept somewhere safe.

These scratch codes are used as a backup, in case your phone is not available to generate the code. A scratch code is only valid for one use, then is removed from the list of codes. The scratch code can be entered into the same "Code" field when logging into DA.

Information on the importance of Two-Factor Authentication can be found here: in new window

Applicable directadmin.conf settings include the following:

twostep_auth=0|1   default 1
block_ip_after_failed_twostep_auth=0|1|2  default 0

Where twostep_auth=1 enables two-step authentication, max_twostep_auth_attempts=5 permits 5 authentication attempts via this feature, and block_ip_after_failed_twostep_auth is whether or not to block the IP after failing two-step authentication, where setting to 0 (the default setting) means that no blocking will occur, 1 means that a warning will be given to the User that their IP will be blacklisted on their last attempt, and 2 means that no warning will be given when blocked. Of course, enabling the IP blocking requires that you have Blacklisting turned on in your Admin Settings.

The twostep_auth_discrepancy value should be a positive integer representing the number of 30 second time slices you can be off by (before or after). So the default of 1 allows a code to be valid before 30 seconds before, and 30 second after the phone's timer is done counting down.

DA's "Test Code" button may show you a message about the code being valid, but for a different time. If, for example, you see the time discrepancy as "-4", that means your code expired 2 minutes ago.

If you can't fix your server's time, then change this setting to be "4" (positive 4), and DA will allow a wider range of -4 to +4 for logins. Also useful if someone's phone time isn't accurate.

The twostep_auth_trust_days=30 value represents the duration that a trusted cookie is allowed to live in the client's browser. A trusted device can be un-trusted on the CMD_TWOSTEP_AUTH page. This may make your phone sad, as the server would no longer be its friend.

Applicable DA User files:

Applicable DA User user.conf settings:


NOTE: Each failed 2FA/security question is counted in the 'failed_logins' file (where wrong passwords are counted). This means you must get a valid password and valid 2FA/Security Question within the "brutecount" limit, else you'll be put on the ip_blacklist (/usr/local/directadmin/data/admin/ip_blacklist), which is where IPs bruteforcing the DA login are blocked. To remove yourself from the blacklist, edit /usr/local/directadmin/data/admin/ip_blacklist to remove your IP from the list. You can also ensure you never become blocked by adding your IP to the file /usr/local/directadmin/data/admin/ip_whitelist.

Detecting and preventing brute-force attacks

A common method of gaining access over a server is to use a technique called a brute force attack, or dictionary attack. What the attacker will do, is use a script to try and log in to an account with every possible password combination. This tends to require tens of thousands of login attempts, but eventually, the right combination will be found, and they can log in normally.

To prevent this, we can use a brute force login detection system. DirectAdmin has 2 such systems for these attacks.

  1. The original feature was created in DA 1.25.5, and will detect and block login attempts on DA itself (port 2222): in new window

This feature only applies to port 2222. It only blocks IPs on this port. It does not block IPs from other ports.

To enable this feature, go to Admin Level -> Admin Settings -> Blacklist IPs for excessive login attempts use a value around 10-20.

  1. The newer system works in tandem with the previous, and will scan the logs for the other services (Apache, Dovecot, Exim, ProFTPd, SSHd).

When an attack is detected, DA will notify the Admins on the box that the attack is in progress.

DA will not block the IPs since that would require a firewall, and DA doesn't manage firewalls (see below).

To enable the detection reporting, go to:
Admin Level -> Admin Settings -> Parse service logs for brute force attacks

The brute force monitor (BFM) page can be viewed at Admin Level -> Brute Force Monitor.

Hide brute-force notifications

As brute force attacks are fairly common, and the tools to prevent those attacks are fairly reliable, some admins do not wish to be told about every case of attacks.

Since the trigger of the only happens with notices, I've added an option to prevent the sending of the notices, but still call the scripts normally to block the IP.

The directadmin.conf option will be:


which is the internal default (option disabled, notifications shown).

If you wish to prevent notices from being sent out, but still have the IPs blocked, then set this in your directadmin.conf:


All servers should be running some sort of firewall to prevent them, e.g., </operation-system-level/securing/firewall#i-need-a-firewall-what-are-my-options>

The purpose of this guide is to hide those Message System messages once you've established that your blocking system is working correctly. There are several options and levels to suppress the messages.

  1. If you want to hide the messages from the "Message System", but continue to be notified via E-Mail: in new window

  2. If you want to send the high-volume attack E-Mails to some different address, like, you can add a user.conf variable: in new window


Brute-force monitor page generates a timeout

If you get a timeout message similar to the one below when accessing the Brute Force Monitor (BMF) page CMD_BRUTE_FORCE_MONITOR:

Your connection has timed out.

Either your request was invalid or the program hasn't completed your request.
Please notify the server admin.

This is usually caused by an over-sized file /usr/local/directadmin/data/admin/brute_log_entries.list. Check this file to see if it's large. If it is, you can shrink it down, but only keep the entries at the end of the file (the end of the file has the newest entries).

cd /usr/local/directadmin/data/admin
mv brute_log_entries.list brute_log_entries.list.backup
tail -n 1000 brute_log_entries.list.backup > brute_log_entries.list
chown diradmin:diradmin brute_log_entries.list

Where you can increase or decrease the 1000 lines as needed.

Other possible affected file are the and Of these 2 files, it's more likely the is causing the slowdown, because attacks typically happen on many Users from 1 IP address. If you need to empty the file, type:

cd /usr/local/directadmin/data/admin
chown diradmin:diradmin

We wouldn't recommend emptying the because this is what counts the attacks per IP, and is what is used to determine if an IP should be blocked.

Prevent BFM from reporting specific email

If you're using the Brute Force Monitor (BFM) and 1) have an email address that is repeatedly checking your server, but that account is invalid (either a wrong password, or a non-existent account), and 2) you know that the person doing it is not malicious, but only stubborn for not updating their settings, then you can tell the BFM to skip that email address from being checked.

To do this, create the /usr/local/directadmin/scripts/custom/ script and add the following code:

if [ "$type" = "User" ]; then
   if [ "$value" = "" ]; then
       echo "exempt";
       exit 1;
exit 0;

Make it executable:

chmod 755 /usr/local/directadmin/scripts/custom/

Note that this will only prevent reports for users/emails being logged. It will not prevent the blocking of the IPs, as the IP could be "attacking" some other account as well.

Found an XSS or CSRF hole in DirectAdmin?

We get these reports on occasion, but DirectAdmin has had a referer checking tool for quite some time now: in new window

Since this was added, none of the external XSS/CSRF reports have been valid.

People who think they've found one often are testing with a form in the DA skin, on port 2222 on the same IP. This means the form is in the skin, which is exactly where it lives usually for its intended purpose. So of course, the form submission passes, as one would expect. So this test is only possible if they've got access to editing the skins, which means they've already got root access on your server, so the XSS test doesn't mean anything.

An external form, using any different variable, either IP or port will fail the check_referer=1 test.

In DA debug mode, a sample might look like this, where is the server IP, and we actually put the hacking test on the same IP. In real life, the attacking IP would typically be on a different IP, but that only adds one more thing for the referer check to find. This just proves that even just the variance in the port is sufficient to stop the attack.

This test has with any standard form you want, DA on, with the client IP being

Checking referer to
Referer check failed for See error.log

And from the error.log:

2016:03:31-15:49:00: Referer port (80) does not match DA's (2222):
2016:03:31-15:49:00: Referer check failed for

So please, before submitting your security report, please check to ensure that you're not actually testing your form in 2222, since that's where it's going to be valid. Test with your form on any different port or IP.

I wish to have a so I can block IPs through DirectAdmin

Starting from DirectAdmin version 1.61.0, the CSF integration is done directly. New installs will have CSF automatically installed and BFM autoblock covered if installation isn't customized to disable them.

Existing installations after updating to 1.61.0 could have direct CSF integration upon deleting previously installed plugin files.

To activate, remove the following files:


Brute Force Monitoring for xmlrpc.php

DirectAdmin v1.590

The xmlrpc.php, a file included with WordPress, is an API file used for data transfers or actions between various things.

A stand-alone setup often does not need web access to this file, but any external connections, like iPhone apps that routinely do POSTs to it generating a 200 return code would require it.

This is also one of the major attack points for WordPress, used in attempts to determine the website's WordPress password.

As a result, our Brute Force Monitor (BFM), when "Scan for WordPress attacks" is enabled in the Admin Settings, will scan for POSTs to this file with a valid 200 return code (wordpress2 brute_filter.list).

This change is to increase the match count, which would have been the same as the Brute Force Monitor's count limit (set in Admin Settings), to now be 8x that value, to allow for possible valid usage, while still blocking attacks.

For example, if you set your ip_brutecount=100, aka:

"Notify Admins after an IP has: [100] login failures on any account"

This would mean that any User would be allowed 800 POST with a 200 response code to the xmlrpc.php file, based on the BFM's rules.

Note that the BFM's time window is sliding and is entirely based on a period of time where there are no attacks counted in order to reset the count to 0.

So if you have the following set in your Admin Settings,

"Reset count of IP/User failed attempts: [4] hours after last attempt"

A period of 4 hours must pass where there are 0 failed attempts from this IP address in order for the count up to 800 to reset to 0.

If even 1 POST to xmlrpc+200 is done per hour, then the count will never reset, and the 800 limit WILL eventually be hit.

There are plugins for WordPress, which can monitor for such attacks, saving the need for DA to do it, such as WordFence.

It's ultimately up to a website to be protecting itself, as the "Scan for WordPress attacks" is simply there to be a fall-back in case the website owner failed to secure WordPress.

The /usr/local/directadmin/data/templates/brute_filter.list contains options:

wordpress3=ip_after=&ip_until= -&text=] "POST /&text2=/wp-login.php&text3=" 302%20&count_multiplier=4

What this does, is after all log parsing is done, the Brute Force Monitor will count how many entries were triggered for that item (e.g., wordpress3) for that given IP.

Say there were 20 triggers. The multiplier means that instead of having a limit of 100, that item needs 400.

The actual logic in DA is actually backwards, as the total count uses other items, so we actually divide the number of wordpress3 counts by 4.

So instead of 20 hits, the count only see 5 towards the total. This also means that if there are only 3 hits, then 3/4 = 0, so no count would be triggered for that IP.

The entries will still show up in the log list, but count for that given IP (top table) would be lower.

The whole purpose for this is that the entry:

POST /wp-login.php HTTP/1.1" 302

could represent an attack, but could also just be a normal redirection. So we do want to count it, but it should be of lower significance.

Custom blacklisted IP page

An optional custom template file exists here:
If that file exists and the client IP is blacklisted, this content type text/html page will be sent to the client, instead of the hard-coded: "Your IP is blacklisted".
Read more.

Last Updated: