Version 1.56.1

Released: 2019-04-08

Add the php binary path to cron PATH new

April 9th:

UPDATE: bug with this feature.

Changed default to:


where $PATH varible is not valid in crons, making PATH=/anything/:$PATH invalid.

1.56.2 should released shortly today with a fix.

Clients will often try to use "php" in their cron commands.

It's recommended that they use the full path, which is guaranteed to exist:


However, with the php selector, their website is allowed to use the 2nd (or 3rd, 4th) php version.

Using /usr/local/bin/php would only use the 1st php version.

This feature would automatically set the cron PATH to be (for example):


New internal default directadmin.conf value, enabled by default:


to disable, add this to the directadmin.conf and restart directadmin:


If they've chosen php 7.1 on their default domain.

This lets them use "php", which should be found.. and also is more portable, since you can change php versions, and it should update the cron PATH automatically.

This way, both the website and it's related cronjobs use the same php version.


DirectAdmin will only set the path to include /usr/local/phpXX/bin in certain scenarios.

One of:

  1. PATH is currently empty, or blank

  2. PATH already has /usr/local/bin/phpXX, but must be first in the list.

if none of the above are true, then DA will not set, nor update the list.

For example, DA will not touch this, if it's set:


because /usr/local/phpXX is not first in the list.

However, if you have any of:


Then anytime the User changes their selected php version at:

User Level -> Domain Setup -> -> php selector

DA will swap this first php72 value with the newly selected php version.


Because cronjobs are per-User, and not per-Domain, only 1 php path can be used.. hence we've opted to set the php version PATH to that of the main/default domain of the User account.

If a 2nd domain requires some other php version, the client can manually specify it, eg:


instead of "php".

