Version 1.45.3

Released: 2014-06-30

Admin will override subdomain_owner_check new

Since an Admin has control over the setting anyway, DA will now ignore the subdomain_owner_check for any Admin actions.

This will apply to User/Reseller creation by an Admin account, and will also apply to the restore of accounts from the Admin Level.

If an Admin restores an account from the Reseller Level, this override will not apply, the check will be done.

Ability to force no sorting in a table new

Table sorting is specified by sort1=N where N is a number greater than 0, or less than 0, but not 0.

The number represents which column, and negative means descending.

Change allows sort1=0 (or sort2), which makes the table skip all sorting, which could speed up the page load if it's got many entries.

If no sort1 value is passed at all, it will revert to the default, which is often sort1=1 (but there are sometimes other defaults, depending on the tables)


Since CMD_API calls usually mirror CMD_ calls, the command:


had the API:


with an "S" at the end, which could cause confusion.

I've added an alias:


so that both CMD_API_SUBDOMAIN and CMD_API_SUBDOMAINS will work.

New log file: login.log new

In addition the the error.log, errortaskq.log, security.log, a new log has been added:


It will follow the same rules as for the other logs.. meaning, if you've already changed the logdir= variable, it will follow that path.

Also, if you use syslog for logging with the use_syslog, the "priority" is set as:


The messages will look like this:

2014:05:08-01:40:09: '' 15 failed login attempt on account 'test'
2014:05:08-01:40:09: '' 16 failed login attempt on account 'test'
2014:05:08-01:40:09: '' 17 failed login attempt on account 'test'
2014:05:08-01:40:09: '' 18 failed login attempt on account 'test'
2014:05:08-01:40:09: '' 19 failed login attempt on account 'test'
2014:05:08-01:40:13: '' successful login to 'test' after 19 attempts

Where all failed attempts are logged into the login.log, as well as the single successful login

It does not log each navigation/click once the login is already done.

The difference between this, and what the security.log already has, is that it will login all failed attempts, while the security.log only starts logging after the alert threshold is hit.

DA will check for login.log in the file /etc/logrotate.d/directadmin, and will copy the new file to that location if it doesn't exist.

For FreeBSD, it will add the required entry into the /etc/newsyslog.conf.

The log is also added to the data/templates/logs.list.

With regards to the Brute Force Monitor (BFM) the default rest time of 120 seconds has been increased to 1200 seconds (20 minutes), which is the amount of time from the last attempt before the failed login count is reset.

For "Login As", it will show up like this:

2014:05:08-02:12:34: '' 4 failed login attempts. Account 'test' via 'admin'

2014:05:08-02:12:37: '' successful login to 'test' via 'admin' after 4 attempts

For Auth Basic / API logins, it will look like this, as well as the login-as:

2014:05:08-02:22:28: '' successful Basic Auth/API login to 'test'

2014:05:08-02:22:54: '' successful Basic Auth/API login to 'test' via 'admin'

Support up to 4096 bit key for SSL certificates (SKINS) new

In addition to 1024 and 2048 bit keys, a new size is now available:




Plugins to have the ability to run as a specified User new

Previously, a plugin would always run as the User that is calling it.

This was simple and secure, but proved to be an issue for some plugins that required access to different areas of the system, as they wouldn't have sufficient privileges.

A new default directadmin.conf option will be present, and this is the internal default for that option:


so if you do not wish to allow plugins to set different User values to run as, set your directadmin.conf to have:


*** SECURITY IS ENTIRELY UP TO YOU, the plugin designer ***

As for plugin coders, if you wish to set any level to run as a specific user, you'd add any of these options to your plugin.conf file:


where you can set "user" to any value you wish, as long as it's not uid=0.

Meaning, DA will actively do a check the /etc/passwd file for the uid, to ensure you didn't create another non-root User with uid=0.

For any line that is not there, DA will run as the User that is logged in to DA, just like plugins already do.

This means that existing plugins will still work fine.

A side-benefit of running a plugin as one account (which nobody else has access to), is you can much more easily setup an suid binary with 4750 root:user, so that no other account can call it, making security much easier, while still allowing root access via the suid wrapper.

Other benefits would be a common user for reading or writing a plugin data file, as needed.

However, if you set a level to run as that User, it also means that the plugin, at that level, will no longer be running as the account that's logged in...

so this feature wouldn't apply to any User Level plugins that need to write to /home/username for the current account.

NOTE about environmental variables:

New variable:


will be the value that the script is running as.

As well:



will remain unchanged as the normal values of the current account, and they will not reflect the username that the script is running as.

If you need the Admin Level account have access to a specific system account, as well as another account, or it's own account, you can blend the plugin levels to have different Users.

For example:


If you want Admin and Users to have access to files created by the plugin, but the the Admin could call CMD_PLUGINS_RESELLER to be running the plugin as themselves, for other local data under /home/admin, for example.

Of course, you'd want the Reseller Level plugin to double check that the current account is indeed an Admin, or you might have some confused Resellers.

In any case, the mix and match method just gives you more options to run the plugin in different ways.

Try to leave the more dangerous levels of access to Admin accounts only, in case you have a code bug, giving Resellers or Users access to things.

SHA-256 for certificates (SKINS) new

Ability to create both self-signed and certificate requests of the type SHA-256 (SHA-2)



currently only in "enhanced". Add to power_user and default once tested.

add below the bits:

<tr><td class=list>&nbsp;</td><td class=list>Certificate Type</td><td class=list><select class=selectclass name=encryption><option value="rsa" selected>SHA1</option><option value="sha256">SHA256</option></select></td></tr>

Message System, Manage Tickets, Plugin Updates, Licenses/Udpates to show count box (SKINS) new

New green count boxes with the number of new items to address or update.

May require a ctrl-F5 for stylesheet css reload.

They will replace the "(12 new)" texts for "Message System" and "Manage Tickets"

Boxes will be hidden if there are 0 items/counts.

For plugins and licenses/updates count display, it uses ajax to fetch the counts, so you must turn that on in the directadmin.conf if you want to see those counts:


and restart DA.


The plugin count goes through each plugin, and determines if a different version is available, which adds +1 to the plugin count.

The Licenses/Updates count checks for a license in it's grace period, or for a new version of DA. Each add +1 (max = 2 for this one)

There will be a cache file for each plugin for the current version, so this change doesn't DDOS the plugin authors with this on their version_url.

Each load of the plugin page will write the cache file, regardless of it's time.

Loading of the ajax to look for updates will use the cache if it's not expired.

It will update if it is.

The file will be here:


where plugname is replaced with the plugin name.

A new directadmin.conf option has been added to specify the amount of time, in seconds, that one of these ajax cache files is allowed to live.

The internal default is:


(30 minutes)



added class .count_notice for green highlight


ajax changes for plugin count and license/updates

span changes for manage tickets count


span changes for manage tickets count


span changes for messages count


added new function:

function set_admin_level_updates()

Changed default numservers=10 for new installs new

Default changed from 4 child process to 10 for new installs.

With more css, js, images, it will reduce the chance of running out (even though DA does spawn more as needed, up to 20)

Plugins to be allowed to set a timeout new

The default timeout for a plugin is 10 * timeout (Admin Settings).. so usually 600 seconds, or 10 minutes.

If a plugin needs more time, they can set:


in the plugin.conf to allow a higher value for the alarm() function.

The maximum value is 4294967295, from UINT_MAX.

The value must be greater than 0, as unlimited is not allowed.

Just as example, 4294967295 seconds is 136 years.. so your not likely going to want a value that high.

Set a number that's comfortable enought, but doesn't last forever, else you may end up with hanging directadmin child processes, waiting around for a plugin to run for 136 years.. and eventually clogging up everything, preventing you from logging in.

At most, I'd say one or two hours should be sufficient for most cases.

Better pipes for plugins new

  1. Previously DA only listened for stdout from a plugin, and stderr went nowhere.

Now, stderr is piped to /dev/null. (make sure all your errors are stdout if you want to read them)

  1. When DA forked the to the child process, before the exec for the plugin script, the socket to port 2222 wasn't opened.

For most plugins, this wouldn't be a problem.. but the issue arises when the plugin wants to spawn it's own background process with setsid();

Although DA did return all output and DA closed the client pipe, it wasn't actually closed to the client because the child was still holding it open.

Fix was to close the 2222 pipe after the fork, in the child process, before the plugin was called with exec.

  1. The main directadmin process will now re-direct stdout/stderr to /dev/null.

Previously, they were just closed, which could in theory cause issues if any script or child process were to output text that DA wasn't reading in, as it would eventually fill the buffer.

There will be a new internal directadmin.conf value, the default is:


If you want to see if there is any output, you can add the value to the direcatdmin.conf, eg:


it will have root write access.

There really shouldn't be any output, but it could be possible for errors from programs that DA isn't capturing.

Random passwords now have a random length new

New directadmin.conf option:


where 10 is the internal default.

Any randomly generated password will now be a value between 8 and 10 characters long, to improve difficulty to guess.

Applies to both the javascript generated random passwords, and also the ajax generated passwords.

New token is also available:



Option to specify length of the gernated random passwords (SKINS)



in function function random_pass():

var length_min = |RANDOM_PASSWORD_LENGTH|;
var length_max = |RANDOM_PASSWORD_LENGTH_MAX|;

var length = Math.floor(Math.random() * (1 + length_max - length_min)) + length_min; 17 and updated exim.conf (Manual changes) new

Changes to the and exim.conf.

You must update BOTH your, and install a new exim.conf.

For the exim.conf updates, check your current version, and if you have 2.1.1, you can patch it to 2.1.2.

You can patch from 4.2.1 to 4.2.2.

If you are jumping verions, eg, 2.1.1 or older to 4.2.2, then do a fresh install of 4.2.2.


New version 17:

  1. This version fixed the "off-by-one" issue, where Users could send 1 more email than they were allowed.

  2. Added support for an limit check during ACL (requires new exim.conf) to more accurately gauge the count.

It will also stop returning a failed password at limit, and instead return the actual "too many sends" message, which is less confusing.

New exim.conf 4.2.2

to support the ACL checks,

but also has 2 more ACL checks to:

  • drop connections sending from postmaster@ to more than 1 recipient (should never happen)

  • drop connections where 3 or more recipients are invalid.

  • deny ymlf-pc HELOs

  • clarify rbl block reasons

If force_hostname is used, set that domain in message/ticket notifications new

Previously, this guide would be needed to change the domain value of a ticket/message email:

With this change, if the force_hostname option is used:

Ability to force which hostname is used when accessing DA

then DA will set that hostname in the |DOMAIN| token in those emails. to know if there were errors new

Relating to this script:

The has been given 2 new environmental variables:

success=1|0                      # 1 meaning all is well, and 0 meaning there was an error somewhere.
current_result=string          # which will contain a string that DA will output in the notification.. could be blank (although not likely)

Added roundcube and squirrelmail to the BFM new

Changes to DA to allow it to scan:



for login failures, and the BFM will track the User/IP doing the attack.

Changes made to:


roundcube1=ip_after= from &ip_until=. AUTHENTICATE PLAIN&text=IMAP Error: Login failed for&user_after=IMAP Error: Login failed for &user_until=%20from%20
squirrelmail1=ip_after=) from &ip_until=: Unknown user or&text=: Unknown user or password incorrect.&user_after=\[LOGIN_ERROR\] &user_until=%20(

In order for SquirrelMail to log it's failed login attempts, the squirrel_logger plugin must be installed.

CustomBuild 2.0 currently does this by default, but requires you to re-install squirrelmail:

cd /usr/local/directadmin/custombuild
./build update
./build squirrelmail

If you have CustomBuild 1.2 or 1.1, this is related:

cd /var/www/html/squirrelmail/plugins
wget ''
tar xvzf squirrel_logger-2.3.1-1.2.7.tar.gz
cd squirrel_logger
cp config_example.php config.php
cd ../../config

Type 8, then enter for plugins.

Type in the number of the squirrel_logger, and press enter to activate it.

Press "S" to save, then "Q" to quit.

catch proftpd requests for task.queue when pure-ftpd is being fixed

In various areas of DA, such as restores, a reload or reread of proftpd may be requested, via the task.queue.

If you're running pure-ftpd, then we'd have no reason to see the proftpd commands there.

The change will swap the "proftpd" action with "pure-ftpd".

A secondary check will be run, such that if pure-ftpd reload or reread are called, they're ignored.

An HUP sent to pure-ftpd will kill it, as it does not use HUP in the normal fashion.

This does not affect the action=rewrite&value=pureftp_db calls.

Hidden button "Update disk usage" was broken (SKINS) fixed

When viewing a domain at the User Level (main domain page), the right bar shows basic stats about the User.

Related feature from 1.33.1:

Disk Usage update link at User Level (SKINS:lang)



Changed it from this:

<a class=tabtext href="javascript:onClick(document.updateform.submit());" title="|LANG_CLICK_TO_UPDATE|">

to this:

<a class=tabtext href="#" onClick="document.updateform.submit();" title="|LANG_CLICK_TO_UPDATE|">

Occurred 3 times, once in the php/script for the usage bar, and then twice more (once for each <td> in the table)

DA thinks it finds Roundcube 0.1 for 1.0.1 and chmods to 0 fixed

During an update, DA does a string check and throws this error:

Subject: A system issue requires your attention Today at 14:59

Roundcube version 0.1 has been found your system.

The locations on disk are within /var/www/html in the folder(s):


These locations have been disabled by means of chmod to 0 for security reasons.

Please update roundcube to 0.2 or higher and remove any old versions.

resulting in a disabled install of RoundCube.

The if roundcube is chmod to 0, run the following as root:

chmod 755 /var/www/html/roundcubemail-1*

DDNSSEC showing expiry for some formats fixed

In our testing, the RRSIGN SOA looks like this:

14400 RRSIG SOA 5 2 14400 20140611201156 (

20140507201156 62883

14400RRSIGSOA 5 2 14400 (

20140619074628 20140515074628 1077

Where the expiry is before the signed date in both cases, but the 2nd case has the expiry on the next line.

Parser had to be changed to account for this possibility.

Change default connect_timeout to 20 and drop expired pre-connections fixed

Relating to this change:

Change default connect_timeout from 5 to 10 seconds

and this error:

Your connection has timed out Details: No input given before connect_timeout reached

It means that Chrome (or any browser that pre-connects) was holding open idle connections, but the connection timed out.. and chrome tried to use them for subsequent requests, when DA had already sent that text.

Two changes have been made:

  1. The new internal default for connect_timeout is now 20 seconds (from 10)

  2. If such a pre-connect timeout occurs, no output will be given at all. The connection will simply close, which is what should have happened before.

The previous error (above) should not happen, because if Chrome tries to use the connection by sending a request, the error is output, making chrome think that was the correct output.. when it's not. The change to drop the connection with 0 output is how we tell Chrome to try again with a new connection.

I believe this was the cause of some randomly occurring half-loaded images or pages (although not confirmed)

With the cache enabled, most people wouldn't notice that anyway, as 1 more click and the proper file is completed.

Add "dns" to backup_options.list fixed

If "All Data" is selected, then "dns" is included in the backup_options.list.

If a custom data items are selected for a backup, "dns" is not in the backup_options.list, even though the is always backed up.

Fix simply adds "dns" to the backup_options.list, in the even a custom list of options is selected, as dns is always in the backup.


If you do need to restore the dns for a given "custom item" backup, then use this guide to re-pack your tar.gz file:

and for step 2, edit:


and add:


and follow step 3 to repack it, then restore.

Only restore domains in the backup fixed

Previously, the list of domains to be restored was taken from the combination of the live domains.list and the list of domains in the backup.

This would throw errors (which could be ignored) if a live domain was already in the User account, but was not in the tar.gz, since DA would try and extract something that wasn't there.

Another change was to have better limit enforcing of the domain count during the restore.

output from and to be displayed fixed

Regardless of the exit value for the and, it's output would have only been shown if there were some other errors which happened before the script was called.

This change it to display any output from the script, regardless of it's exit code (it's exit code isn't checked anyway, as there is no point since everything is already completed)

Although, if a non-zero value is output, the string "Script Output" is used before your text.. but a 0 value will only output your text.

A side-effect may be that if other non-critical warnings were added in the class, they may be displayed as well, when they previous were not.

I've not yet hit any of those messages.

Last Updated: