Version 1.52.0
Released: 2017-10-03
new
http2Support for http2 in the templates.
Requires:
http2=1
in the directadmin.conf.
Uses:
|LINKEDIP|
|LINKEDIPSSL|
In the custombuild apache/nginx configure templates;
configure/nginx/conf/nginx-vhosts.conf:|LINKEDIPSSL|
configure/nginx_reverse/conf/nginx-vhosts.conf:|LINKEDIPSSL|
configure/ap2/conf/extra/httpd-vhosts.conf:<VirtualHost |IP|:|PORT_443||LINKEDIPSSL|>
Note, CustomBuild 2.0 rev 1600+ can setup http2 for you for Apache, but it doesn't install openssl with ALPN for you.
This is related:
http://forum.directadmin.com/showthread.php?t=52590&p=269958#post269958
So with CB2 now, you'd do:
- Add a non-standard instance of apache/nghttp2 to use:
wget ftp://ftp.openssl.org/source/openssl-1.0.2k.tar.gz
tar xzf openssl-1.0.2k.tar.gz
cd openssl-1.0.2k
./config --prefix=/usr/local/lib_http2 no-ssl2 no-ssl3 zlib-dynamic -fPIC
make depend
make install
DO NOT USE 1.0.2h or newer, as they've dropped older SSL functions that apache 2.4.26 does not know about .. so you'll get compile errors if you use anything newer thatn 1.0.2k.
- Set:
http2=1
in the directadmin.conf, eg:
https://help.directadmin.com/item.php?id=641&in1=http2&in2=1
- Let CB2 do the rest:
cd /usr/local/directadmin/custombuild
./build update
./build nghttp2
./build apache
./build rewrite_confs
For Chrome, you'd need the SPDY extension to access HTTP/2 sites.
new
CMD_PLUGINS ability to skip user.conf writeA plugin may need to make an API call to change a user.conf setting for the current User.
This is a race condition, since the CMD_PLUGINS call to that plugin, follows up with a check on the user.conf timestamp (and related files),
and if DA notices the timestamp changed, it will decide to overwrite it and log something like:
2017:06:11-01:05:53: ConfigFile::writeFile(./data/users/fred/user.conf) : Timestamp from when it was read is different, overwriting anyway
The solution is to tell DA not to write to disk when you know you'll need to be doing that.
To accomplish this, pass a GET request:
user_conf_write=no
eg:
http://1.2.3.4:2222/CMD_PLUGINS/hello_world?user_conf_write=no
http://1.2.3.4:2222/CMD_PLUGINS/hello_world/index.html?user_conf_write=no
and this will stop the user.conf write for that call to CMD_PLUGINS.
You'll then be able to make an API call within the plugin code, to alter the user.conf, without racing to write first.
new
Ability to message Users from task.queueRelated to this guide:
Ability to script/send your own custom notifications to the Admin Message System
you can now message a specific account, list of accounts, or all accounts (Admins+Resellers+Users) with the task.queue
Format is as follows:
action=notify
value=users
users=all|select1=fred&select2=george&select5=gary
subject=Your Subject
message=Content of your Message
where the "users" variable can be "all", meaning DA will message all accounts on the server,
or can be a list of accounts, url encoded with select1, select2,
For a single account, just use:
users=select1=gary
Note.. the = and & characters in the users list must be url encoded with hex (%3D and %26, respectively)
Also, if you want to include a newline in the message, use %0A instead.
A sample echo command is:
echo 'action=notify&value=users&subject=Hello World&message=Hello,%0A%0A This is a message.&users=select1%3Dadmin%26select2%3Dgary' >> /usr/local/directadmin/data/task.queue
new
json for CMD_FTPSupport for json on all CMD_FTP commands:
- CMD_FTP
- CMD_FTP_SETTINGS
- CMD_FTP_SHOW
The json output uses the API functionality, so use the above commands, but use the CMD_API versions of those commands for info on how to use them:
new
Ability to tokenize CSS_* files.By default CSS_ files are sent as raw file for quickest performance.
This change allows you to add this get request, eg:
CSS_STYLE?v=|VERSION|&tokenize_css=yes
where adding tokenize=yes to the CSS will force DA to tokenize it with all global tokens.
You can also set variables, and do standard if-then-else structures, etc, like like HTM requests.
This change was added for the custom color feature, so a signle token can be set anywhere in the skin and CSS files.
CMD_SKINS custom skin colors json/api (SKINS)(LANG)
new
Ability to include custom other disk usage for a User (LANG)If you have data that should be counted in the total disk usage for a User, but does not fall under the standard usage areas (eg: data on a remote server),
then you can use this option to create a hook, which lets you add extra bytes into the disk usage under "Other Usage"
Set the following in the directadmin.conf:
count_other_disk_usage=1
and create a script:
/usr/local/directadmin/scripts/custom/other_disk_usage.sh
the script must exit with code 0.
If a non-zero code is exited, the output is logged to the errortaskq.log.
The output on exit 0 must be a URL encoded.. and for now, it will basically just be:
other_quota=12345
where 12345 bytes will be added to the user.usage file.
In the future, we might add more, like
other_quota=12345&something_else=56789
but for now, it's just "other_quota".
The value must be a positive integer.
ENVIRONMENTAL VALUES PASSED TO SCRIPT
username=fred
type=user|reseller|admin
runs as root.
new
JSON for CMD_SECURITY_QUESTIONSIf you call CMD_SECURITY_QUESTIONS with GET option:
json=yes
you'll get the output in json.
See the contents of enhanced/user/security_questions.html for the usage of the tokens.
=========================
num_questions=22
Most variables should all be self-explanatory, but the "num_questions=22" will be confusing by design.
The security_questions.txt file starts at 1, but index 1 must contain the last index number.
By at the time of this writing, it's:
1=22
where the last entry is 22, eg:
22=What is the name of a college you applied to but didn't attend?
Also, because 1 is taken, the first question starts at index 2.
The json variable "questions" is standard table output, with the json[questions][info] showing info on columns, sorting, etc.
When posting data, just like the API methods, include json=yes (GET or POST) and the dynamic output should be json-ified.
SECURITY_QUESTIONS_DISABLED
this value will be set to:
SECURITY_QUESTIONS_DISABLED=disabled
if the number of questions is 0.
If this is set, then the checkboxes for:
- security_questions
should be disabled, because you cannot turn on the feature, with 0 questions available for DA to ask the client.
new
brute_filter.list supports count_multiplier optionA new option has been added to the lines in the file:
/usr/local/directadmin/data/templates/brute_filter.list
specifically for the wordpress3 entry, eg:
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 (eg: 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 is 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.
SKIN:
There are no html changes required.
However, we have changed the |LOGINFAILURES| table token value.
The wordpress3 attempts, which are usually 1, will now be displayed as a float / multiplier.
So for this case, each wordpress3 attempt count will show 0.25.
There is also a title= hover-over popup to provide info about what that's about.
new
skin.conf 404 overrideYou can now add a new variable, eg:
404_override=user/404.html
to the skin.conf file.
This setting allows you to control the output of the 404 pages by instead, sending a specific page, with the data set in the desired file (eg: user/404.html, can be changed).
This file is tokenized similar to an HTM_ file.
Note, the FileManager is chrooted, so if you trigger a 404 for a file that does not exist, you'll still get the old format because the 404_override file is loaded after the chroot has already happened.
Also new optional file in the skin document root:
routes.conf
which will list valid paths that will return 200 instead of 404 for the 404_override file.
Intended purpose is for vue-router / JS framework to redirect things like:
domain.com:222/app/ftp/create
to valid places via JS using the 404_override file.
The same file is sent regardless of the routes.conf list, but the list simply controls if it's a http 200 or 404 response code.
The routes.conf supports wildcards, similar to the shell (cannot cross / character)
So:
/app/test/*
will mach:
/app/test/bob
but will not match:
/app/test/ftp/bob
new
Referer check override files (PLUGINS)New optional file can be created:
/usr/local/directadmin/data/templates/custom/referer_check.allow
or per-plugin:
/usr/local/directadmin/plugins/PLUGINNAME/referer_check.allow
where the referer_check.allow files can contain a list of URLs, eg:
http://somehost.com
https://otherhost.com
https://otherhost.com:8080
etc..which will be used as a backup list of allowed referers, in addition to the host value set in the session file.
This is used for cases where a remote site needs to use the current User's session file, via a form on that remote site.
As this is bypassing a security step, be sure you fully trust the list of referers added to your lists.
As you may have noticed, you can either manage your own global list,
but each plugin can also have it's own list as well, in case the plugin needs to make a call out, then back in again.
new
ACCESS_LEVEL token on all CMD_ pagesA new global token:
ACCESS_LEVEL=admin|reseller|user
is available on all CMD_ pages.
The values is based on which class list of functions it's allowed in.
HTM_, CSS_ files, etc.. will not get this token, but could be figured out by coding into the given skin.
eg, if you know the user/passwd.html is a User page, you'd just add:
|?ACCESS_LEVEL=user|
to the top of the user/passwd.html file.
new
CMD_JSON_LANG .po files for languages, and localesExtension for the CMD_JSON_LANG tool:
- If no options are returns, a json output will show something like:
{
"default":
{
"id": "en"
},
"languages":
{
"en": "English",
"fr": "Français",
}
}
depending on the languages available for this skin (we only include "en" by default)
The "en" can be any valid language, and the rules have been related to allow proper locale naming, like en_US.
Each value for that local on the right will be in that native language, not English.
So for fr, it will show Français, and not "French".
The actual locales.po file should exist the skins document root, eg:
/usr/local/directadmin/data/skins/SKINNAME/locales.po
If if it doesn't exist, DA will fall-back to use the "internal_lang" directadmin.conf, variable, but access the po file using the .. method eg:
/usr/local/directadmin/data/skins/enhanced/lang/../locales.po
allowing the fallback to be used, even if the client has some other skin set, for the event where the other skin does not have locales.po file.
TODO: Fill with all languages/locales.
- WIth a lang value, eg:
CMD_JSON_LANG?lang=en
it will dump json for the given .po file.
A language po file can exist either at:
/usr/local/directadmin/data/skins/SKINNAME/lang/LANG/lang.po
where "lang.po" is the literal filename for the current LANG...
OR
/usr/local/directadmin/data/skins/SKINNAME/lang/LANG.po
where LANG.po could be any valid lower-case language or local name (instead of a directory), eg:
/usr/local/directadmin/data/skins/SKINNAME/lang/fr.po
- With everything:
CMD_JSON_LANG?default_data=yes
will include the array from #1, but will also have:
default[data]
containtaining the entire json array for the whole defautl language po file, eg:
{
"default":
{
"data":
{
#whole json output for "en" becaue id=en.
}
"id": "en"
},
"languages":
{
"en": "English",
"fr": "Français",
}
}
new
JSON for CMD_LOGOUT and CMD_LOGINIf you include GET:
json=yes
you'll get json output.
CMD_LOGOUT?json=yes
returns:
{
"result": "success",
"success": "logout"
}
if you were "logged in as" the User, and end up as the creator, you'll get:
{
"current_user": "admin",
"result": "success",
"success": "creator_logout"
}
where "admin" is the creator.
If a LOGOUT_URL was specified at login time, a value:
"LOGOUT_URL":"http://logout.com",
will also be present at logout.
CMD_LOGIN:
POST:
json=yes
note that is is a POST, not a GET for the login. GET will not be seen.
During login, if json=yes is included with the POST, you'll get output like:
{
"json": "yes",
"referer": "/",
"success": "yes",
"username": "admin"
}
If FAIL_URL was specfiied at login time, you'll get it in the output, eg
"FAIL_URL": "http://failure.com",
"LOGOUT_URL": "http://logout.com",
the LOGOUT_URL will also be shown if passed, but not likely you'll be using it.
new
http2=1 enabled by default for supported OSsDebian 9 has ALPN compiled into openssl by default.
DirectAdmin will use an #ifdef to control the default state of the http2= setting in internal directadmin.conf settings.
The actual directadmin.conf will still override it.
So the short version of this is, Debian 9 will have http2 enabled by default.
CustomBuild 2 will read the DA setting and adjust the httpd.conf accordingly.
Note that mod_php won't work, since http2 won't support prefork anymore.. so we may set Debian 9 to use php-fpm by default.
http://www.apache.org/dist/httpd/CHANGES_2.4.27
new
Custom Package Items skin up to 8 items (SKINS)The internal custom package item limit is 99.
However, the skins only had a set number of tokens filled in, previously 5.
This change increases that to 8 in the enhanced skin.
admin/
create_customized_reseller.html
modify_reseller.html
show_reseller_package.html
reseller/
create_customized_user.html
modify_user.html
show_user_package.html
new
CMD_CHANGE_INFO can set temporary language in sessionRelating to the usual way User would change their language:
this adds an extra option:
session=yes
such that it will save the language into the session file instead of the user.conf.
Then any future pages loaded, the language set in the session file will override the user.conf language.
This is useful if you have multiple people using different languages, logged into the same account at the same time.
POST:
CMD_CHANGE_INFO
language=<any text>
lvalue=en
session=yes
This will also affect the global |USERLANG| token.
new
Skins can provide their own login.html page or images (SKINS)If a skin creates the file:
login.html
in it's top level directory, eg:
/usr/local/directadmin/data/skins/enhanced/login.html
then whatever skin is set in the directadmin.conf for:
docsroot=./data/skins/enhanced
will be search for that login.html, and used if it exists.
The priority order is:
/usr/local/directadmin/data/templates/custom/login.html
/usr/local/directadmin/data/templates/login.html
${docsroot}/login.html
internal login page
======
Similarly, you can now create your own skin's "login_images" path, eg:
/usr/local/directadmin/data/skins/enhanced/login_images/logo.png
new
JSON for CMD_ALL_USER_SHOW, CMD_RESELLER_SHOW, and CMD_ADMIN_SHOWJSON support has been added for the commands:
CMD_ALL_USER_SHOW
CMD_USER_SHOW
CMD_RESELLER_SHOW
CMD_ADMIN_SHOW
where you simply add the GET request (not POST)
json=yes
and JSON is output.
The format for all 3 is similar, the existing table tokens are simply converted into json, so that we can maintain the searching, sorting and filtering features of the table class.
Like other json table output, the format is a list of numbers, representing the row index displayed.
Also an index called "info" is shown, to give info about the table:
"info":
{
"columns":
{
"username": "1",
"creator": "2",
"bandwidth": "3",
"quota": "4",
"vdomains": "5",
"suspended": "6",
"ip": "7",
"domains": "8",
"sent_emails": "9"
},
"current_page": "2",
"ipp": "50",
"rows": "69",
"total_pages": "2"
},
which is the "info" index for the CMD_ALL_USER_SHOW table.
The other 2 (Reseller and Admin lists) look like:
"info":
{
"columns":
{
"username": "1",
"bandwidth": "2",
"quota": "3",
"nusers": "4",
"vdomains": "5",
"suspended": "6"
},
"current_page": "1",
"ipp": "50",
"rows": "5",
"total_pages": "1"
},
where the "columns" sub-index represents the values shown in the table rows.
=================================
A sample CMD_ALL_USER_SHOW row would be:
"3":
{
"username": "admin:not_user",
"creator": "root",
"bandwidth": "2.76 / unlimited",
"quota": "18839.4 / unlimited",
"vdomains": "6 / unlimited",
"suspended": "no:",
"ip": "1.2.3.4:1.2.3.5:",
"domains": "domain.com:pointer_domain.com=pointer.com|pointer2.com|:domain2.com:pointer_domain2.com=domain2-alias.com|:domain3.com:",
"sent_emails": "2:1"
},
where:
- the username will contain the username, followed by a colon. After that, if it's a user, it will show "user". If it's not a user (admin or reseller), it will show not_user.
This is used to link to CMD_SHOW_USER or CMD_SHOW_RESELLER (even admin's go to their Reseller info page)
vdomains is the number of domains on the account, followed by a space, forward slash, space, then the limited (number in meg, or unlimited)
the suspend item is similar, where after the colon will be the suspended reason, if set. Can be blank. Example: "yes:inactive", where the reason is from the "reasons" list (see below)
ip list is colon separated.
domains are also colon separated BUT any domain that starts with "pointer_" is a list of domain pointers, for the domain name contained in the string after pointer_. The pointer list starts after the = character, and is pipe | separated.
sent_emails contains the total number of sent emails this month, and after the colon, it's the number sent today. Sometimes there will be no colon or trailing value, eg, "0"
The method is also adds an exrtra index, the other 2 don't have:
add_leave_dns
will be set to yes or no, to let you know if the "Leave Dns" checkbox should be shown (is controlled by the Multi-Server Setup clustering being turned on)
=================================
CMD_USER_SHOW
is very close to CMD_ALL_USER_SHOW, but without some of the columns:
"0":
{
"username": "testuser",
"bandwidth": "0.0000 / unlimited",
"quota": "11.0 / unlimited",
"vdomains": "1 / unlimited",
"suspended": "no:",
"ip": "1.2.3.4:",
"domains": "domain.com:"
},
it also does not have the "add_leave_dns" index, as it's not relevant for Resellers.
=================================
A sample CMD_ADMIN_SHOW or CMD_RESELLER_SHOW would be:
"0":
{
"username": "admin",
"bandwidth": "1.0217 / unlimited",
"quota": "19391 / unlimited",
"nusers": "45",
"vdomains": "67 / unlimited",
"suspended": "no:"
},
where the info is pretty much the same, but:
username does not need to be colon split, it's only the username, since the list is exactly the type you requested.
nusers is the number of User accounts created under this Admin or Reseller
=============
Reasons:
all 3 methods will also get a "reasons" index for the selectbox shown at the bottom of the GUI tables.
"reasons":
{
"0":
{
"selected ": "yes",
"text": "-- Reason:",
"value": "none"
},
"1":
{
"text": "Abuse",
"value": "abuse"
},
etc..
Where the "text" will be from the data/templates/suspension_reason.txt file, so may not be correctly translated (.po lookup?)
new
JSON for CMD_EMAIL_POPThis change allows the ability to use CMD_EMAIL_POP?domain=domain.com&json=yes to get JSON output.
The output will vary quite a bit depending on several conditions, so be sure to test all conditions, as each DA box might give different output.
Top level variables:
"count_pop_usage": set to 1 if enabled: option to disable quota counting for pop accounts page
"EMAIL_MESSAGE": this will usually be an empty string "" but if it isn't, it should be a general info string, shown to the User, eg:
"Until the cache is created, the values may not be correct. Refresh the page in 1 minute."
"pop_disk_usage_cache": set to 1 if enabled: email disk usage cache to speed up the pop page
"pop_disk_usage_true_bytes": set to 1 if enabled: Email Disk Usage opion to show true bytes rather than block usage
If enabled, then you'll need to show apparent_usage instead of usage (see below)
"user_can_set_email_limit": set to 1 if enabled: Per-Email send limit (SKINS)
"block_cracking_unblock": set to 0, 1 or 2, depending on: BlockCracking notices and unblocking (TEMPLATES) (SKINS)
"hide_outlook": usually 0, but if 1, don't show the outlook column with a url like:
CMD_EMAIL_REG/${domain}/${usernmae}/${login}/outlook_admin.reg
"purge_select": select box data for the account purge tool.
"when_select": "select box data for the "when" portion of the purge (eg: all or messages older than x days, etc..)
"emails": main data for all email account, including system account. This returns a "table" version of the json, so has the standard "info" sub-array giving info about rows, column names, etc..
Because it's a standard table, you can search, sort and filter, like a normal table.
===========
A sample row from emails might look like:
"4":
{
"account": "user@domain.com",
"login": "user@domain.com",
"usage":
{
"apparent_usage": "12.023",
"imap_bytes": "25047040",
"quota": "30",
"usage": "23.886",
"webmail_bytes": "0.000000"
},
"sent":
{
"send_limit": "42",
"sent": "1"
},
"suspended": "no:blockcracking:change_pass"
},
where this data can vary a lot depending on the values of the global settings above.
"login": this is straightforward, but will be just "user" for the syseem account.
"usage": This is dependant on "count_pop_usage", and if count_pop_usage=0, then only "quota" is shown, or nothing at all for system account.
"sent": if user_can_set_email_limit=0, this will not appear.
"suspended": usually "yes" or "no", but can be "no:blockcracking:change_pass" or "no:blockcracking:no_unblock", where it means the account is blocked via BlockCracking. If change_pass, then you can offer info that it can be unblocked by changing the password for this account, but no_unblock cannot be unblocked.
unblocking info: BlockCracking notices and unblocking (TEMPLATES) (SKINS)
Manually blocking a User can be done by adding them to /var/spool/exim/blocked_authenticated_users in the format:
user@domain.com:1501988529
where the right part is the timestamp when they got blocked.
IMPORTANT:
when coding with this json output be sure to test all of the directadmin.conf settings, off/on etc, and scenarios to ensure you're handling all cases.
Different servers will have different settings, thus different output.
new
session_destroy_pre.sh and login_key in sessionIf a session is to be destroyed due to old age, or due to logout, you can now create:
/usr/local/directadmin/scripts/custom/session_destroy_pre.sh
which will be called just before the session file at:
/usr/local/directadmin/data/sessions/sess_XXX is removed.
Environmental values passed will be the entire contents of the session file, plus:
file=/usr/local/directadmin/data/sessions/sess_XXX #path to the current session file.
Contents of a session file might look like this, but can vary:
home_memory=3
host=2.3.4.5
ip=1.2.3.4
key=SEbYTmsYQ7kccy0OhWenhidoEs6POWfqiEO2yHgPMQzyOxM3TAp9rfv5V2UtW7hE
login_key=keyname
passwd=base64encodedpasswd
selected_domain=domain.com
username=admin
Also changed, if a Login Key is used to login to DA, the login_key=keyname is added to the session file.
You can then get info on that login key with path:
/usr/local/directadmin/data/users/$username/login_keys/${login_key}/*
Note that this does not account for the "login-as" method which might set the username to be:
username=admin|fred
so be sure to check for that in the $username variable before using it, eg:
REALUSER=`echo "$username" | cut -d\| -f1
In the above example, the login_key and key pass would be from User "admin" and not "fred".
and use $REALUSER everywhere, instead of $username.
EXIT CODE
unlike other pre.sh script, the exit code of your script will not abort the deletion process, as we should never block the removal of a session.
That being said, I still recommend you use exit 0; at the end of your script, in case this policy does change later on.
new
json for CMD_USER_HISTORY & CMD_BANDWIDTH_BREAKDOWNCMD_USER_HISTORY?domain=domain.com&json=yes
will now give json output.
Also:
CMD_BANDWIDTH_BREAKDOWN?json=yes
OR
CMD_BANDWIDTH_BREAKDOWN?year=2017&month=7&json=yes
can be used.
new
JSON: large list of added commandsImplementations for more JSON output.
Add json=yes for GET to show info.
User Level:
CMD_USER_STATS
CMD_USER_HISTORY
CMD_STYSTEM_INFO
CMD_DB
CMD_DB_CREATE
CMD_DB_VIEW
CMD_DB_USER_CREATE
CMD_DB_USER_PRIVS
CMD_EMAIL_FORWARDER
CMD_EMAIL_VACATION_CREATE
CMD_EMAIL_VACATION_MODIFY
CMD_EMAIL_VACATION
CMD_EMAIL_AUTORESPONDER_MODIFY
CMD_EMAIL_AUTORESPONDER_CREATE
CMD_EMAIL_AUTORESPONDER
CMD_EMAIL_FILTER
CMD_EMAIL_LIST
CMD_SPAMASSASSIN
CMD_CHANGE_INFO
CMD_SUBDOMAIN (same as CMD_SHOW_DOMAIN for main list)
CMD_DOMAIN_POINTER
CMD_REDIRECT
CMD_LOGIN_KEYS
CMD_PERL_MODULES
CMD_LOGIN_HISTORY
CMD_HANDLERS
CMD_MIME_TYPES
CMD_SITE_BACKUP
CMD_CRON_JOBS
CMD_PROTECTED_DIRECTORIES
CMD_FILE_MANAGER/path?action=protect&json=yes
Other CMD_FILE_MANAGER json actions here: CMD_FILE_MANAGER action=json_dirs action=json_files action=json_all
CMD_EMAIL_USAGE?domain=domain.com&which=both&json=yes
Be sure to check for "sending_php_scripts" and:
"block_cracking_paths": "yes",
"block_cracking_paths_table":
which only show up if many sends have taken place, hitting some limit.
Reseller Level:
CMD_RESELLER_STATS
CMD_RESELLER_HISTORY
CMD_IP_CONFIG
CMD_NAME_SERVER
CMD_SHOW_USER
CMD_COMMENTS
CMD_SHOW_USER_PACKAGE
CMD_ACCOUNT_USER
CMD_EDIT_USER_MESSAGE
CMD_RESEND_EMAIL
CMD_MODIFY_USER
CMD_MANAGE_USER_PACKAGES
Admin Level:
CMD_SHOW_SERVICES
CMD_SERVICE
CMD_SHOW_RESELLER
CMD_ACCOUNT_ADMIN
CMD_ACCOUNT_RESELLER
CMD_EDIT_ADMIN_MESSAGE
CMD_EDIT_RESELLER_MESSAGE
CMD_MAIL_QUEUE
CMD_ADMIN_STATS
CMD_ADMIN_HISTORY
CMD_MODIFY_RESELLER
CMD_SHOW_RESELLER_PACKAGE
CMD_MANAGE_RESELLER_PACKAGES
CMD_ADMIN_BACKUP
new
Etag and custom cache timePreviously, static static files, images, css files, js, files, etc... all used a default cache time of 65536. (18 hours)
Now, DA supports Etags, so the browser can ask DA if any file has changed, and DA will respond accordingly if it has or has not.
Also, those static files will still have a default cache time, but is now lowered to be 3600 seconds (1 hour) AND you can change this value in the directadmin.conf.
The internal default is:
cache_time=3600
so override that if you want it to last longer/shorter, which can be handy if you're developing a new skin, and don't want to hard refresh everything all the time.
new
mail_sni for dovecot and exim sni certificatesThis will replace both dovecot_sni and exim_sni, even though the functionality is roughly the same.
The dovecot_sni and exim_sni options will be deprecated from the directadmin.conf, and replaced with a single option:
mail_sni=0
which is the internal default.
To enable it, set:
mail_sni=1
and any certificate that is saved, either by pasting it through the SSL page, or created/renewed via LetsEncrypt, will trigger a write.
The /etc/virtual/snidomains file should already be setup and used as the "valid cert index", and will be used to setup the dovecot domain sni config.
Can also set:
mail_sni=OFF
in the domain.com.conf to override domains that should not have it enabled.
Related: Ability to shut off dovecot_sni per-domain in the domains/domain.com.conf
When a signed cert and cacert are found, the domain.com.cert.combined file is created (similar to with nginx), and then all records in the cert are added to:
/etc/virtual/snidomains - for exim to use as a lookup - if a subdomain exists in some other domain, but is also in this cert, the last one added has priority (would be a newer, valid cert anyway)
/etc/dovecot/conf/sni/domain.com.conf - with each record in there, pointing to the correct cert.
REQUIREMENTS
OpenSSL and exim supporting SNI, usually CentOS 6 and higher.
Recent dovecot and ./build dovecot_conf, for support of:
/etc/dovecot/conf.d/95-sni.conf
/etc/dovecot/conf/sni/*
CustomBuild 2.0 to install the exim and dovecot configs.
secure_access_group=access should be enabled in the directadmin.conf, so that the certificates are chmod to 640 with group "access", so "mail" (within the access group) can read them.
INSTALL
cd /usr/local/directadmin
echo mail_sni=1 >> conf/directadmin.conf
service directadmin restart
cd custombuild
./build update
./build set eximconf yes
./build set eximconf_release 4.5
./build set dovecot_conf yes
./build exim_conf
./build dovecot_conf
IMPORTANT:
DirectAdmin will only accept valid signed certificates. If you use a self-signed certificate, or your own domain does not exist in the certificate, then DA will refuse to accept it, and won't add the values to:
/etc/virtual/snidomains
and will not create the dovecot sni file at:
/etc/dovecot/conf/sni/domain.com.conf
If you rename your domain to domain2.com, for example, the old values are removed from snidomains, and conf/sni/domain.com, and are only re-added if the above checks are still true.
Currently a certificate is only considered signed using the quick check where the Issuer and Subject values in the certificate must be different.
If you have a signed certificate which DA isn't accepting, please let us know, and include the certificate and ca bundle/chain so that we can check it out.
TASK QUEUE
To generate snidomains file:
echo "action=rewrite&value=snidomains" >> /usr/local/directadmin/data/task.queue
If you want to tell all live SSL domains to have their dovecot configs written, type;
echo "action=rewrite&value=mail_sni" >> /usr/local/directadmin/data/task.queue
echo "action=rewrite&value=mail_sni&domain=domain.com" >> /usr/local/directadmin/data/task.queue
this will recreate the sni/domain.com.conf for each SSL domain, plus one for the system hostname.
It will use the /etc/virtual/domainowners, to go through each domain, each cert, and remove any existing *:user:domain.com entries from snidomains, and re-add whatever is present.
new
Ability to always load all php-fpm settings into User nginx.conf: nginx_fpm_always_set=1New directadmin.conf option:
nginx_fpm_always_set=0
where 0 is the internal default, which can be set to 1:
nginx_fpm_always_set=1
and restart DA, to prevent the server{} entries from using:
include /usr/local/directadmin/data/users/username/nginx_php.conf;
and instead force the loading of the php-fpm settings right inside the nginx.conf for each domain.
This is already done in cases where Users have swapped php versions but this adds the option to do it all the time for other scenarios where you might need control tokens from the nginx_php.conf on a per-domain basis.
The nginx_php.conf is a per-User file, thus times where php is not swapped, but you need per-domain control, set this option to 1.
TOKENS
A change to how tokens are given to the php-fpm.conf template in per-domain mode (php versions swappped or nginx_fpm_always_set=1)
in that the previous tokens, although loaded in, where not sub-sorted.
For example, if you set:
|?USER=fred|
in the |CUSTOM| token at Custom Httpd Config -> domain.com, the CUSTOM token is available to it, but the php-fpm.conf doesn't have it set anywhere, so the sub-tokenization never happened.
I've added a pre-tokenizer on all values to set:
USER=fred
for all tokens given to the php-fpm.conf
Note, a new token container is created for the php-fpm.conf template, so if you set something right inside the php-fpm.conf, it will not carry up and on to other templates for the domain (eg: nginx_server_sub.conf), but the CUSTOM tokens set in the GUI will, as they always have.
This was done to isolate these changes, as we don't want the sub-tokenization to happen too soon, as the order of tokens (eg: CUSTOM) is important, if a value is set there, vs CUSTOM1 before it.. the (eg: the USER should only be set once |CUSTOM| is called, so fred shouldn't be set until that point)
new
http2 for nginx: new token |SPACE_HTTP2| (TEMPLATES)If http2=1 is set in the directadmin.conf, a token will be present:
SPACE_HTTP2= http2
where the value is " http2" or "".
Note that there is a space before the http2 value, so that we don't end up with a space in the template if http2 is turned off.
TEMPLATES:
nginx_ips.conf
nginx_server_secure.conf
nginx_server_secure_sub.conf
added |SPACE_HTTP2| after ssl, before the semicolon:
listen |IP|:|PORT_443| ssl|SPACE_HTTP2|;
If you're already using custom templates, this won't affect anything.
Note, that the |MULTI_IP| token will now automatically insert http2 if http2=1 is enabled.
per-User template changes for http2 are not required for apache, it's enabled in a global config.
new
login_pre.sh login_post.sh session_create_pre.sh to add $user_agent headerIf you're using the login_pre.sh, login_post.sh, or session_create_pre.sh, you can now access the environmental variable:
user_agent
which is the User-Agent header passed to DA in the request, should you need to check that to validation, eg:
user_agent=Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
new
private_html to public_html link by default (DEFAULT CHANGE)New directadmin.conf option, where the internal default is:
default_private_html_link=0
such that existing installs will not have any behavior change.
New installs have:
default_private_html_link=1
in the template:
/usr/local/directadmin/data/templates/directadmin.conf
so NEW INSTALLS will have this feature enabled by default.
Old/existing installs are unaffected.
When you add:
default_private_html_link=1
any domain created with SSL enabled will have a private_html -> public_html link, instead of a private_html folder.
This should save some confusion, as the internet is slowing moving towards 100% https, so there is less need for split folders.
Of course, you can still set the private_html to be a folder or link via:
User Level -> Domain Setup -> domain.com -> private_html setup for domain.com
RESTORES
There are several different scenarios to take into consideration.
We'll assume default_private_html_link=1 for all of these scenarios (default_private_html_link=0 is the old behavior)
A) Merge method:
Empty User and domain are created normally first, then restore in a 2nd step.
or User already exists, then restore to merge from backup
For a merge, if private_html->public_html already exists, but the backup has a private_html folder, the private_html folder has priority.
The link is removed before the tar extraction, and the data is extracted normally.
If private_html is a folder, and the backup has a link, again, the backup has priority.
This case means if you had any data in your private_html folder, it will be deleted, and replaced with the link from the backup.
OLD DATA WILL BE LOST if you had any data in the private_html before the restore.
Either way, backups have priority.
After a backup has been extracted, if there is no private_html at all in the backup (no link, no folder), then then original private_html, and old value it pointed to, will be restored (in case it was pointing elsewhere).
BUT if the file in the backup file: backup/domain.com/domain.conf has private_html_link=1, this causes an extra step to wipe the old private_html and replace it with a link (again, backup has priority, even if there was no link in the file).
So if you're doing something creative, where you don't want the domains/domiain.com/private_html in the backup at all, ensure private_html_link=0 is in the domain.conf file.
This probably doesn't apply to anyone.. as if it is set to 1, then the link would exist.. so might be a moot point.
B) restore creation
If the User does not exist prior to restore, then the User/domain will be created by DA at restore time.
With this case, the public_html/private_templates are not used, and backup has priority.
Related change: Skip all templates in ~/domains/domain.com upon restore creation
new
option: spam_inbox_prefix_name=INBOX.spamYou can now set a new value for INBOX.spam in the directadmin.conf.
This is the internal default:
spam_inbox_prefix_name=INBOX.spam
to add that to the directadmin.conf and adjust as needed, if you wish to use a different value.
It's only used when spam_inbox_prefix=1 is set, which is when INBOX.spam applied.
Simply swaps all INBOX.spam strings with the new value.
The leading dot is added internally, where applicable (eg, Maildir paths), so don't add a leading dot, else you'll get 2.
new
UserDir for nginx in shared IPs (TEMPLATES)Previously, only the server IP could use /~username access with nginx.
This change lets you use the shared IPs for /~username access.
Affects:
/etc/nginx/directadmin-ips.conf
Also, this is controlled by the CustomBuild 2.0 option for:
userdir_access=yes|no
but if DA can't figure it out (eg: it's not visibly set to no), it defaults to "yes".
Also make the apache UserDir settings enable/disable as well in the file:
/etc/httpd/conf/ips.conf
based on the options.conf userdir_access setting.
If you don't need it on, we do recommend shutting it off, eg:
./build set userdir_access no
./build rewrite_confs
TEMPLATES
nginx_ips.conf - Added just below the index line:
|*if HAVE_USERDIR_ACCESS="1"|
include /etc/nginx/nginx-userdir.conf;
|*endif|
ips_virtual_host.conf - Added the if settings (was always present before)
|*if HAVE_USERDIR_ACCESS="1"|
UserDir public_html
|*endif|
new
https for redirect domain pointers (TEMPLATES)Added the 443 code for VirtualHost/servers in the templates:
redirect_virtual_host.conf
nginx_server_redirect.conf
added only if the current domain has SSL enabled.
Requires the User's httpd.conf or nginx.conf to be rewritten.
If you want this feature (After updating DA), you can do it for the whole server with:
cd /usr/local/directadmin/custombuild
./build update
./build rewrite_confs
Note, SSL certificates used in the VirtualHost/server will be the ones from the master domain the pointer is created under.
To avoid SSL Certificate errors, you'll need to ensure that the pointer is also in the master domains certificate.
LetsEncrypt can do this for you, just an extra checkbox from the list.
new
Ability to change pm.max_children in php-fpm.conf (TEMPLATE)Template change.
Added:
|?MAX_CHILDREN=50|
to the top of the template (before |CUSTOM1|) and change the line:
pm.max_children = 50
to be:
pm.max_children = |MAX_CHILDREN|
this will not allow you to go to (for example)
/CMD_CUSTOM_HTTPD?user=fred&php-fpm=5.6
to add:
|?MAX_CHILDREN=100|
or any number you need, into the |CUSTOM1| token to increase the pm.max_children value.
new
Fill checkboxes in LetsEncrypt based on existing certificateIf you make a change to a LetsEncrypt certificate by requesting a new one, this feature will select all checkboxes based on the values in the current LE certificate, saving the need to re-check values that are already in the old certificate.
new
named-checkzone to be more strict with -k failNew internal default directadmin.conf option:
named_checkzone_level=fail
Where this setting is used with the named-checkzone query -k option.
The default used before (via absence of -k option) was warn.
It was found that some warnings returned by named-checkzone would actually cause a full failure in named, so the strictness level of this call had to be increased.
Valid options for named_checkzone_level are:
- fail
- warn
- ignore
If you find this to be too strict, set it back to level "warn" by adding:
named_checkzone_level=warn
to the directadmin.conf.
new
plugin_max_hooks to allow more pluginsNew internal directadmin.conf setting:
plugin_max_hooks=16
which replaces a hardcoded internal default.
Note that this never restricted the upper limit of plugins used, it did prevent the auto-filling of the blank plugin token values..
So if you had 20 tokens, and 8 plugins, the last 4 wouldn't be filled with "", and would end up showing "none".
So this variable simply sets the number of default plugin tokens to "".
new
Ability to disable forwarder pipesAbility to prevent processing email through email pipes.
Internal default is:
allow_forwarder_pipe=1
To disable it, add:
allow_forwarder_pipe=0
to your directadmin.conf file.
new
Periodically check to ensure versions.txt is being updatedIt's important to keep your server up to date. CustomBuild will help you update all of your services to their latest versions and config files.
You can either do this manually or have it check via cron, but in the event that perhaps you've forgotten to update it, or perhaps the update isn't working (say a files server has a stale copy),
this new feature will check to ensure that your file:
/usr/local/directadmin/custombuild/versions.txt
is no more than 30 days old.
It does this two ways:
login time, after a successful login to DA by any account, there is a 10% chance the check will trigger.
monthly reset will trigger the check each time.
New internal value:
cb_version_check_odds_percent=10
where it's the percentage chance for any login to trigger the check.
If you change this check to 0, then the check will never run for either the post-login trigger nor the reset.
fixed
MySQL 5.7.6+ dropped mysql.user password columnBETA
Although CustomBuild didn't get the MySQL 5.7 version added (because it had some conversion issues to MariaDB), we've also learnt that it dropped the password column completely:
http://dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-6.html
basically replacing it with a column called "authentication_string", but also means there are other required syntax changes that DA will need to do if MySQL 5.7 would be supported in DA.
To support the 5.7.6 changes, add
mysql_milestone_16=1
to your directadmin.conf, and restart directadmin.
Update: April 2018: CustomBuild DOES currently support MySQL 5.7, so setting the variable in the directadmin.conf should happen automatically.
More info:
https://www.mysql.com/why-mysql/white-papers/whats-new-mysql-5-7/
fixed
Backup dns: don't remove sole record if it's a linked IPSay you have a domain on 1.2.3.4, and you have 1.2.3.5 linked to it for dns, DA will duplicate all A/AAAA records accordingly.
So you'd have:
www A 1.2.3.4
www A 1.2.3.5
however, some people might manually change the ns1/ns2 records to look like this:
ns1 A 1.2.3.4
ns2 A 1.2.3.5
while the other records are doubled up.
When DA creates the backup, it will remove the linkeds IPs from the zone, leaving just:
www A 1.2.3.4
ns1 A 1.2.3.4
where this would actually cause the write to fail the zone write check, since if this was present:
domain.com. NS ns2
the ns2 A record is now missing.
This change is to check how many total A+AAAA records there are for that given name, and if there is only 1, then the value is not removed.
This can span AAAA records too, eg:
ns1 A 1.2.3.4
ns2 AAAA :::1:2:3:5
and DA will ensure if there is only 1 of either A or AAAA, that last value is not removed, even if it's only on the linked IP.
This will allow it to pass the zone check.
Backups will now also include the domains/domain.com.ip_list, so that DA can eventually be coded to know that the 1.2.3.5 value is an additional value, and should be swapped if the new server is using a different IP.
As this change currently sits, when you restore the zone, if you were to set the User/Domain to use 4.3.2.1, it would end up like:
www A 4.3.2.1
ns1 A 4.3.2.1
ns2 A 1.2.3.5
Since 1.2.3.5 is considered a "custom" IP at this point, since DA does not yet check that it's a linked IP (as the backup system only currently supports a single IP to restore to)
If you're restoring to the same IPs, then it should be fine, it just gets a bit messy if you're restore to a different IP, then 1.2.3.5 would need to be swapped accordingly after the restore.
fixed
More plugin hooks (SKINS)Added 4 more tokens for Admin, Reseller and User Levels, supporting up to 14 plugins.
admin/content_main.html
reseller/content_main.html
user/show_domain.html
fixed
Set language in dataskq for backup/restore messagesWhen doing language translations, there is an area of code called the "InternalText" class. This is used to translated texts set within the DA binaries, and not part of the html skin code.
When browsing in DA through port 2222, the language set set from the user.conf files, so DA knows which internal texts to use.
However, for dataskq task.queue commands, there is no login, so the language is not set, so some background messages might be in English, this is the bug.
Solution for the backup/restore is to set the docsroot and lang settings from the user.conf as needed, based on who called the backup/restore.
fixed
Don't count hard-links multiple timesFor the "Email Disk Usage" count, DA includes various areas, including:
/home/user/imap
/home/user/Maildir
which are files managed by Dovecot.
Dovecot often uses hard-links when copying messages around to save space, but when DA previously counted the disk usage, the same file might get counted many times.
This changes is to still count the same file multiple times, but if it's owned by the User and has multiple hard links, divide that file's current size by the number of hard links.
So if a file has 2 links, DA counts 1/2 the size twice, giving a more accurate result.
Note that this will not affect the total disk usage, which relies on the System Quotas, a completely different system.
This change will just make the results closer to the "du" output, which handles multiple hard-links in a different way (likely tracking all of their IDs in a hash)
but should arrive at the same result as long as the files are under the same path (which is why this is only done for specific dovecot paths)
This will also not affect the File Manager directory usage output for the above folders, so for example, the results you'll see for /home/user/imap will probably be different than the total that DA gets during the tally.
fixed
Removing additional IP from User that was in use by a domain causes wrong IP in configDuplicate:
User + domain assigned to server IP .1
Add an additional IP .2 to the User.
Login as the User, add .2 to the domain.
Remove .1 from the domain.
logout, back to creator, edit user and delete .2 from User.
Expected result would be everything, dns, all configs, revert back to .1.
What was happening, was close, but the domain.com.conf file did not get the last .1 user IP.
Previous check was checking if the domain.com.conf's IP was not in the domain.com.ip_list file, and use index[0] for the .conf ip,
but the domain.com.ip_list was actually empty at that point, so the conf overwrite did nothing, and left the previous .2 IP.
New check to ensure the "backup" IP used is not NULL, and if it is, use the user.conf ip.
fixed
swap gethostbyname with getaddrinfoWhen DA used to do lookups, it would use the older gethostbyname, which still worked fine.
However, to better support IPv6, I've switched over to getaddrinfo (which is newer anyway)
So any lookups that DA does, will now support IPv6.
However, DA still favors IPv4, so the hint will start with AF_INET, and only move to AF_INET6 if there are no IPv4s.
fixed
LetsEncrypt: remove deleted domains/subdomains from san_config before renewalIf you've got subdomains, create a multi-domain LetsEncrypt certificate to include those subdomains, and then delete the subdomain, the renewal would fail, because the san_config still has the subdomain listed.
Before any renewal call to letsencrypt.sh, DA will scan the list of subjectAltName=DNS entries, to ensure that:
they're a domain on the sysetm
or a subdomain of a domain on the system
or resolve to any IP that exists on the system (data/admin/ips/ip.list)
If not, it's removed from the domain.com.san_config, prior to the renewal via letsencrypt.sh.
fixed
Deleting a User with php-fpm while a php script is running throws errorIf you run php-fpm and the User's website is active when you delete it, this error may appear:
Unable to remove Unix User. Continuing with the other files.
userdel: user testuser is currently used by process 123456
DirectAdmin does scan for, and kill all Users processes before running the userdel command, however php-fpm is quick to spawn a new process for the User.
The solution is to delete the file:
/usr/local/directadmin/data/users/testuser/php/*
and quickly triggering a graceful reload of php-fpm before running userdel.
Currently, this is triggered multiple times if multiple Users are deleted, so we may need to change it.
Predicting the full list of Users is possible, but more difficult due to the recursive nature of Reseller, so for now the graceful trigger is done per-User being deleted.
As "graceful" restarts don't affect live requests, in theory, this should't hurt other Users, except those being removed.
Note, by "graceful", it will be whatever is the correct term for your OS, as it has several variables.
If "php_fpm_restarts=1" set, the "restart" is used.
if systemd, then reload is used,
else graceful is used.
fixed
CMD_SYSTEM_INFO not showing nginx for nginx_proxyFixed a few things in the CMD_SYSTEM_INFO area, mainly the missing nginx entry when the nginx_proxy is in use (both nginx apache are running)
Also enabled json=yes.
fixed
Double mysql_close call causes segfaultBug that has oddly only showed up on Debian 9, caused by 2 calls to mysql_close on the same pointer during a restore.
Main surprise is that other systems did not trigger a segfault. Found/fixed either way.
fixed
FreeBSD: apache_public_html not setting apache groupThe older apache_public_html=1 setting (Which is redudnant with secure_access_group, not no longer enabled by default) was not correctly setting the public_html folder to apache.
Linux is not affected, as the process group is applied to the folder, but apparently not with FreeBSD.
fixed
FileManager Edit: write to temp firstWhen saving an edit file, changed to save to a mkstemp file first, before renaming the successfully saved file to the original name.
This prevents files becoming 0 bytes if you save an edit to a full disk or full quota.
However, this also means that symbolic links will no longer be followed, if you editing a file through a link.
So if you were, be sure to edit the destination file, instead of the link.
fixed
Debian 7 cast bug for php-fpm versionsLikely an old compiler bug or something similar, where a double value of 71.0 cast to to (int) gives 70 (via options.conf php2_release=7.1, x10)
Solution (not great) is to add 0.00001 to account for the floating point rounding error, where the int always rounds down, so it will then end up with the correct 71.
Other OS versions don't seem to run into this rounding error.
Related to php-fpm config files, with Custom Httpd Config, eg:
/usr/local/directadmin/data/users/username/php/php-fpm70.conf.custom1
vs
/usr/local/directadmin/data/users/username/php/php-fpm71.conf.custom1
it was writing to the fpm70 file, when it should have been fpm71.
fixed
segfault (SECURITY) CVE-2017-18045Important security fix where a segfault from a specific request could allow a remote attacker unauthorized access.
For anyone who cannot update to this version of DirectAdmin (eg: end-of-life OS), please add:
email_ftp_password_change=0
to your directadmin.conf and restart DirectAdmin.
We won't be immediately commenting on the details of the bug to allow everyone time to update.
Update:
As some client have disabled their auto-update or have still not updated yet, to help get the message out more quickly, we've requested a CVE ID number:
CVE-2017-18045
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-18045
Related messages:
RoundCube:
"Could not save new password. The password changing feature has been disabled"