Not done: Also add to /home/username/.bashrc for ssh (if it's clean enough to do so)


fallback path for mysqldump new

In the event that DA cannot find the mysqldump path for your given OS,

DA will fallback to try various other common paths for mysqldump.

For most DA boxes, this won't be used, but some where packages are manually installed/maintained, this can be useful.

Ability to shut off certain features of the File Manager new

New internal default for directadmin:


and then each feature will have it's own bit (assignment to be determined)

For any feature you wish to disable, simply add that bit to the decimal number.

Defines are as follows:


#define FM_F_RENAME 2

#define FM_F_COPY 4

#define FM_F_RESET_OWNER 16



#define FM_F_EDITABLE 128

#define FM_F_EXTRACTABLE 256

#define FM_F_DELETE 512

#define FM_F_CHMOD 1024

#define FM_F_MKDIR 2048

#define FM_F_CLIPBOARD 4096

Added in 1.60.0:

#define FM_F_UPLOAD 8192

#define FM_F_DOWNLOAD 16384


which related to the API flags returned for given filenames.

The same flags will be used for this feature.

For example, to fully disable directory proection, set:


to disable rename and copy, add them together:


If you only want "protectable" enabled, then add everything, less 1.


(8 currently unused.. can add it if you want to future-proof if we ever use it)


Internally, each number has it's own bit position, so all settings can be stored in 1 number.

Note: FM_F_CLIPBOARD was added in DA 1.56.3.


Realtime system quotas new

The nightly tally will add things up, just as it did before, but also store a lower total usage count that excludes the system quotas (but still includes databases, and other non-system-quota items)

This then allows DA to count system quotas on the fly (which returns the count very quickly), which can be added to this lower number, for a more accurate usage count for each load of a page in DA.

This only applies to the usage shown to the User, while they're logged in. It does not update the Show All Users, or List User pages, nor does it write to their user.usage with the update value.

for now, disabled by default to confirm functionality, internal directadmin.conf default:


To enable kernel-level quotactl function calls, set it to 2:


For more slower binary "quota -v username" calls, use:


but for most cases where possible use 2 as it's far quicker without external calls.

Note, DA needs the device names to pass to the quotactl call. This is done with the "mount" program, but for efficiency purposes, this is only done once at startup in the master process.

This means, if you make any changes to your partitions/quotas, be sure to restart DA to get an updated mount list.

Inode counts are also updated in realtime with this turned on.



Use realtime_quota=2 when possible

FreeBSD often does not have quotas compiled into the kernel, if that's the case, you cannot use 2.

However, if that's the case, then you might as well stick with 0, as it's probably a nighly quotacheck cron anyway, so you'd gain nothing from realtime quotas.

Tested back to FreeBSD 9, for my cases, 1 was the best that worked.

CentOS 5 "quota -v user" does not support "no-wrap" -w, so you must use 2.

CentOS 6 is fine for both 1 and 2, but the quota command does not support --show-mntpoint, so DA uses the block device lookup, which should already be cached anyway for the 2 mode.

But use 2 for CentOS 6 when possible.

Debian 7+ works for both cases.



Use php-fpm.conf ACTIVE_USR_LOCAL_PHP_LIB by default (TEMPLATES) new

Related to recent new token:


in the php-fpm.conf template:

php-fpm.conf to support ACTIVE_USR_LOCAL_PHP_LIB token

This release will swap the line entirely to use the token.

Old value: |?OPEN_BASEDIR_PATH=`HOME`/:/tmp/:/var/tmp/:/usr/local/php`PHP_VER`/lib/:/usr/local/php54/lib/:/usr/local/php55/lib/:/usr/local/php56/lib/:/usr/local/php70/lib/:/usr/local/php71/lib/:/usr/local/php72/lib/:/usr/local/php73/lib/:/usr/local/lib/php/|

New value:


Global: never_commands new

New internal directadmin.conf setting:


being fully unset to anything.

The feature allows you to add any CMD_ to this variable, colon separated, so it can never be used on this DirectAdmin server.

For example, if you want to fully prevent the creation of any new Admin account, you can add this to the directadmin.conf:


in the directadmin.conf.

This is similar to the per-user commands.allow and commands.deny files, which could do this same thing for this example..

However, the feature is global, so it would apply to all accounts, and saves needing to setup the commands.deny multiple times.

Support for MySQL 8.0 new

Relating to this feature in 1.56.0:

MySQL: new user methods: ALTER USER, DROP USER, etc. (SCRIPTS)

which was for MariaDB 10.3,

this new change extends those changes to also cover MySQL 8.0, with regards to User creation.

Requires the use of:


in the directadmin.conf.


php-fpm check before sending to AddHandler (TEMPLATES) new

If you access a php file through apache/php-fpm, but it does not exist, this will throw:

No input file specified


File not found.

A simple solution is to not pass it to php-fpm if it's missing, and let apache throw the usual 404 from the website's setup.

To accomplish this, a simple <If ..> check tag can be added around the AddHandler in the VirtualHosts, to look for the REQUEST_FILENAME variable.

|*if HAVE_PHP1_FPM="1"|
<FilesMatch "\\.(inc|php|phtml|phps|php|PHP1_RELEASE|)$">
#ProxyErrorOverride on
AddHandler "proxy:unix:/usr/local/php|PHP1_RELEASE|/sockets/|USER|.sock|fcgi://localhost" .inc .php .phtml .php|PHP1_RELEASE|

as per the documentation here, in the "Proxy via handler" section:

Credit to zEitEr on the forum for finding/posting the solution:

Rspamd: task.queue config rewrite new

Ability to rewrite one or all Users' .conf files in:


via the task.queue


Command for one User:

echo "action=rewrite&value=rspamd&user=USERNAME" >> /usr/local/directadmin/data/task.queue

where USERNAME is set in lower case, to the User you'd like.

Only does anything is user_prefs is present.

Running the dataskq in debug mode will help if anything isn't writing, for whatever reason.

Command for ALL Users:

echo "action=rewrite&value=rspamd" >> /usr/local/directadmin/data/task.queue

CustomHttpd: php-fpm: save to all php versions (SKINS) new

New checkbox on the custom php-fpm config page:

Admin Level -> Custom Httpd Config -> php-fpm XX

that shows:

[ ] Save for all PHP versions

beside the [ Save ] button.

When checked, the CUSTOM1/CUSTOM2 tokens will be saved to the php-fpm customX files, for all active php versions (as set in the options.conf)






The php-fpmXX.conf is only written for the active/selected php version.

When a User changes their php version via the Domain Setup php selector, the custom changes set by the Admin would apply through all versions, without the need for another set of the custom settings.

Get new messages/tickest from a previously assembled count. new

Each page load would previous count the number messages and tickets sent to an account from the tickets.list.

This could be slow if there were many messages.

Design change to save the current count of messages to the ticket.conf for that User, for both messages and tickets when a message is being saved to this account.

When the next page load happens, the the .conf can much more quickly read in the numbers.

Also added new global tokens:


which reads the current account's creator's ticket.conf file to check the active=yes or not.




The TIMEZONE is the name of the timezone.

TIMEZONE_OFFESET is in seconds, so /3600 for hours.

The values are taken from:

localtime_r(&now, &t);

User Level: Restore: Dns used remote IPs new

Relating to changed done here to support restore of a multi-domain IP with the same values:

Restore: additional IPs for Users and domains

it introduced a bug at the User Level, such that the restore did not swap the old multi-domain list of values to the new list.

An extra check was made when a User Level restore is done to add a domain, to ensure the local IPs exist in the user_ip.list file, when assembling the IP conversion list.

If it's missing, it will default to the usual "new IP" value, typically the ip from the user.conf.

MX Templates: Other record types, extra SPF, ~all types (TEMPLATES) new

Extension to the recently added MX Templates feature:

MX record templates (SKINS)(TEMPLATES)

Added support for any DNS record type (tested with A, CNAME, SRV, MX)

Changes also allow for on/off switch on the "Local Mailserver" checkbox, automatically, eg:


inside the .txt template files.

The EXTRA_SPF is inserted to the end of the v=spf TXT/SPF records, before the ~all/-all/?all.

The SPF_STRICT allows setting the desired enforcement level.

All 3 default mx templates now use:


When selecting a different template of reverting back to the default,

DA will first load in all templates and compare the first MX record to see if it's listed in any of the templates.

This lets determine which template is actively being used (exact match)

With that being known, DA can scan the current zone for required changes,

including removal of all listed records listed in the template.

It will also revert to the default SPF back to the default dns_txt.conf / dns_spf.conf, and redo the adding of the next template into it, where applicable.

The Local Mailserver option (LOCAL_DOMAIN=no|yes) will use the currently selected templates's LOCAL_DOMAIN setting to decide if any change should be made.

Note: if the new template is unset, then it's possible the value won't be altered.

But the "default" template will always turn it back on.

If you create a new template, it's best to set the LOCAL_DOMAIN variable as needed, so DA doesn't get confused as to what to do.


which uses a dash instead of the periods, used in office365.


New template file:


with contents:

|?NAME=Office 365|
autodiscover 3600 IN CNAME
lyncdiscover 3600 IN CNAME
msoid 3600 IN CNAME
sip 3600 CNAME
_sip._tls 3600 IN SRV 1 100 443
_sipfederationtls._tcp 3600 SRV 1 100 5061

CMD_JSON_VALIDATE: type=ip_range_list new

New json validation for IP range lists.

Specifically created for Login Key IP validation.


value=<range list>

where <range list> can be a list of IPs (IPv4, or IPv6 if enabled), one IP or IP range per line, separated by a new line character.

Sample valid list:

Valid returns:

    "success": ""

Error returns:

"error": "&#49;.&#50;.&#51;.&#52; is not a valid IP or range<br>\"

where A.B.C.D will be html encoded to &#49;.&#50;.&#51;.&#52;.

Custom Php-FPM: per-User global php CUSTOM tokens (SKINS) new

With the more common use of the php version selector, you may want your custom php-fpm configs to span all php versions.

2 new textareas in the Custom Httpd Config -> php-fpmXX page for "global php-fpm CUSTOM1" and "global php-fpm CUSTOM2"

When you save data into either of these fields, the CUSTOM1/CUSTOM2 tokens set to span all php versions that the User may select from.

The bottom 2 boxes, as before, will only apply to that given php version.

There is also the "save to all php versions" which copies your data to all custom tokens for each php version:

CustomHttpd: php-fpm: save to all php versions (SKINS)





which will be set into the CUSTOM1/CUSTOM2 tokens before the php-fpm73.conf.custom1 files (for example).

But both global and per-php, if present, will end up into the same token.



2 new textareas, added before the per-php tokens:

<textarea class="code_edit" cols=160 rows=4 wrap=off name=global_custom1>|GLOBAL_CUSTOM1|</textarea>
<textarea class="code_edit" cols=160 rows=4 wrap=off name=global_custom2>|GLOBAL_CUSTOM2|</textarea>

CMD_DOMAIN: action=modify: single value endpoint new

When modifying a domain, sometimes you really don't want to have to read in all variables for that domain, as the:


requires all values to be passed, anything missing (checkbox) is assumed to be off.

This change allows you to specify just the item you wish to modify.

For example, to only affect the ssl checkbox, post modify like this:

method: POST
ssl=ON | full omit the ssl= value for off.

Similar can be done for:


with their associated values.

The same code in DA is used, except each check/set is now surrounded by an "if" statement for that value.

By default, they're all turned on.

If only_affect= is set, they're all turned off, and only the value set is turned back on and checked/set.

DNS Restore: use highest serial from the merge fixed

If the serial in the backup zone is higher than the existing zone's serial, use the backup serial as the starting point.

Login Keys with Evolution denied /assets fixed

If you were using a restricted login key with the Evolution skin (where the commands are restricted by any amount), the /assets path would have been blocked since it's not one of the /CMD or HTM command, etc..

This fix will include /assets, /user, /reseller, and /admin routes, should the "Allow HTM" option be enabled in the Login Key.

CustomHttpd: Php versions needed decimal place fixed

Recent changes to DirectAdmin to support 4 php versions resulted in changing the code to do loops for the number of php versions, rathern than 2 hardcoded variables.

One part of the change was how the list of php versions was return, which was a list of doubles, instead of strings, and the return of "7.0" was not forcing the extra .0 to the string, so "7" was used in some areas.

This included clicking the (php-fpm 7.0) link on the CustomHttpd Config page, where clicking it would show the error:

"Cannot find that php version in the list of php-fpm instances"

because the internal list didn't contain "7.0", which was being requested.

A simple %.2f solved that.

Don't throw error if User is deleted mid-backup fixed

Related to previous change:

Don't throw error is User is deleted mid-backup

this extends the checks to also not throw an error if the User is deleted after they've been started.

Only applies to:

Select: All Users


Select "All Users except Selected"

If a specific user is requested to be backed up and is deleted mid-run, then an error will be thrown.

The error strings will still be included in the Message System reply (if valid backup replies enabled), however, an error return code won't be set, so the subject would say there was no error.

Threshold notices not going out fixed

Bug with this new feature:

pre script for overusage:

prevented the User quota, bandwidth, inode overusage notices from going out when the User reached 80% (or whatever limit was set)

Temporary work-around is to grab the pre-release binaries, which already has the fix:

RSPAMD: writing the user_prefs found wrong spamd number fixed

If you have rspamd.. but do not have spamd (SpamAssass), DA cannot determine the spamd version.

The old default would end with VERSION3=no.. which was not correct (rspamd wants the v3 versions of the user_prefs)

This change converts the internal default to VERSION3=yes for the user_prefs template.

If spamd is found, and if the first by of the version is 2, then VERSION3=no will be set.

If you already have rspamd, you may want to confirm if your:


files.. and you're looking for v3 settings:

required_score ...
rewrite_header subject ...

and not the v2 settings:

required_hits ...
rewrite_subject ...
subject_tag ...

If you do see the v2 bits, then re-save your user_prefs through the User Level.

This should reset the user_prefs... and the will then be able to properly find things like the "rewrite_header subject" lines from the user_prefs.

The result of the bug meant the subject **** SPAM **** was instead loaded with "" so spam wasn't tagged as spam in the subject line.

LetsEncrypt: All requests to background fixed

Relating to locking, and often large LetsEncrypt requests, all have now been moved to the background.

Relates to this locking feature:

Basic locking for LetsEncrypt requests

Other non-LetsEncrypt requests will still be foreground calls.

The change simply alters the behavior of background=auto, such that it's no longer just wildcard certs in the background, it's all LE requests.

Last Updated: