Version 1.59.2

Released: 2019-10-21

Domain Pointers option to receive duplicate dns entries from master domain (SKINS) new

If you have main User, and it has Domain Pointer below it, this feature would mean that any record added to through the API or GUI would added to

There will be a checkbox both at the top of the "Add Domain Records" table, as well as at the bottom of the "Delete Selected" table.

This only applies to the User Level DNS Manager, as the Admin Level feature is more of a raw-zone type feature, and the actual User domains might not actually exist locally anyway.

When adding a value where the left-side is in the full form, eg:  A A

DA will automatically swap each pointer's call to use the left-side: A A

The right-side value is not adjusted, so if you're setting to use say, the will also get


The feature itself is always on, but if you wish to change the default for the checkboxes to be unselected, set:

./directadmin set dns_affect_pointers_default 0

and when it's set to 1 (which is the internal default), the 2 checkboxes will be checked by default.


The CMD_DNS_CONTROL page will now get this token, representing the dns_affect_pointers_default=1|0 setting:


DNSSEC (DS records) would be a per-domain setup.. so they will not not be synced.

DKIM: should be fine to duplicate, since the dkim key files are shared via /etc/virtual/ -> symbolic link.


The code that writes the pointer's zone will now check for it's master domain's ttl_override setting in the data/users/username/domains/ file, since the pointers know which domain they're under.



user/dns_mx_control.html #changes here are very similar.




<input type='checkbox' name='affect_pointers' value='yes' |DNS_AFFECT_POINTERS_CHECKED|> Remove From Pointers


<input type='checkbox' id='affect_pointers_checkbox' |DNS_AFFECT_POINTERS_CHECKED|> Duplicate to pointers

Each of the "Add Record" forms includes:

<input type=hidden name='affect_pointers' id='a_ap' value='|DNS_AFFECT_POINTERS_DEFAULT|'>

which is updated on each form's submission:

<form action='/CMD_DNS_CONTROL' method='POST' onsubmit="return set_affect_pointers('a_ap');">

and the JS lives in


function set_affect_pointers(hidden_id)
  var checkbox = document.getElementById('affect_pointers_checkbox');
  var hidden_input = document.getElementById(hidden_id);
  if (checkbox.checked)
    hidden_input.value = 'yes';
    hidden_input.value = 'no';

  console.log('hidden value has been set to: '+hidden_input.value);
  return true;


gzip compression on 2222 data transfers new

Add gzip compression for transfers on port 2222.

Duplicate entry. see:

gzip compression on 2222

Plugins can add level menus in Evo (PLUGINS) new

The calls to:


will now include an item called:


below each plugin's array, if that plugin created a given menu file..

This will be used to add entire menu sections at the Admin, Reseller and/or User Level menus, say if you want to add many features yourself, instead of just the single URL to your plugin.


To enable a menu for the given level, in the plugin.conf:


where you can adjust the path to whatever you'd like.

Absence of a menu_* line will prevent it from showing up in the json output.

To setup a menu, place it in the matching path from the menu_*= setting.

Again, it does not need to be admin/menu.php, it can be whatever you want.





example, for the CMD_PLUGINS_ADMIN?json=yes call:

    "additional_menus": "CMD_PLUGINS_ADMIN/hello_world/admin/menu.php",



Should be JSON output, at the moment, please use this formatting so Evo can create it correctly:

    "name": "Plugged User Menu",
    "icon": "",
    "entries": [
        "href": "",
        "name": "",
        "icon": "",
        "newTab": true,
        "updates": 1
    "name": "Second Plugged User Menu",
    "icon": "",
    "entries": \[
        "href": "",
        "name": "another menu item",
        "icon": "",
        "newTab": true,
        "updates": 0
        "href": "https://localhost:8080",
        "name": "localhost",
        "icon": "http://icon.does.not.exist/icon.png",
        "newTab": false,
        "updates": 2


gzip compression on 2222 new

New internal default directadmin.conf option:


If you need to disable it:

./directadmin set da_gzip 0

service directadmin restart

This feature will add chunked gzip compression to static files generated by DA.

Slower connections will greatly benefit from this feature, and faster connection will see a slight speed improvement.

The main benefit is resource size.

For example, the /assets/app.js is 1.9MB, but with da_gzip=1

it's shrunk down to 378KB, to just 20% of the original size.

Currently the requests that will get gzip compression, if the browser mentions support would be:

/assets/*    # excluding /assets/lang

All log downloads (Admin Level -> Log Viewer, User Level Logs, Login Key Logs, etc.)

Email/FTP password change tool html

Plugin images/vue/css

Skin custom config.json

Other areas will be assessed to see if support would work there.

Add license verification button on Admin -> Licenses/Updates page (SKINS) new

To aid Admins in determining if their license is authentic, we've added a "Verify" button to:

Admin Level -> Licenses/Updates

in the "License Values" table.

It basically just a URL to:


The output generated by DA will also include a URL to the page, so they can verify it on our end as well, with the IP pre-loaded in.

The absence of the button could be treated as suspicious if you're not sure about state of your license.

Use the page to confirm your server IP.

The same "Verify License" button already exists on the page:

User Level -> Site Summary / Statistics / Logs

dovecot_proxy_override new

Relating to the dovecot_proxy setting:

dovecot_proxy for Multi-Server Setup email sync

New optional value:


which is internally set to NULL (disabled).

If you're using;


and you wish to override the /etc/virtual/ files:

... proxy_maybe=y host=

to be something static, say:

... proxy_maybe=y

you can enable it like this:

cd /usr/local/directadmin
./directadmin set dovecot_proxy_override
service directadmin restart
echo "action=rewrite&value=email_passwd" >> /usr/local/directadmin/data/task.queue; ./dataskq d2000

If you wish to disable it, either clear it from the directadmin.conf, or set it to be blank:

./directadmin set dovecot_proxy_override ''



Default: mysql_detect_correct_methods=1 for new installs new

New installs will get the setting:


existing installs will not be affected, but if you wish to enable it:

cd /usr/local/directadmin
./directadmin set mysql_detect_correct_methods 1
service directadmin restart

Admin Stats: change device usage to use /proc/net/dev new

Previously, the Admin Stats page used "/sbin/ifconfig eth0" to hunt down the RX:TX values for that device.

New method changes it to use:


Only noticeable difference will be the units will be shown in "MB/GB" instead of "MiB/GiB", for example.

Change does not affect FreeBSD, which still uses the call to /usr/bin/netstat.

scripts: addip/removeip to use "ip" commands instead of ifconfig new

The scripts at location:



previously used ifconfig to add IPs to the device.

Changed to use the "ip" command, eg:

ip addr add dev eth0


This change will put additional IPs into the main device aliases, rather than some eth0:0 section.

DirectAdmin will also scan all aliases in the main device for IPs in there, during any licenses checks.

To see a proper list of IPs on your system, use:

/sbin/ip a

rather than:


as ifconfig does not support ipv4 alises in the same device:

FreeBSD is not affected, although the scripts are now unified into the same script for all OSs.

The call for FreeBSD still uses ifconfig.

JSON: Show list of document roots for all domains under this User new

New option for CMD_DOMAIN or CMD_API_DOMAIN, both of which will only output JSON:


Where all domains will be output.

Sample output:

          "private_html": "/home/admin/domains/",
          "public_html": "/home/admin/domains/",
              "private_html": "/home/admin/domains/",
              "public_html": "/home/admin/domains/"
          "private_html": "/home/admin/domains/",
          "public_html": "/home/admin/domains/",
              "private_html": "/home/admin/domains/",
              "public_html": "/home/admin/domains/"

one-click phpMyAdmin Login: User login can see all databases (SKINS) new

New option for the one-click SSO login for phpMyAdmin on the Databases page (listing all Dbs)

with a phpMyAdmin button to login to view all databases under this DA User account.

If you're on the DB page viewing a specific DB, there is still the PMA button there, to view just that given DB, that's unchanged (Enhanced)

Evolution skin has per-DB logins on the DB list page, but for each DB listed, "Login" button on the far right.


If you specify:


instead of:


and DA will use:


instead of:


for the login, allowing the view of all databases below the User.


Various changes and a new global token are in this entry.

Global token:

PHPMYADMIN_PUBLIC=yes|no    #relating to for SSO-only logins to PMA

The HAVE_PHPMYADMIN remains, but now checks for /var/www/html/phpMyAdmin instead of /var/www/html/phpmyadmin


|?PMA_HREF=<a target="_blank" href="\`PMA_URL\`">\`LANG_PHPMYADMIN\`</a><br><br>|

<form id='pma_form' action='CMD_PMA_LOGIN' method='POST' target="_blank">
<input type='hidden' name='name' value='all'>
<input type='hidden' name='domain' value='|DOMAIN|'>
<input type="submit" value="|LANG_PMA_SSO|"> |LANG_PMA_NO_PASS|


replace the old /phpMyAdmin link with this:

|?PMA_HREF=<a target="_blank" href="\`PMA_URL\`">\`LANG_PHPMYADMIN\`</a><br>|

Better response codes for file sends new

The standard internal file sending function previously would always throw a basic 404 not found error, if any error was hit.

For any errors with regards during the open() call on a file during a file send, there will now be various checks on the errno for better http response code handling.

It should also provide the strerror(errno) from the failed open() call, helping debug any issues, if it's not simply a permission/401 or 404 error.

See "man 2 open" for more info on the error codes.


per-user.conf check_subdomain_owner override new

Relating to the check_subdomain_owner setting in the directadmin.conf, you can now override this setting on a per-User basis by adding:


to the user.conf of a given User account.


System account to support RoundCube SSO new

The one_click_webmail_login feature previously only support virtual accounts in the /etc/virtual/ files.

The system account was not in there, it's in /etc/passwd, so the passwd_alt method used by dovecot as a backup login file didn't work.

The system_user_to_virtual_passwd=1 feature lets you store the system account in the virtual passwd file.


This change simply accepts the system account, when creating the login token.

No other changes were needed, aside from making the system account name clickable on the CMD_EMAIL_POP? page.


Support http OPTIONS method new

With to compliment the CORS feature:


We've now added support for the OPTIONS method, which is essentially just an alias to HEAD for the time being, unless other controls are needed.

DNS: rndc for efficient immediate reloads new

New optional directadmin.conf value, with internal defaults:



./directadmin set named_rndc 1
service directadmin restart

Where changes to the dns zone will make use of the 2 possible calls:

Changes to the contents of a zone:

/usr/sbin/rndc reload

Add or remove zones from the named.conf

/usr/sbin/rndc reconfig

such that the rndc reload domain is done immediately, without any delay (task.queue is not used for dns in some cases)

Other cases, like full rewrites of all zones will still use the old "service named reload", or whatever you've got setup.



to enable this level, rndc 9.11 and up is needed:

rndc --version

Basically, CentOS 7 and up.

You should also have named_rndc=1 enabled, although they are somewhat separate.


./directadmin set named_rndc_addzone 1
service directadmin restart

You must also have:

allow-new-zones yes;

in the options{} section of your named.conf or you'll get a permission denied error.

/var/named must also be writable by "named:named"

This will make use of the rndc addzone/delzone calls to add/remove the zones.

The data/templates/zone.conf should NOT be overly customized (single line only) as it's passed to rndc on the command line.

When using the named_rndc_addzone , zones are not stored in the named.conf.

The rdnc call automatically adds them to the default view:


so for any listing of all zones on the box, DA will get the list from both that file and the named.conf.

For "does the zone exist", DA will use:

rndc zonestatus ''

and will look for a zero result for true.

Else, it will continue to hunt in the named.conf for the zone.



For any non-immediate calls, where the task.queue is still used, instead of action=named, it will use:

echo "action=rndc&value=reload&" >> /usr/local/directadmin/data/task.queue


echo "action=rndc&value=reconfig" >> /usr/local/directadmin/data/task.queue

But for any calls pushed to the task.queue, their exact value will still be used.

So if you're reloading named through the task.queue, the old service named reload will still be used.


Domain Already Exists: check multiple areas new

Previously the domain existence check during User domain creation, reseller User creation, etc,, only looked at the named.conf.

This change will do the check in order:

  1. If /etc/virtual/ exists, return true

  2. Previous dns/named.conf check runs, returns true if exists locally or in remote cluster

  3. Returns true if domain is in /etc/virtual/domainowners

  4. returns false

Add "Default" to the system account on E-Mail Accounts page (SKINS) new

To help alleviate some confusion around the system account that appears by default (cannot be delete, since it's linked to the hostname),

we've added a "Default" message to the system account, under the "Login" column.

If you are using system_user_to_virtual_passwd=1, then this option will be hidden, since the part would take up too much space.


just ensure you have this in your loaded stylesheet:

.float_left {
  float: left;
.float_right {
  float: right;
  background: #008a0d;
  color: white;
  margin-left: 10px;
  padding: 1px;
  padding-left: 5px;
  padding-right: 5px;
  border-radius: 5px;
  border: 1px outset #58b761;
  box-shadow: 1px 1px 3px #004506;

Feel free to adjust the count_notice however you want..

We've re-used it from the Enhanced skin's counter popups on the Admin page,

so you may already have these css classes.


Ability to disable: check_home_path_on_user_create=1 new

New internal directadmin.conf option:


where you can set it to:

./directadmin set check_home_path_on_user_create 0
service directadmin restart

should you wish to disable the pre-User-creation check to see if the User's home path:


already exists.

This would be useful should you need to setup some things in the folder prior to creating the account.

Domain suspended by Admin should not be unsuspended by User or Reseller fixed

Related to this change for User:

Prevent Reseller from unsuspending User if Admin suspended it (LANG)

We've extended the functionality so that if an Admin has logged in as User "fred", and suspended "", this will add a tag to the file:


Should User fred or the Reseller that created User fred try to login-as fred and unsuspend the domain, it will throw the error:

Error modifying the domains:


Domain was suspended by an Admin and you not have this access. You cannot unsuspend this domain.

Improve action=rewrite&value=all_lists to check user.conf creator fixed

Related to:

Internal admin/reseller/users.lists checker

which is setup to ensure the users.list, reseller.list, and admin.list files are correct.

This has been expanded to also ensure the creator value in the user.conf file for Resellers is correct.

Previously, on Users had their creator value checked.


MariaDB 10.1 needs CREATE USER before GRANT on restore: system account fixed

Relating to fix which applied to dbname_user accounts:

MariaDB 10.1 needs CREATE USER before GRANT on restore

The restore of a database had it's own code to create the system account, which was not updated with id=1801.

Swapped it out and replaced it with the now standardized internal code to correctly handle all MySQL/MariaDB versions and their variances.

Related error:

Error Adding Main Username to database: Can't find any matching row in the user table


Restore: use mysql_old_password if old password format is used fixed

Sometimes, very old accounts still use the pre-mysql-4.1 16-byte password format.

Using the newer methods, if DA tries to reset the raw 16-byte old hash while specifying mysql_native_password (eg: MariaDB 10.2),

it will throw an error:

Error altering user 'user_dbname': Operation ALTER USER failed for 'user_dbname'@'localhost'

without much other information, but if you hunt in the "backup/user_dbname.conf" backup file, and check the "passwd" entries,

if you see they're the short 16-byte password without the * character in front, then those are the old_format passwords.

The fix is for DA to scan the password being restored.

If it does not start with * and is 16 bytes, then DA will instead use:


instead of the mysql_native_password plugin, when altering or duplicating hosts for accounts with a raw hash.

The mainly only applies for restores, and when adding extra access hosts to a DB.

Should an old password be found, a warning will be included in the restore output, even if everything went ok.

This is because these passwords should really be reset to the mysql_native_password format (41-byte hash values starting with *)


Mailing List: Edit: json out not to be html encoded fixed

The Evolution skin uses json, so the values returned to it should not be html encoded.

The only applies to the <<END type variables.


RoundCube/PhpMyAdmin one-click Login/SSO: use x-forwarded-for IP fixed

When creating one-time use login tokens, DA was previously using the cilent's connecting IP.

This change uses the determined client IP, factoring the possible use of X-Forwarded-For with proxies.


scripts/ftp_upload.php improvements fixed

Clear out old ncftpput code.



which is now included in the curl call, forcing a minimum of TLS 1.1. It should use a newer version if available.


nginx apache proxy not rotating correct number of logs. fixed

Relating to this:

compress_rotated_logs=1 did not rotate old months logs

The rotation could should be double, set internally.

The count of 5 would hold, for example:

3 nginx, and 2 apache logs

which is not correct.

While working on the changes. the nginx- prefix has been replaced with nginx. for domain.

The subdomains already used nginx. for the prefix.

Either nginx- or nginx. will be valid in the clearing of old logs.

The assumption is that the 2 files:


should have roughly the same timestamp, so the dated rotation simply multiplies the limit counter by 2 when nginx is in play.

Subdomain file are sorted per subdomain, and each grouping is sorted by date before clearing.



Simply double the number of logs you want to keep, until the bug is fixed:

cd /usr/local/directadmin
./directadmin set logs_to_keep 10


named_reload=yes to respect named_service_override fixed

It was reported that LetsEncrypt wildcards were not working correctly due to "named" being called, when a given system might have needed bind9 via named_service_override=bind9.

Bug found where the immediate named reload was not respecting the named_service_override setting, so "named" was used, thus named didn't get reloaded when it was intended to be.


readLine no longer ignores lines without trailing newlines fixed

The readLine function in DA, used fairly extensively throughout DA, will now accept the final line of a file as a "line" even if it does not have a trailing newline character.

This should help avoid some confusion for cases where there is no trailing newline.


Domain deletion with pointers throws 'Account fred with domain has an empty caroot cert' fixed

When deleting a domain, the SSL certs were removed, then domain pointers, followed by domain configs.

When deleting pointers, Apache was re-written, but the certificates were already missing, thus throwing the mentioned error.

Solutions implemented

  1. Delete certs after pointers

  2. Do not issue an Apache rewrite for pointer deletion if master domain is being deleted, as it's redundant

PHP1_RELEASE not set in php-fpm.conf in some scenarios fixed

Some cases of the php-fpm.conf may not be loading the PHP1_RELEASE token into DirectAdmin before passing it to the php-fpm.conf template.

This would affect the open_basedir path in some cases of CloudLinux.

More validation on password changes: Low (SECURITY) fixed

Report from Rack 911 on a minor security issue during password changes.

No reports of issues from it, and probability of using this for anything malicious is also improbable.

Does not do anything as root. Cannot be triggered by a User or any external sources.

Last Updated: