Version 1.37.0

Released: 2011-01-10 script for SSL certificate page new

Scripts are:

Data will be the post values passed to CMD_SSL (and CMD_API_SSL), plus:


Check the <form> in the skins to see which values are passed for which cases.

There is some info for CMD_API_SSL here:

CMD_API: catch-all, pop passwords, frontpage, protected dirs, ssl certs

which will be the same info that CMD_SSL uses.

Admin Level cronjob manager (SKINS) new

First iteration of the Admin Level cronjob manager.

This version only show User crons based on crontab.conf files.

It does not show root, or non DA-User cronjobs.

This version cannot edit/create crons.

It's simply a page to let the Admin see what his Users have done.



add link for CMD_ADMIN_CRON_JOBS




  • lang/en/internal/cron.txt

  • lang/en/admin/content_main.html

new files:

  • admin/admin_cron_jobs.html

  • lang/en/admin/admin_cron_jobs.html

Future versions:

Will show all cronjobs on the entire system, and where it's located.

Will also show crons in /etc/cron.d, /etc/cron.daily, etc.. and /etc/crontab.

If all goes well, it should be showing every cron that exists on the box.

Internal translation of reseller class (SKINS) new

Translated all hardcoded text in the reseller class. The new translations are added to the end of the lang/en/internal/user.txt file (31-73), as the reseller class is inherited from the user class, thus is uses the same translation file.

Number of email deliveries in all stats new

Since the bandwidth.tally already knows how many emails a User has delivered (both incoming and outgoing), we've now added this number to the user.usage file, and it shows up in all stats levels.

New user.usage values:


Note that email_deliveries can be higher than the number of the incoming and outgoing, as any bandwidth.tally rows that do not specify incoming or outgoing are assumed to be "email", but we don't know which direction the email was going (mainly only applies to old files that don't log this info)

A new row called "Email Deliveries" will show the number in the usage column, and for User Level stats, the "Maximum Usage" column will show either unlimited, or the number, based on the contents of the /etc/virtual/limit file. The Reseller/Admin levels won't show the value of the /etc/virtual/limit file because it's a per User limit, and at Reseller/Admin stats levels, it's counting the sum of all Users, so the number would be confusing. Note the limit file's value for unlimited is 0.

During the tally, a check is also done on the daily count of email_deliveries_outgoing for the previous day's stats.

If the limit is exceeded, a warning is added to all logs (system.log, errortaskq.log, security.log).

If the limit is 0 (unlimited), then DA will throw the warning at 1000 email sends (outgoing).

Note that the "Deliveries" count is for both inbound and outbound emails, but the /etc/virtual/limit file is only for an outbound cap. That means the above check won't be entirely accurate, hence it's just a background log.

Added code into:


echo "0=type=timestamp&time=\`date +%s\`" >> $USERS/$U_NAME/bandwidth.tally

before the /etc/virtual/usage/user.bytes is dumped into the bandwidth.tally so that the emails don't end up on the day before they were sent.

Else, the number of deliveries for "yesterday" will always be 0, and 2 days ago would be the actual total... and the above limit check would be looking at 0 all the time, which would be pointless.

More info on the limit file:

If you have an older exim.conf and, you may need to update these files to get properly working stats:

*** If you update your exim.conf and are running dovecot, don't forget to repatch!

Same goes for SpamAssassin, if the exim.conf is updated, re-enable SpamAssassin in the exim.conf

Added a notification to all Admin's of a User's mass emailings.

The User will also be notified of his limit being hit.

This will be done if the value:


is set (default to 1, internally, so doesn't exist in your directadmin.conf, but is set to 1)

If you wish to disable this notification, set:


in the directadmin.conf.

As well, a new option will be enabled by default to include the User in the notice:


Setting this value to 0 will prevent your Users from getting the notice.

Note that if notify_on_mass_emailing=0 is set, then notify_user_on_mass_emailing=1 will not have any effect (Nobody will get anything)

Temporary Additional Bandwidth new

New feature where a creator can assign an extra one-time use sum of bandwidth for a client (Reseller or User). This will be added to the current limit, allowing that client extra breathing room until the end of the month reset. The monthly reset will set this value back to 0. If a client's limit is unlimited the "Temporary Bandwidth Increase" row will not be shown (since there would be no point)

Implemented for both Users and Resellers.



method: POST

User modifiable TTL values (SKINS) new

Users can now modify their own TTL values if they have DNS control enabled.

There is also a new directadmin.conf option, which has a default value of:


set it to 0 if you wish to disable it.

So a User must have dns control and this directadmin.conf value enabled in order to use the feature.

The feature is accessed by Users from:

User Level -> DNS Management

They can specify their own TTL value, or use the default.

This is related as to why someone would want to lower their TTL:

at this time, domain pointers are not supported for this feature.

Only full domains can use the feature.

Also, this is not available at the Admin Level -> DNS Administration page.

Only the User Level -> DNS Management



after the |*endif| for the USERDNSCONTROL check:

<form action='/CMD_DNS_CONTROL' method='POST'>
<input type=hidden name=action value=ttl>
<input type=hidden name=domain value="|domain|">
<td class=list2>Override TTL Value</td>
<td class=list2 align=center>TTL</td>
<td class=list2><input type=radio name=ttl_select value="custom" |TTL_CUSTOM_SELECTED|><input type=text name=ttl size=6 value="|TTL_VALUE|">&nbsp; <input type=radio name=ttl_select value="default" |TTL_DEFAULT_SELECTED|>Use Default</td>
<td class=list2 align=center><input type=submit value="Save"></td>
|*endif| and new and

Called before and after a user httpd.conf is written.




If a non-zero exit value is used with, then the process aborts with an error, and the script output is displayed. The user httpd.conf won't be written in that case.

added support for favicon.ico new

Admins can now define a favicon.ico.

There file in place by default (same as located at:


This path is determined from the value:


(relative to /usr/local/directadmin)

in your directadmin.conf.

Using a different default docroot path can override this (assuming it's pointing to a valid skin)

Added 301 to redirect_virtual_host.conf new

Added 301 to redirect_virtual_host.conf for related thread:

Error reading from new

It was found that Chrome seems to open a new connection in anticipation of more requests based on the html. Eg: to be read to get more images. However, once the page is done loading, this extra anticipatory connection is no longer needed, thus it hangs up on DA without requesting anything (no GET/POST, etc.. ). This would flood the DA logs with the message:

Error reading from

Extra debug code was added to DA (level 100) to check this case, and it would show:

Error reading from Cannot find first space after where GET or POST should be<br>

which is how it was determined that there was an extra connection going on.

DA will now prevent logging into the error.log for the above case. However, the DA access logs (eg: 2010-Nov-27.log) will still show a normal connection failure, eg:

27/11/2010:15:47:46 BAD REQUEST       unknown

Added apache upload info to bandwidth tally and breakdown new

As long as you've got:

LogFormat "%O %I" bytes

in your main httpd.conf, DA will know how much info was uploaded vs downloaded through apache. This uploaded data was always included in the totals, but the specific value wasn't known.

This info will now be included in the the bandwidth.tally and bandwidth.tally.cache files, thus will also show up in the bandwidth breakdown page as a hover-hover popup item.

Hover your mouse over the apache column for a specific day, or the total at the bottom, and you'll see a "Downloaded:" and "Uploaded:" popup.

Added "port" to ftp backup options (SKINS) new

Added the ability to specify a port when creating a backup to be transferred via ftp.






added new form value "ftp_port".

Tokens with name to match, eg: |ftp_port|

Copy lines from ftp_path, as it follow all areas.

Note, on the admin_backup.html and backup.html, there are 3 locations to add the variables to. One is a hidden form for the submission of the restore.

Note that if the skin does not have these options, it's not an issue. If the ftp_port value isn't passed, or isn't a valid number port number, DA will use a default value of 21.





to support the ftp_port option.

language specific files_custom.conf files. new

With this feature, language coders can add their own files_custom.conf files inside their language directory.

This allows for each languge to have their own files_custom.conf, allowing for custom html files and images, based on language.

An example path:


this path varies based on the language value the User is using.

The main benefit of this feature is to allow language translators to have images right inside their language directory, for language specific images.

Example, the IMG_SKIN_BODY_ACCOUNT image at the User Level can be changed based on language by adding:


which will override the values found in the top-level files_*.conf.

The language files_custom.conf will also override the top-level files_custom.conf.

This somewhat voids the requirement of:


since it would be doing a double lookup...

However, this would allow you to leave the original images alone, and create your own.

For example, you could leave IMG_SKIN_BODY_ACCOUNT alone, and don't override it...

and instead have:


and set the:


to have:


So either method will work with this new file.

Pure-FTPD new

Added support for Pure-FTPD.

The unified_ftp_password_file option must be set to 1 and all passwords converted:

multi-ip issue for ftp password files ACTION REQUIRED


should also be set to 1.

After any change to the /etc/proftpd.passwd file, DA will add a task.queue entry:


and the dataskq will call:

/usr/bin/pure-pw mkdb /etc/pureftpd.pdb -f /etc/proftpd.passwd


Use custombuild to install this for you:

cd /usr/local/directadmin/custombuild
./build set proftpd no
./build set pureftpd yes
./build pureftpd

Keep in mind that this is in beta, so there may be bugs.

existing .htaccess files breaking with addition of password protection fixed


<Files "config.php">
Order Allow,Deny
Deny from All


<Files "config.php">
Order Allow,Deny
Deny from All
AuthGroupFile /dev/null
AuthName "Secret Area"
AuthType Basic
AuthUserFile /home/user/domains/

So </Files> is missing after addition of password protection.

Solution entailed a full rewrite of the .htaccess parsing/inserting code.

Awstats computation of last day of month overriding entire previous month & added cgi based dynamic awstats fixed

Related to this fix:

awstats doesn't compute last day of month

the was changed to compute the last day of the last month on the 1st day of this month (as that's when the tally/rotation is done). The issue is that if there are any log entries in the window from midnight of the 1st day to the time the tally is run, the new month's days will be in the logs. Awstats will then only show stats for the current month, overriding the last months stats with a small volume of this months stats.

Since there is no great solution for splitting a log efficiently, I've reverted the to use the old method.

However, not to leave it that way, in addition to the static html files that are generated, I've also implemented the cgi based script to work by default (when awstats is enabled)

The dynamic method of accessing awstats ( can now be done through both DA and Apache.

The DA method is access from the same "Awstats ..." dropdown on CMD_USER_STATS?, but the new value will show up in the list as:

All Months (cgi)

and the months/years can be selected right on the awstats page using the

The will be access from:


and does not require apache at all (DA emulates apache via environmental variables).

Users can also access the through apache.

To do that, they need only to create the /awstats symbolic link to ../awstats in their public_html directory, and the will be called (via .htaccess with DirectoryIndex set). Note that they must use the value "/awstats", as the configs/paths require it.

The .htaccess also contains a RewriteRule to ensure that is used, and not (only applies to the apache method, DA doesn't read .htaccess files).

The script checks for the configs and data files based on the hostname used, and since there are no data files for www, the rewrite is required to ensure consistency with client connections.

With the dynamic cgi based, all stats for all months, all years, can all be accessed on one page.

Also, with the previous bug overriding the last months html files, the data is still fine, and the cgi method reads all of the data in correctly, nothing is missing with this method. The September html files will still be missing permanently, but we figure clients are not as likely to use the html version anyway.

If you wish to increase system efficiency, you can disable the html files from being generated (as they are the bulk of the cpu-time) and have only the data files be computed. To do this, type:

cd /usr/local/directadmin/scripts/custom
cp ../ .

edit the custom/, and set:


and the html files will no longer be generated, increasing performance.

Additional report (no longer relevant):

FreeBSD has no key:


use this instead:


Domain pointers not adding additional IPs into VHs fixed

When using a redirect type of domain pointer (not an alias), the "additional IPs" are not being inserted into the |MULTI_IP| token.

The alias type of pointers are not affected since they are placed into the main VH for the domain.

IPs missing from user_ip.list after Reseller creation fixed

The user_ip.list file was not being filled with the list of IPs for a newly created Reseller. By default (after the fix), it will only hold the 1 IP that is assigned to their domain.

Search on main page returns empty results (SKINS) fixed

The domain/user search was returning empty results because they were not sorted.

Added this to the form:

<input type=hidden name=sort1 value="1">

resolved the issue because items that were on the 2nd page were not sorted to the top of the list when other items were removed. Items that show up on page 2 unsorted (for example), will still be on page 2 after the search, even though page 1 may not have returned any results.

Note that the addition to the form works for both search types. The rows will just always be shown in user order (which is intuitive anyway). After the search, you can still click the column headers to get different sort columns.




add [] characters around IP if IPv6 in welcome emails fixed

The |ip| token did not add the [] characters around the IP if the IP was of type IPv6.

Added a check to see if the IP is IPv6, and adjust the token as needed for the welcome emails.

multi-ip issue for ftp password files ACTION REQUIRED fixed

A domain can now have multiple IPs.

DA previously determined which ftp password file to use based on the User's main IP (shared or owned).

Now, a domain can have both a shared and owned IP. Which ftp password file to use?


The multi-IP options will be hidden unless the unified_ftp_password option is enabled.

See below on how to simulate and convert your data to a unified password file.

option for the directadmin.conf for the proftpd password files to be unified.

This will make things about 8x simpler. A conversion tool will be provided to move all ftp.passwd files to the main proftpd.passwd file (as some username changes would be needed)

All IP types, all usernames, everything will be in the /etc/proftpd.passwd with this enabled.

The /etc/proftpd.vhosts.conf will no longer be needed, and will be emptied during conversion.

This option has the added benefit of support for pureftpd or vsftpd with very minimal pain and suffering.

The only drawback will be the loss of "username" ftp logins (except for DA usernames)

All created ftp accounts for domains will require the format.

A minor drawback for many gains.

This also greatly simplies the entire system for multi ip for backups as well.

If this option is disabled and multiple ftp password files are to be used.. then the system will no longer allow the use of multi-IPs (an override may be added, preferrably not, but with the knowledge that ftp account creation breaks)

directadmin.conf variable:

  1. unified_ftp_password_file=0

will be the internal default.

  1. Existing installs will use this value (0).

  2. New installs will have:


in their directadmin.conf (physically set)

0: old method: Allows separate ftp login files (proftpd.passwd and ftp.passwd). Owned IPs can have login format "user". ** Multi-IP setup will be disabled/hidden from the interface **

1: new method: Forces all logins into the proftpd.passwd file. Owned IPs ftp accounts wil have the login format ""


This will let you know who's login format will change before you actually do the change.

This will give you some advanced notice, if you need to tell your clients what will be happening.

An email address is also included in the output for each User, letting you know where to deliver the changes.

cd /usr/local/directadmin
echo "action=convert&value=unifiedftp&simulate=yes" >> data/task.queue
./dataskq d1


cd /usr/local/directadmin
echo "unified_ftp_password_file=1" >> conf/directadmin.conf
echo "action=convert&value=unifiedftp" >> data/task.queue
./dataskq d1

TLS for owned IP ftp accounts fixed

Added this into the <global> section of the /etc/proftpd.conf template (/usr/local/directadmin/data/templates/proftpd.conf)

        <IfModule mod_tls.c>
                TLSEngine on
                TLSLog /var/log/proftpd/proftpd.tls.log
                TLSRSACertificateFile /etc/exim.cert
                TLSRSACertificateKeyFile /etc/exim.key

Moved dns creation to last part of domain creation, and skipped on error fixed

Since any error during the creation of a domain will result in the domain not showing up in the User's domains.list file, if the dns was already created, and the domain is not in the domains.list, then the User will end up with the error "domain already exists", as mentioned in this guide:

The solution is to move the dns creation to the very last step of the domain creation, and if there were any previous errors in the domain creation, then the dns part is skipped so as to not add the domain into the named.conf. This will prevent the "domain already exists" error, for the domain creation error case.

There could be other causes of this error, but this fix will resolve this particular case.

If you are affected by this, then you should see log entires similar to:

Error Creating Domain: someerrormessage api=0

Domain removed from user bob's domains.list file due to error

in your /var/log/directadmin/error.log.

Security: Better checks before backup creation fixed

More checks have been added before a backup is created to ensure the location being saved to is safe.

Using %s when adding a cron becomes blank fixed

When adding a cron, a temp file is used to generate the file to give to crontab to load them in.

fprintf was used to create the file, so any %s sequences (or others) would be replaced with nothing.. making some cron commands like "date +%s" becomes "date +" in the actual cronjob.

Changed fprintf to fputs since we don't want any string parsing to happen with this file.

Last Updated: