Version 1.56.0
Released: 2019-03-18
new
Subdomain owner check to include User domains below a ResellerRelating to this feature:
Option to prevent creating subdomain of a different user.
If a Reseller is creating a domain, this change will allow them to also create subdomains on any domains owned by any User account they've created.
So say a Reseller creates a User with user.com.
The Reseller will then be allowed to create sub.user.com under a different User, or their own account.
However, it does not allow Users themselves to create domains, or change their domain a subdomain value, belonging to a different User.
T14211
new
Widgets (SKINS)(LANG)Widgets are tabs that can be added/removed/re-ordered which let the User customize their main screen for the current access Level.
To enable widgets in your skin, you must first create a skin.conf, and add:
widgets=1
then setup the default widget lists in the skin.conf, and defaults if unset, eg:
admin_widgets=WGT_ADMIN_STATS:WGT_ALL_USERS:WGT_SHOW_SERVICES
admin_widgets_default=WGT_ADMIN_STATS:WGT_ALL_USERS
reseller_widgets=WGT_RESELLER_STATS:WGT_LIST_USERS:WGT_SKINS
reseller_widgets_default=WGT_RESELLER_STATS:WGT_LIST_USERS
user_widgets=WGT_USER_STATS:WGT_ADDITIONAL_DOMAINS
user_widgets_default=WGT_USER_STATS:WGT_ADDITIONAL_DOMAINS
Just as an example. The WGT_ values are your own creation, and can be named whatever you want. (A-Z and _)
If unset, the lists will be saved into the admin.conf, reseller.conf and user.conf.
The order of the list in the conf file determines the order the widget is displayed.
To specify what each widget will show, you must create a 'widgets" folder in your skin directory,
and each widget must have the files:
- tab.html
- content.html
- lang.txt
DA will set a token called:
WGT_ID
which starts at 1 and counts up for each widget used.
All global tokens are available.
But specific table data, use ajax or API type calls for detailed info for your widget.
LANGUAGE/TRANSLATION:
the lang.txt is just the base translation file.
It might have TITLE and DESCRIPTION, but can also have other tokens you want int the widget content.
The widgets can also be included in the actual language packs, if you wish, eg:
lang/en/widgets/WGT_ALL_USERS.txt
where "en" would be for english, and WGT_ALL_USERS.txt is a duplciate of the lang.txt file, but for this given language.
The "InternalText" class was adapted for this, so the search priority is:
Current skin, current language widget .txt file
Default skin (usually enhanced), then current language widget .txt file.
Widget's lang.txt
Note, we're going to standardize the language packs, so both the enhanced and evolve skins can use the same packs interchangeably.
new
CMD_WIDGETNew json-only output command for widgets:
CMD_WIDGET
List all loaded, widgets, and available widgets:
CMD_WIDGET
Sample:
{
"user_widgets":
{
"WGT_ADDITIONAL_DOMAINS": "Description",
"WGT_USER_STATS": "Description",
"WGT_DB": "Description",
"WGT_EMAIL_POP": "Description"
}
,"user_widgets_available":
{
"WGT_SYSTEM_INFO": "Description"
}
,"reseller_widgets":
{
"WGT_RESELLER_STATS": "Description",
"WGT_LIST_USERS": "Description",
"WGT_SKINS": "Description",
"WGT_IP_CONFIG": "Description",
"WGT_SYSTEM_INFO": "Description"
}
,"reseller_widgets_available":
{
}
,"admin_widgets":
{
"WGT_ADMIN_STATS": "Description",
"WGT_ALL_USERS": "Description",
"WGT_SHOW_SERVICES": "Description",
"WGT_IP_MANAGER": "Description",
"WGT_SYSTEM_INFO": "Description",
"WGT_MAIL_QUEUE": "Description",
"WGT_LICENSE": "Description"
}
,"admin_widgets_available":
{
}
}
Add a widget to a given level
CMD_WIDGET
GET options:
action=add
type=user_widgets|reseller_widgets|admin_widgets
widget=WGT_EMAIL_POP|etc..
Optional
position=3
where position lets you specify where it should go,
else it will go to the end.
Position 0 is the first position.
Move a widget up or down
CMD_WIDGET
GET options:
action=move
type=user_widgets|reseller_widgets|admin_widgets
widget=WGT_EMAIL_POP|etc..
direction=non-zero positive or negative integer, eg 1, 2 or -1, -2, etc..
where direction shifts the widget by that amount.
Delete a widget:
CMD_WIDGET
GET options:
action=remove
type=user_widgets|reseller_widgets|admin_widgets
widget=WGT_EMAIL_POP|etc..
Reset the widget list
CMD_WIDGET
GET options:
action=reset
type=user_widgets|reseller_widgets|admin_widgets
resets to the default from the skin.conf.
====================================================================
All of the action calls (add/move/delete) will get a json array either like:
{
"success": "widget WGT_EMAIL_POP set to 4"
}
or:
{
"error": "widget is not in the allowed list"
}
so it will be either a "success" or an "error" with a related message.
new
SPF: Swap old server IP with new server during restoreBackup will now store the old "server=" in the backup/user.conf, so DA will know what it was for swapping in the TXT/SPF records.
Only applies if you ensure the spf restore setting is enabled:
"Restore with SPF values from backup. (unchecked: Use local spf values)"
This should be fairly smart, relating to this similar restore change:
Restore: additional IPs for Users and domains
where a list of old to new IPs is assembled.
This change expands on that list, by also adding the old server IP to the new server IP.. so any other areas that had the server IP in the zone should be swapped to the new server IP.
new
CMD_FILE_MANAGER: action=parent_treeFor json calls like this:
CMD_FILE_MANAGER?json=yes&path=/domains/test.com&action=parent_tree
Returns 1 level of everything the current branch touches, but not lower.
This will be much faster for navigation trees, vs action=tree.
Sample output:
[
{ "path": "/domains/test.com/public_html", "dirs": 1, "files": 12, "files_size": 12949 },
{ "path": "/domains/test.com/.htpasswd", "dirs": 0, "files": 1, "files_size": 0 },
{ "path": "/domains/test.com/private_html", "dirs": 0, "files": 1, "files_size": 206 },
{ "path": "/domains/test.com/public_ftp", "dirs": 1, "files": 0, "files_size": 0 },
{ "path": "/domains/test.com/stats", "dirs": 0, "files": 29, "files_size": 315070 },
{ "path": "/domains/test.com/logs", "dirs": 0, "files": 5, "files_size": 7979 },
{ "path": "/domains/test.com", "dirs": 6, "files": 1, "files_size": 9703385 },
{ "path": "/domains/test2.com", "dirs": 0, "files": 0, "files_size": 0 },
{ "path": "/domains", "dirs": 1, "files": 0, "files_size": 0 },
{ "path": "/.php", "dirs": 0, "files": 5, "files_size": 0 },
{ "path": "/imap", "dirs": 1, "files": 0, "files_size": 0 },
{ "path": "/tmp", "dirs": 0, "files": 1, "files_size": 56 },
{ "path": "/.spamassassin", "dirs": 0, "files": 1, "files_size": 99 },
{ "path": "/Maildir", "dirs": 1, "files": 1, "files_size": 11 },
{ "path": "/.ssh", "dirs": 0, "files": 1, "files_size": 417 },
{ "path": "/", "dirs": 7, "files": 5, "files_size": 509 }
]
Where it prints lists:
all subfoldres of current path
all subfolders of each parent path, including /
new
CMD_FILE_MANAGER?json=yes&action=get_clipboardCleaner way for JSON to fetch clipboard data, and provides more info as well.
Previously, the .clipboard file might not have existed, so was an imperfect way to handle the list.
Sample output:
{
"data":
{
"/directadmin.tar.gz":
{
"date": "1312712544",
"gid": "admin",
"linkpath": "",
"permission": "744",
"showsize": "1.90M",
"size": "1992905",
"truepath": "/test.tar.gz",
"type": "file",
"uid": "admin"
},
"/public_html":
{
"date": "1541455507",
"gid": "admin",
"islink": "1",
"linkpath": "./domains/domain.com/public_html",
"permission": "777",
"showsize": "0.03k",
"size": "29",
"truepath": "/public_html",
"type": "dir",
"uid": "admin"
},
"/test":
{
"date": "1539610802",
"gid": "admin",
"islink": "0",
"linkpath": "",
"permission": "755",
"showsize": "4.00k",
"size": "4096",
"truepath": "/test",
"type": "dir",
"uid": "admin"
}
}
}
Note: directory size is not recursive, this would be too slow and beyond the intent of this feature.
new
Evolution: Widgets for pluginsAbility for plugins to provide their own widgets.
Sample plugin to test with:
https://www.directadmin.com/hello_world-1.1.tar.gz
but rename it to hello_world.tar.gz before installing it, as DA would end up calling it hello_world-1 and the links inside would be broken.
This 1.1 path is just temporary for testing.
PLUGIN.CONF
similar structure to skin.conf, eg:
admin_widgets=WGT_PLUGINS_ADMIN_HELLO_WORLD:WGT_PLUGINS_ADMIN_HELLO_MARS
admin_widgets_default=WGT_PLUGINS_ADMIN_HELLO_WORLD
reseller_widgets=WGT_PLUGINS_RESELLER_HELLO_WORLD
reseller_widgets_default=
user_widgets=WGT_PLUGINS_HELLO_WORLD
user_widgets_default=WGT_PLUGINS_HELLO_WORLD
WGT_PLUGINS_ADMIN_HELLO_MARS=Hello Mars
Where the format should start with the given level, as per above (eg: WGT_PLUGINS_ADMIN to match an admin level call)
WIDGET TEXT
Can have multiple widgets for each level, separated by a colon.
By default, the plugin.conf: "name=" vaule will be the text for the plugin.
For other names, or if you have more than one widget, you can set that widget name in the plugin.conf, eg:
WGT_PLUGINS_ADMIN_HELLO_MARS=Hello Mars
TODO: language/translation ability for widget texts.
NAMING RULES
Your plugin widget name mus start with one of:
WGT_PLUGINS_ADMIN_
WGT_PLUGINS_RESELLER_
WGT_PLUGINS_
the suffix after this naming can be anything you want, but best to keep it unified with something similar to your plugin name.
This is to avoid duplicates.
WIDGET TABS
The default request:
CMD_WIDGETS?json=yes&level=user
will include any plugin widgets/names in the usual area (eg: user_widgets),
but any extra widget tabs will be in an array beside user_widgets, eg:
,"user_widgets_tabs":
{
"WGT_PLUGINS_HELLO_WORLD":
{
"img": "CMD_PLUGINS_ADMIN/hello_world/images/hello_world.svg",
"tab": "Details from tab.html",
"title": "Hello World!",
"url": "CMD_PLUGINS/hello_world/index.html"
}
}
where, if a widget is listed there, this should take precedence (As you'd likely not be able to get the info from anywhere else).
Although in reality, if you see it listed there, it's not likely a usual widget, so use it's data either way.
Similar for reseller_widgets_tabs, admin_widgets_tabs.
SHOWING THE WIDGET
new command options for CMD_WIDGET, eg:
CMD_WIDGET?json=yes&show=WGT_PLUGINS_ADMIN_HELLO_WORLD&item=both
where we want to "show" the current plugin widget.
The "item" can be one of:
item=tab
item=main
item=both
where tab is the left side html to click each widget.
main is the right side that fills the widget content
and both returns both the tab and main content (default if no "item" is passed)
The "level" variable is not required, as DA can decipher it from the WGT name.
SHOWING MULTIPLE WIDGETS
Similar to the above show= call, you can alternatively use:
CMD_WIDGET?json=yes&item=main&select0=WGT_PLUGINS_ADMIN_HELLO_WORLD&select1=WGT_PLUGINS_ADMIN_HELLO_MARS
for example, in addition to the rest of the requests.
You can still use show= in addition to select0+.
Note that select0 is the trigger to look for the list, so you cannot start from select1 and go up.. must start from 0.. then any number is fine (does not need to be in order)
PLUGIN FILES
plugins/YOURPLUGIN/widgets/WGT_PLUGINS_ADMIN_HELLO_WORLD/tab.html
plugins/YOURPLUGIN/widgets/WGT_PLUGINS_ADMIN_HELLO_WORLD/url.html
plugins/YOURPLUGIN/widgets/WGT_PLUGINS_ADMIN_HELLO_WORLD/main.html
plugins/YOURPLUGIN/widgets/WGT_PLUGINS_ADMIN_HELLO_WORLD/img.html
plugins/YOURPLUGIN/widgets/WGT_PLUGINS_ADMIN_HELLO_WORLD/vue.html
plugins/YOURPLUGIN/widgets/WGT_PLUGINS_ADMIN_HELLO_WORLD/title.html
which will be run through the plugin system, so you can execute code there as need, but not if it's ever going to be slow.
REQUIRED
The tab.html is the basic description inside the tab itself, but should not include the tab title.
See the WIDGET_TEXT, above for that.
REQUIRED
The url.html would need to echo something like this:
CMD_PLUGINS/hello_world/index.html
without a trailing newline
pointing to where you want the "view full details" link to take you, usually a link with the full output, rather than the minimal output from main.html
REQUIRED
main.html is the right-side of the widget.. the html data shown when you click that widget's tab.
Can be tables, whatever you'd like.. a staging point, etc.. but as mentioned, it's best that if it's slow, you use ajax to load some other data.
The widget call won't return until everything is ready to go, so if you have a slow call, it will hold up the entire widget page.
Instead, use ajax to make a call to your plugin, perhaps in an iframe or something like that, to load the data in later on.. so the page can be shown more quickly, and then the widget main data just filled in once the ajax call is done.
To avoid JS conflicts with the skin, and to satisfy the quick page loads, it's likely simplest to use an iframe in main.html, and load your other page inside that iframe.
OPTIONAL
img.html returns a URL the skin can use as an image/icon to be shown in the tab itself. Use .svg if you can, square aspect ratio.
Do not output a trailing newline character.
OPTIONAL
vue.html, similar to the other one-line URL output script, this will output the URL to access to your /vue/* files.
OPTIONAL
title.html - the title of the widget. This is a script, like all others, and the LANGUAGE env variable is set (Eg: to 'en' or other)
So if you want your plugin widgets to support different languages, check this variable and output as needed.
Stick with UTF-8 encoding, which is what Evolution uses.
If you do not plan on translating your plugin, then we don't recommend using this file, in order to improve performance.
If absent, DA will grab the "name=" from your plugin.conf instead..
Or if the widget name is set in the plugin.conf, you can override the title that way too
eg in plugin.conf:
WGT_PLUGINS_ADMIN_HELLO_MARS=Hello Mars!
FILLING MAIN AREA
widgets are typically loaded with ajax or in real-time when you click that widget tab.
So the main html area usually should not be your final data..
instead it should contain code to write that content to the widget, so as to not slow down the loading of the widget list.
If running the tab or main code is not a time-intensive run, then you could just load your final data directly from the tab/main html files.
But if they could ever be slow, you could have the main/tab code be fully static (more or less), and have the time-intensive call be done,
loaded from a CMD_PLUGIN/yourplugin/user_widget.html, or example, and load that into the main area, using ajax/JS type code from your main.html
REFRESH INTERVALS
you can specify:
refresh_interval=10
in the plugin.conf to have all plugin widget to refresh every 10 seconds, done automatically by the skin.
Will basically just reload the main.html area.
You can restrict it to only given widget with:
refresh_interval=10:WGT_PLUGINS_ADMIN_HELLO_MARS
to only have WGT_PLUGINS_ADMIN_HELLO_MARS refresh every 10 seconds, but all other widgets in the plugin will not refresh at all.
Span all levels with this setting. Cannot currently specify different interval
DELETING A PLUGIN
When deleting a plugin, the user_widgets value in the user.conf (and other levels) will not be immediately touched.
The full list of possible skin and plugin widgets is known, so if the combined list of possible widgets does not list a given widget that the user.conf is trying to use, it's not shown, and removed from the user.conf's user_widgets list.
new
always_load_all_script_env_vars for session variablesThe all_pre.sh and all_post.sh will end up loading in some specific environmental variables.
In some cases, these still hang around for other custom hook scripts, which is sometimes useful.
The issue is that we might not want to impose the large overhead of these scripts, just to have those variables loaded.
Solution is a new internal variable, off by default:
always_load_all_script_env_vars=0
So that when you turn it on in the directadmin.conf:
always_load_all_script_env_vars=1
even if the all scripts are not present, DA will still load in the environmental variables from these scripts, so the might be available later on.
new
Default crypt_method=6 for sha-512CentOS 7 and FreeBSD 11 (and all going forward) will have their internal default changed from:
crypt_method=1
to now be:
crypt_method=6
any new password being saved by DA will now use this format.
Existing md5 formats will still continue to work normally, as the crypt() function knows the has type when checking.
new
php-fpm.conf: pm.max_requests = 500 new default (TEMPLATES)To clear possible memory leaks from php or 3rd party libraries, reloading the php-fpmXX services after 500 requests can be done.
If there are leaks, this will help keep runaway memory leaks to a reduced amount of overhead.
New default in the template:
/usr/local/directadmin/data/templates/php-fpm.conf
=======
|?MAX_REQUESTS=500|
...
pm.max_requests = |MAX_REQUESTS|
========
where the |CUSTOM1| token can be filled to override this limit, but setting something similar to the |?MAX_REQUESTS=500| in the CUSTOM1 token, but with a desired value.
Using 0 will disable the reload count (which is internal default in php, if unset).
new
reseller.conf: suspend_at_limit overridePreviously, the only global setting for "Suspend at Limit" for Reseller accounts is at:
Admin Settings -> Suspend a Reseller and their Users when the Reseller goes over their Bandwidth limit.
This feature allows the variable:
suspend_at_limit=ON|OFF
which can be ON or OFF, where the set value will override the global Admin Settings option.
If no suspend_at_limit is set in reseller.conf, or it's set but not set to ON nor OFF, then it's ignored, and the global Admin Settings value is used.
NOTE:
The admin.conf uses suspend=YES|NO for the global feature, but the decision was made to match the user.conf suspend_at_limit naming scheme.
new
Plugins: admin_run_as=rootAdmin Level plugins are now allowed to run as root, but only if:
plugins_allowed_run_as=1
is enabled in the directadmin.conf,
and if the plugin has this set in it's plugin.conf:
admin_run_as=root
Reseller and User Level plugin call cannot run as root.
If you need root access, you'd need to use a wrapper.
NOTE:
Running a plugin as root can be very dangerous.
If you chose to use this option, only do so with an extreme level of variable input sanitation and checking.
If making calls to things on disk, ensure nothing passed with the input can be used in a mischievous manner (like paths with ../ in them, etc).
If you make many calls which could be run as a less privileges User, consider using this guide to make those call with sudo AS that user, instead of full root:
https://help.directadmin.com/item.php?id=680
allowing your script root access, but the security for the user-access calls from that script.
new
Load Notice: extra_load_info.sh (TEMPLATES)Another script at:
/usr/local/directadmin/scripts/extra_load_info.sh
which can be cutomized by copying it to:
/usr/local/directadmin/scripts/custom/extra_load_info.sh
which will output the top 10 processing using the most memory.
As well as vmstat to get more info on the swap memory usage, 3 iterations (3 second delay, which is fine, as it's called by the dataskq in the background)
This script is trigger when the load of the box is above the amount specified by directadmin, eg:
check_load=10
check_load_minute=5
TEMPLATE
/usr/local/directadmin/data/templates/load_check_message.txt
added token:
|EXTRA_INFO|
new
CMD_JSON_VALIDATE: type=email allow check for mailing listRelated command:
CMD_JSON_VALIDATE?json=yes&value=user@domain.com&type=email
can now be extended to:
CMD_JSON_VALIDATE?json=yes&value=user@domain.com&type=email&check_mailing_list=yes
which also checks to see if a mailing list exists, if you're creating an email account.
Returns json error if hit:
"There is already a mailing list alias with that name"
new
custom scripts variable: login_key_nameSimilar to the "login_as_master_name" variable that's set if present, a new variable will be set in all custom hook _pre.sh/_post.sh scripts, if it's available:
login_key_name=keyname
which will be the name of the key used to login, if the login was done using a "Login Key"
Note, that custom hooks scripts can be called by things that do not use a login at all, such as restores, or things like that.
So there is no guarantee that it will be set if any of those other methods are used... not to mention all normal logins not using a login key 😃
new
Plugins: ability to update with task.queueYou can now tell DA to update plugins from the task.queue. Sample command:
echo "action=plugin&value=update&select0=hello_world" >> /usr/local/directadmin/data/task.queue
You have multiple Admin accounts, you can specify the one you want by including username=admin to the list.
If no username is passed, directadmin will read the admins.list file and use the first entry found.
Some plugins do need the correct Admin account to be set, so ensure you're calling the update as the correct account for those cases.
new
Plugins: global vueIf you set:
vue=yes
or
vue=1
or
vue=http://localhost:3000/
in your plugin.conf, the plugins request page:
CMD_PLUGINS_ADMIN?json=yes
CMD_PLUGINS_RESELLER?json=yes
CMD_PLUGINS?json=yes
will add (use admin as an example)
"vue": "/vue/admin.js"
into the "hooks" array, for that given plugin, if the file exists:
/usr/local/directadmin/plugins/hello_word/vue/admin.js
Also applies to reseller.js and user.js.
Evolution will pick this up for it's vue system.
If vue= starts with http, then a vue override mode kicks in.
In the above example, we show:
vue=http://localhost:3000/
which starts with http, thus applies. In that case, if the admin.js (or reseller.js/user.js) exists, the vue json output would be:
"vue": "http://localhost:3000/admin.js"
new
SSL Certificates: Allow www.domain.com in Common NameNew directadmin.conf option, with internal default:
certificate_common_name_with_www=0
where, if you set it to 1 in your directadmin.conf:
certificate_common_name_with_www=1
this will use:
CN = www.domain.com
instead of the previous value using 0:
CN = domain.com
All other settings will remain unaffected.
1.56.3: Changed the CMD_SSL page to use |WWW_DOMAIN| token for "Common Name".
With certificate_common_name_with_www=1, WWW_DOMAIN=domain.com.
With certificate_common_name_with_www=0, WWW_DOMAIN=www.domain.com
so that when DA prefixes the common name with www, it's not doubling up in the san request.
new
MySQL: new user methods: ALTER USER, DROP USER, etc. (SCRIPTS)TODO: Known bug: MySQL 8.0 does not allow "IDENTIFIED BY" with GRANT, so that also needs to be changed.
Relating to the forum request:
http://forum.directadmin.com/posts/290690
We've added an internal option:
mysql_use_new_user_methods=0
where if you set it to 1 in the directadmin.conf and restart directadmin:
mysql_use_new_user_methods=1
DirectAdmin will use the newer methods for controlling accounts, such as:
ALTER USER
DROP USER
RENAME USER
GRANT/REVOKE USER
....
Users are still added to DBs as before, using the GRANT option.
Listings of accounts will continue to use the SELECT method, local retrieval shouldn't affect saving to a cluster.
T12523
SCRIPTS
change_database_username.php
removed the old UPDATE mysql.user and UPDATE mysql.db methods, in favor of the RENAME USER for the system account name.
Had to loop through each access host for it to apply to all entries, but it simplies this in that is covers both mysql.user and mysql.db in one call.
MAJOR CODE REWRITE
There was a massive number of query lines touched, and new function calls created to handle this alteration (the "diff" output has 20 pages of line changes)
The main issue was that the previuos UPDATE calls handled all "host" entries by simply omitting them.
The ALTER/DROP/RENAME, etc.. all require the specific host to be used (cannot specify %, as that's also a literal value), so functions with loops to query all hosts, and update every entry one by one were needed.
As such, during the BETA release phase, this would be a key point for testing, backup/restore, as well as db/user creation, password changing, access host adding/removing, and privilege changing.
Also, the new GRANT/REVOKE method (also requires calling once per host), but if you set all privileges to "No" ('N'), the REVOKE call will actually fully delete the line from the mysql.db, which is not what we want.
So DA now blocks anytime you try to set N for every privilege, only for the mysql_user_new_user_methods=1 (0 still allows it)
new
Domains: user.conf to block domain adding/deletingNew custom user.conf option:
users_can_add_remove_domains=0|1|2
where it's not present in the user.conf by default, and internally loads to 0.
If added to the user.conf, you can set it to 1 or 2 where:
users_can_add_remove_domains=1
will block the ability to delete any domain.
users_can_add_remove_domains=2
will block the ability to add or delete any domain.
DIRECTADMIN.CONF
The directadmin.conf file now also has a duplicate of this setting, which will be the default, taken first.
It defaults to 0 internally.
If set to 1 or 2 or in the directadmin.conf, this will be the new global default.
The user.conf value will override it, if set (eg: can override back to 0 in the directadmin.conf, for example)
T14300
new
Up to 4 php versions in DirectAdmin and CustombuildTESTING
With this change, the CustomBuild 2.0 options.conf can support up to 4 php versions, eg:
php1_release=7.2
php1_mode=php-fpm
php2_release=5.6
php2_mode=php-fpm
php3_release=7.0
php3_mode=php-fpm
php4_release=7.1
php4_mode=php-fpm
No templates changes are needed.
The POST to CMD_DOMAIN action=php_selector now supports values upto the number of php versions installed.
So php1_select can be set to 1, 2, or 4.
The php2_select can also be set to 0, but the current internal default doesn't show the 2nd php selector.. since most people don't need 2 php versions live at the same time.
Any of the 4 versions can be set to php1_select, which is sufficient almost all the time.
Be sure to run "./build update" to get the latest version of custombuild.
Also updated CMD_CUSTOM_HTTPD to show correct php-fpm select (also defaults to just 1 php now, based on php_version_selector=1)
And fixed a bug where "php 7" should have shown up as "php 7.0" in various areas.
new
Drop TLSv1.0 and TLSv1.1 in DirectAdminDirectAdmin will now fully drop older TLS methods from connecting to port 2222.
For older binaries that don't support TLS 1.2, it will revert to the highest possible server method, with priority top-down being:
TLSv1_2_server_method()
TLS_server_method()
SSLv23_server_method()
where SSLv23_server_method does not imply SSLv2 or SSLv3, but is there from the older openssl libraries to be used for all possible methods (name is misleading)
There are not currently any directadmin.conf options to downgrade your server_method, but if you do need it, let us know and we can look at adding them.
You really should be upgrading your client if it doesn't support TLS 1.2 😃
WORKAROUND - Insecure
If you really need to connect to a DA box, but the client does not support TLS 1.2, then the current workaround is to set that DA box to run on both https:2222 and http:2223 at the same time,
where 2222 is still https/secure, but 2223 is not. (swap 2223 with some high random port number, and set your firewall to only allow the client IP to connect to it)
The DA settings for https on 2222, and http on 2223 would be:
SSL=0
port=2223
ssl_port=2222
where 2223 uses SSL=0, but the secondary setting ssl_port=2222 runs a 2nd fork of the master for SSL/TLS 1.2 connections, as before.
If the client is another (older) DA box, then the connection should be using a Login Key, restricting both the IP, functions, as well as the firewall.
It's not perfectly secure, but neither is using TLS 1.0/1.1.
new
php-fpm.conf to support ACTIVE_USR_LOCAL_PHP_LIB tokennew token, filled based on the options.conf settings for php, only filled with active php versions on the system.
ACTIVE_USR_LOCAL_PHP_LIB
sample output:
/usr/local/php72/lib/:/usr/local/php56/lib/:/usr/local/php70/lib/:/usr/local/php71/lib/
if you have this in the options.conf:
php1_release=7.2
php1_mode=php-fpm
php2_release=5.6
php2_mode=php-fpm
php3_release=7.0
php3_mode=php-fpm
php4_release=7.1
php4_mode=php-fpm
regardless of which php modes the User has enabled.
new
Backup Settings: can change related directadmin.conf settingsEvolution only at the moment.
The Admin Level -> Admin Backup/Transfer -> Backup/Restore Settings
will now include the related directadmin.conf options in the json out from:
CMD_ADMIN_BACKUP?json=yes
"settings" : ...
"directadmin_conf":
{
"add_non_readable_files_to_strict_backup":
{
"type": "i01",
"value": "1"
},
"allow_backup_encryption":
{
"type": "i01",
"value": "1"
},
....
"backup_nice":
{
"type": "ir:-20:19",
"value": "19"
},
...
Where you can add the settings below to the existing action=setting form.
Use only the desired settings, as some are more advanced.. might not be 100% suitable for novices to change them.
For example if you set strict_backup_permissions=0 (not recommended), then you must have backup_hard_link_check=1.
DA will let you set what you want, but the skin should not allow those combinations.
The manual directadmin.conf would allow it, but would be somewhat of a security issue, as strict_backup_permissions=0 runs backups as root.
For the novice User, these might be simplest to show:
backup_ftp_pre_test
backup_ftp_md5
allow_backup_encryption
restore_database_as_admin
tally_after_restore
backup_hard_link_check (only show this option if strict_backup_permissions=1)
But the following settings are available if you want them:
skip_hometargz_in_backups
skip_domains_in_backups
skip_imap_in_backups
direct_imap_backup
skip_uebimiau_in_backups
skip_roundcube_in_backups
skip_databases_in_backups
skip_ftp_on_backup_fail
backup_apache_files_list
allow_backup_exclude_path
backup_hard_link_check
strict_backup_permissions
add_non_readable_files_to_strict_backup
backup_ftp_pre_test
backup_ftp_md5
allow_backup_encryption
backup_gzip
backup_nice
add_non_readable_files_to_strict_backup
restore_database_as_admin
tally_after_restore
where each setting includes the current value from the directadmin.conf, but also that setting "type".
The current types are:
i01: integer, either 0 or 1.
b01: boolean, either 0 or 1
i: integer: anything from -2147483647 to 2147483647.
ir:low:high: integer range, with numerical low and high values. See "backup_nice" example, above.
The implementation of the "type" option is a change to the core Config class, where that class doesn't more checking of it's own.
Will be adding those type checks more in the future for other directadmin.conf options, but for now, it's just these backup options, only in the Admin backup/restore settings.
new
Ability to delete domain in the background via the task.queueRelated to backgroun User deletion (see related links), this new feature lets you delete a domain from the task.queue.
Sample call:
action=delete&value=domain&requestedby=admin&select0=domain.com(&select1=domain2.com...)
Where options:
requestedby=admin : controls where the result Message is sent to in the Message System. Success or fail.
It does not have to be the owner of the domain, but can be.
The actual domain owner is looked up for each domain.
select0=domain.com : the domain to be deleted:
(select1=domain2.com : optional other domains, for any User, does not need to be under the same User. select2=, select3=, etc.)
new
Option to notify all Admins about the creation of any account typeNew directadmin.conf option, defaults to:
notify_admins_on_all_account_creation=0
where, if you set it to 1 in the directadmin.conf and restart DA:
notify_admins_on_all_account_creation=1
Any account, created by any account type (including Resellers), will notify all Admin accounts through the Message system about the creation.
Sample message:
Subject: User account testtest has just been created
Account resellerbob has just created User testtest from IP 1.2.3.4
Domain: useradminnotify.com
new
Ability for Reseller/Admins to message all E-Mail accounts on the system (SKINS)(LANG)Tool giving Admins/Reseller the ability to quickly message all email accounts on the system.
Must be "local" accounts, meaning it will only deliver to local domains listed in /etc/virtual/domains.
Relating to the "Create Message" tool, eg:
A) Admin/Reseller Level -> Manage Tickets -> Send Message
B) Admin Level -> Show All Users -> (select user checkboxes) -> Send a Message
C) Reseller Level -> List Users -> (select user checkboxes) -> Send a Message
This tool will show a 2nd checkbox beside the "Email Only" checkbox, when the "Email Only" checkbox is checked.
The new checkbox shows up as;
[ x ] All E-Mail Accounts
and if this is checked when submitting the "E-Mail Only" message, that message is:
Delivered to all User/Reseller accounts that were specified/selected, just as before
Plus all E-Mail accounts that exist under domains for those selected User accounts.
For Admin's, as there is no "All users on the system" option for A/B (above), the only way to truly message all email accounts on the system,
is to use:
Admin Level -> Show All Users -> Advanced Search -> Items per Page = "All" -> Search
Then top right, click "Select", scroll down, and click "Send a Message".
Ensure both "E-Mail Only" and " All E-Mail Accounts" are both selected when sending the message.
BACKGROUND DELIVERY
Since the list of email accounts is assembled before delivery, this list can get to be rather large.
As a result, like the user=multiple, user=all, user=all_resellers options, the all_email_accounts=yes option will also push delivery to the background with the dataskq,
and the sender will get a Message System notice after it's sent.
LIMITS
The "All E-Mail Accounts" will send those virtual E-Mails as the Admin/Reseller, rather than "diradmin" which is used for the system account "E-Mail Only" part.
This means that if there are any blocks by exim for this account to send emails, they will be handled accordingly.
Note: the SpamBlocker outbound limits do not apply to local email delivery, so that's not really an issue.. probably would mainly just apply to full system account email delivery blocking, like:
/etc/virtual/blacklist_usernames
/etc/virtual/blacklist_script_usernames
SKINS
user/ticket/create_multiple.html
user/ticket/create.html
within the |*if SHOW_EML_ONLY="yes"| section add checkbox for <input type=checkbox name=all_email_accounts value='yes'>
This should be hidden/disabled if the "E-Mail Only" option is not enabled, and visible when "E-Mail Only" is enabled.
Note that the E-Mail Only checkbox can be checked when it's loaded, so if it is, show the new checkbox on page load.
lang/en/user/ticket/main.html
LANG_ALL_EMAIL_ACCOUNTS=All E-Mail Accounts
LANG_ALL_EMAIL_ACCOUNTS_DESC=Selecting this option will apply only to E-Mail accounts under to the selected DirectAdmin accounts at or below your level
lang/en/internal/command.txt
627=%s account %s has just been created
628=Reseller
629=Admin
630=Account %s has just created %s %s from IP %s
new
MX record templates (SKINS)(TEMPLATES)Users can pick google/zoho from a list, to remove their MX records and replace them with the values in the template.
New item at the bottom of the page:
CMD_DNS_MX?domain=domain.com
"Set remote MX records"
Enabled by default in the directadmin.conf:
mx_templates=1
to disable it, set:
mx_templates=0
and restart directadmin.
Note: It does not change the "Local Mailserver" checkbox, this is still manually controlled.
TEMPLATES
new directory:
/usr/local/directadmin/data/templates/mx
with 2 default templates:
- google.com.txt
- zoho.eu.txt
Containing their default MX record settings for those services.
The top will also set:
|?NAME=Google Suite MX|
To give the select box a human readable name, but the selected value in the form is still google.com.txt.
CUSTOM TEMPLATES
You can add more .txt files into the templates/mx directory (in theory they could be overwritten if we ever "happen" to include files with those names),
but if you want to override the 2 .txt files.. or just add more in a more clear way, this is the custom mx templates path:
/usr/local/directadmin/data/templates/mx/custom/
SKIN
user/dns_mx_control.html
uses the token check, representing the mx_tokens=1 directadmin.conf value:
|*if MX_TEMPLATES="1"|
The |MX_TEMPLATES_SELECT| token contains the selectbox for the available templates, plus "default" to revert the User back.
POSTING CHANGES
CMD_DNS_MX | CMD_API_DNS_MX
method: POST
action=mx_template
domain=domain.com
mx_template=google.com.txt|zoho.eu.txt|default
JSON
CMD_DNS_MX?domain=domain.com&json=yes
will return one new entry if mx_templates=1 is enabled in the directadmin.conf.
If it's not present, then it's either shut off, or an older directadmin version.
"mx_templates":
{
"mx_templates_select":
{
"0":
{
"selected": "yes",
"text": "-- Select MX Template --",
"value": "..."
},
"1":
{
"text": "Revert to Local Default",
"value": "default"
},
"2":
{
"text": "Google Suite MX",
"value": "google.com.txt"
},
"3":
{
"text": "Zoho Mail",
"value": "zoho.eu.txt"
}
}
}
new
Rspamd: binary replacement of SpamAssassin (TEMPLATES)Early support for Rspamd, which is a compiled binary, so should have much better performance than SpamAssassin.
https://rspamd.com
It's a smtp-time process only, so you must be using EasySpamFighter to use rspamd.
All existing SpamAssassin settings will remain, and be used as the config for the per-User rspamd settings.
Specifically, the /home/username/.spamassassin/user_prefs file.
TEMPLATES
new template:
/usr/local/directadmin/data/templates/rspamd_settings.conf
CONFIGS
When you save the SpamAssassin settings through DirectAdmin, the the per-User config is save at:
/etc/rspamd/users.d/username.conf
which is loaded from the included file, if it exists:
/etc/rspamd/rspamd.conf.local
which then loads in the this file, which holds the list of all User configs:
/etc/rspamd/directadmin-users.conf
where the list points to the users.d/username.conf.
CUSTOM OVERRIDE
If you need to add other custom settings, the file you'd put that in would be:
/etc/rspamd/rspamd.conf.local
just be sure NOT to remove the directadmin-users.conf include.
REQUIREMENTS
CentOS 7 (known to work, so far)
ENABLE
cd /usr/local/directadmin/custombuild
./build set spamd rspamd
./build rspamd
Note that there is no directadmin.conf settings.
DA will always grab the spamd value from the options.conf to know if it's on or off, to decide how to behave.
CUSTOM SCRIPTS
Script that replace the spamassassin_*.sh counterparts, in the directory:
/usr/local/directadmin/scripts/custom/*
rspamd_edit_pre.sh
rspamd_edit_post.sh
rspamd_destroy_pre.sh
new
Packages: copy/paste import/export of all packages (SKINS)New button on both packages pages:
Admin Level -> Manage Reseller Packages
Reseller Level -> Manage User Packages
Showin "Export Selected"
When you select the desired packages, and click this export button, it will generate an encoded output of those package details.
You can then copy the data, and paste it into the same page on some other server.
The "Import" section is just below, click the + to show the "Import Packages" form.. where you paste in that data.
This action will both create, and overwrite existing packages if they exist.
Similar to any other package changes, any User/Reseller controlled by this account which is set to this package, will have their settings updated accordingly.
If you have many Users, please wait as it can take several seconds depending on the number of Users, and disk I/O speed.
POST
Exporting data:
CMD_MANAGE_USER_PACKAGES | CMD_MANAGE_RESELLER_PACKAGES
method: POST
export=Any text
select0=packagename
(select1=otherpackagename)
basically uses the same form as the "delete".. so you can still use the delete0.. both select0 and delete0 are accepted, they fill the same list.
Added support for select0 for import to avoid confusion in assembling the form.
JSON: the export data is set in the standard dynamic "details" without any surrounding textarea, etc.
Importing data:
CMD_MANAGE_USER_PACKAGES | CMD_MANAGE_RESELLER_PACKAGES
method: POST
action=import
import=base64encoded data
SKINS
admin/manage_packages_reseller.html
reseller/manage_packages_user.html
added new include:
|HTM_IMPORT_PACKAGES|
before the footer.
files_reseller.conf, new entry:
HTM_IMPORT_PACKAGES=reseller/import_packages.html
and new file:
reseller/import_packages.html
containing the form.
style.css
new items:
.text_align_left {
text-align: left;
}
.w64chars {
width: 550px;
}
.h34rows {
height: 550px;
}
new
pre script for overusage: overusage_notice_pre.shRelated to overusage_notice_post.sh:
post script for overusage: overusage_notice_post.sh
new optional custom script:
/usr/local/directadmin/scripts/custom/overusage_notice_pre.sh
where a non-zero return code causes the delivery of the overusage notice to the User not to be sent to the User, nor to the creator.
It does not affect anything else in the tally of that User.
new
Assign Roundcube/Webmail data to "email accounts" instead of "email data"New directadmin.conf option, defaults to:
webmail_backup_is_email_data=1
which maintains all previous defaults where webmail data (squirrelmail/roundcube) are part of the E-Mail Data backup checkbox.
If you set it to:
webmail_backup_is_email_data=0
this re-classifies the webmail data over to "E-Mail Accounts", so you can exclude the "E-Mail Data" checkbox in the backup, but still have your webmail data backed up.
This could be useful for cases where you want your RoundCube database backed up and restored, but want to exclude email Maildir data, as Maildir can be easily transferred with rsync.
new
Allow usernames up to 30 charactersPrevious hard default was 14 character max.
As newer version of MySQL/MariaDB support longer names (or could be modified to do so), DirectAdmin has been changed to allow a longer username length.
Unless you really need it, we'd recommend sticking to 14, eg:
max_username_length=14
but you can set it to:
max_username_length=30
if needed. Be sure to confirm with the MySQL/MariaDB versoins you're running how long they support, else they'll throw errors when DA tries to set a long value.
Not 100% certain on the required version for longer values, but:
16 characters before MySQL 5.7.8 .Aug 25, 2016
up to 80 characters for MariaDB 10.x
So to increase the max_username_length=30, you'd need at a minimum:
MySQL 5.7.8+
OR
MariaDB 10.x+
But regardless, before setting this, you may want to confirm for yourself.
Take the da_admin login from:
/usr/local/directadmin/conf/mysql.conf
login to your server at:
1.2.3.4/phpMyAdmin
and click the "mysql" database on the left.
Click the "db" table on the left, below the mysql db.
Near the top, click the "structure" tab.
Under the "Type" column, see the char() length for both Db and User.
The User seems to be the smaller of the two, so if it shows 32, then you can use max_username_length=30
If the User type is char(16), then the max_usernamae_length=14 would be as high as you should set it.
fixed
Ensure User's are feature-reduced if Reseller is reducedWhen modifying the reseller.conf data of a Reseller, if a setting is shut off, say "SSH Access for Users",
ensure that all packages are updated accordingly to shut it off, and go through all User's below that Reseller to ensure they can no longer use, for example ssh.
This will only apply to the on/off checkbox items, and not the numerical/unlimited items.
For the given options, when disabled, for each User below this Reseller, if that User's user.conf's value for this setting differs (eg: it was on), that User will have it's data activated (set to the value specific > OFF)
This will also disable the settings for all packages under the Reseller.
However, as this could be a very system load intensive (many read/writes if you have many Users), this operation will be done in the background.
In this particular background disabling of only the changed setting will set.
So if the set-to-disabled items are no related to some other feature, that other feature will not force-set the User.
For example, if your sshd_config file had the User enabled.. but there was some sync issue where the user.conf ssh=OFF was set, the User would not be removed from the sshd_config.
This is the only case where this assumes things are in sync, and is done solely for efficiency, since activating data on thousands of Users could be very very slow.
All other areas that change User settings, like manually setting a value for the User, or changing a package entry (which updates all Users set to it), will force all settings back in place.
TASK.QUEUE
When changing a Reseller's settings manually per-setting, or simply changing that Reseller package,
for any setting that has changed to the OFF value, it will be added to the list.
So if you only disable SSH for the Reseller's Users, and say.. anonymous FTP, the task.queue call will look like this:
action=activate&value=reseller&reseller=fred&aftp=OFF&userssh=OFF
(note: userssh converts to 'ssh' when checking user.conf files)
The dataskq will pick up this request, and for each User in fred's users.list file,
if the user.conf has 'aftp' or 'ssh' enabled, they'll be shut off.
fixed
ProxyErrorOverride on for nginx+apache proxy VirtualHosts (TEMPLATES)Update:
This setting has been commented out. Done by adding # in front of the entry, eg:
#ProxyErrorOverride on
in the 4 virtual_host2*.conf templates.
Related thread:
https://forum.directadmin.com/posts/293674
=====
Relates to not passing errors to nginx, and instead let php/apache generate the error pages.
The 4 virtual_host2*.conf files will have:
ProxyErrorOverride on
just before the AddHandler for both php1-fpm and php2-fpm.
fixed
CMD_ADMIN_STATS not showing all disk usageSome languages use commas.
Number verification was added to 1.55.0 causing some language formatting of those numbers to fail, eg:
2,5G
fixed
Allow spaces in ssh key commentsDA previously required that the ~/.ssh/authorized_keys file required comments to be a single word.
Code has been changed around to use the key-type (ssh-rsa) to be the anchor point, so it can have the optional settings to the right, and any number of comment words to the right of the key data.
fixed
CMD_FILE_MANAGER: ensure $LANG set before calling zip/unzip/tarWhen the "extract" button is clicked in the File Manager (eg: on a zip file), the $LANG value set in the environment does affect how the data is output.
For security reasons, and call to any embedded script, DA first clears the environment to ensure nothing malicious was set.
However, the call to zip/unzip (for example) does use the $LANG env variable to determine the encoding of the filenames shown, when displaying files.
Also, it only applies to the CMD_FILE_MANAGER/CMD_API_FILE_MANAGEr, due to the skin file pre-processing, in advance of the chroot (which doesn't actually happen in this case, but it's pre-processed solely on the filename)
As a result, even if the LANG was set correctly, if your skin makes an embedded script call in CMD_FILE_MANAGER, then result will be an empty environment, so the call later on to unzip would mean LANG is not set..
If you needed special encoding, the filename would end up showing in the ugly unicode format, eg:
file-#U00cc#U0160n-name.txt
Note, the extraction would still work correctly, assuming you use the directadmin.conf option:
extra_unzip_option=-O cp396
FIX
To resolve this, prior to the zip/unzip/tar calls in CMD_FILE_MANAGER,
DA checks for the existence of the LANG env variable.
If it's unset, DA will set it to en_US.UTF-8.
It's more desirable to use the skin's encoding name, but as it's either iso-8859-1 or UTF-8 for example, these are not valid LANG variable names.
Since the number of affected people are quite low, this should be fine.
fixed
Delete vacation message along with emailDeleting an email account did not previously remove it's associated vacation messages, if present.
Now it does.
fixed
Reset DNS Zone: find DKIM keys from suspended domainReset zone now notices the domain is suspended and will grab those keys from the renamed domain.com_off directory.
fixed
Restore: additional IPs for Users and domainsWhen using the "Use the IP stored in the backup" option, DA should try and use those IPs, or ensure it's swapped to a new value if the old value was on the old box for "additional IPs" instead of the main user.conf ip.
Assumes they're already added to the given Reseller account, and set to the correct free or shared state, as desired, before issuing the restore.
Previously, it only looked at the user.conf ip setting for the swap to the new value.
It's now much smarter, and will restore a domain to it's previous value, even if the domain was set to some other IP address.
Aside from not being able to restore a server into a previous state, another issue was if you had this setup:
user.conf:ip=1.2.3.4
user_ip.list:1.2.3.4, 1.2.3.5
domains/domain.com.conf:ip=1.2.3.5
restoring to a brand new IP: 4.3.2.1
when restoring this backup, because the IP being search for to swap "from" was only looking for 1.2.3.4, then dns ended up in a bit of a mess where IPs were not being swapped.
This fix looks for the correct 1.2.3.4 for the "old" IP, to swap to 4.3.2.1.
====
If using the "Use the IP stored in the backup", attempt to assign it to that User. Important that you have it assigned to the creator first, and set correctly to "free" or "shared", before restoring the User.
If using the "Use the IP from the list:", DA will create the User and domain with the new value, but search for the backup old domain.conf file for the old search value for swapping to the new IP.
======
T14209
fixed
LetSencrypt hostname: check for cacert path in case it's not the defaultThe LetsEncrypt feature can setup a certificate for your hostname.
In this case, as long as everything is in the default place (eg: directadmin.conf cacert=/usr/local/directadmin/conf/cacert.pem),
things should work normally, and the letsencrypt.sh itself will auto-renew the hostname cert when needed and copy it to all different service cert locations:
/etc/exim.conf
/etc/httpd/conf/ssl.crt/server.crt
/usr/local/directadmin/conf/cacert.pem
etc.. for all cert, key and ca root certs.
However, if you've changed the cacert value in the directadmin.conf so that DA uses the apache cert, or some other path, eg:
cacert=/etc/httpd/conf/ssl.crt/server.crt
the letsencrypt.sh script assumes you're dong something custom, and will not copy things around, so doesn't work as usual and the certs will not auto-renew everywhere.
As the is usually not the desired behavior, but might be, although DA won't ignore the setting and change it back to the default (because what's then the point of a setting),
instead DA will do it's best to let you know that this isn't normal, and will add entires to the system.log erortaskq.log and debug output with:
LetsEncrypt: Ssl::get_cert_creation_time: **** Hostname certificate %s is not in the usual %s path. This can affect the letsencrypt.sh's ability to auto-renew. Please change your cacert,cakey,carootcert setting in the directadmin.conf
where %s #1 is the cacert= value from the directadmin.conf
and %s #2 is the default value DA would like to see for things to work correctly.
Note, although DA only checks the cacert value, if you do change things back ensure you do it for all 3 settings, eg:
cacert=/usr/local/directadmin/conf/cacert.pem
cakey=/usr/local/directadmin/conf/cakey.pem
carootcert=/usr/local/directadmin/conf/carootcert.pem (assuming you use this)
fixed
BFM: Roundcube: X-Real-IP (TEMPLATES)Roundcube apparently now logs information like:
X-Real-IP
so the brute_fitler.list needed to be updated, and now looks like this:
roundcube1=ip_after= from &ip_until=(X-Real-IP:&text=IMAP Error: Login failed for&user_after=IMAP Error: Login failed for &user_until=%20from%20
roundcube2=ip_after= from &ip_until=(X-Forwarded-For:&text=IMAP Error: Login failed for&user_after=IMAP Error: Login failed for &user_until=%20from%20
roundcube3=ip_after= from &ip_until=. AUTHENTICATE PLAIN&text=IMAP Error: Login failed for&user_after=IMAP Error: Login failed for &user_until=%20from%20
where 2 and 3 used to be 1 and 2, and roundcube1 is now present.
fixed
SSL Certificates: san_config: ensure common name is first in the subjectAltName listIt appears as though, regardless of what the CN is set to in the domain.com.san_config, the first subjectAltName DNS value set in the san_config shows up as the main "Issued To" value.
DirectAdmin will now decide what the common name is (either domain.com, www.domain.com or *.domain.com) and will ensure that it's written first in the subjectAltName list at the bottom of the san_config.
fixed
Plugins: too many headers block latest available version from showing upYou might see "Cannot find the end of the headers" in debug mode or errors when trying to see the latest plugin version.
Was a limited buffer size blocking all headers from loading in at once.
fixed
Crontab to strip double-quotes for no email: MAILTOIf you set a blank email value with the intent not to send any email, it's saved into crontab as:
MAILTO=""
however, DA was not stripping the "" values when showing what was set, so it caused confusion in the input field with
value='""'
DA now strips it so it won't show the double-quotes.
If a valid email is set into crontab like this:
MAILTO="some@email.com"
DA will also strip that out for the input field to use value='some@email.com', as it would have similarly shown:
value='"some@email.com"'
which couldn't be saved like that.
fixed
Better validation of IPs (SECURITY)Better validation of IPs. Intentionally left ambiguous.
Risk level low, as attacker must already be logged into a privileged account, and cannot steal or acquire anything useful.
T14343
fixed
X-Forwarded-For to allow multiple IPsRelating to feature:
Allow header X-Forwarded-For header for proxy or load balancers
it allows the client IP to be set via the X-Forwarded-For header.
However, multiple values should be allowed, but DA was only checking for a single valid value, this throwing this error:
X-Forwarded-from IP found (2.3.4.5). But X-Forwarded-For value is not a valid IP: 1.2.3.4, 6.7.8.9
where 1.2.3.4 is the client IP,
2.3.4.5 is the incoming proxy IP
and 6.7.8.9 is the unexpected "middle" proxy IP, likely between the final proxy and the client.
The fix will be for DA to strip out the extra IPs, since we're less concerned with the middle proxies used to get here.
fixed
Restore Domain Pointers to type AliasRelated to this change, which introduced the bug:
Domain Pointers: option to not redirect to www (SKINS)(TEMPLATES)
The domain.com.pointers new format:
domainpointer.com=type=alias
was not being correctly parsed during a restore, causing all new pointers to end up being "redirect" type instead of "alias" type.
fixed
Block global usernameAdded "global" to the reserved username list.
fixed
MariaDB restore: use abort_source_on_errorNew internal default directadmin.conf option:
abort_source_on_error=1
if set to 1, and if MariaDB is used, the mysql binary command option:
--abort_source_on_error
to ensure that failed restores actually return a non-zero return code.
There are some cases where a MariaDB restores are failing but still returning a success 0 code, which is not correct.
DATASKQ
you can confirm if this is being called in the dataskq, level 1000 or higher.
The restore output will include this line:
Database::restoreDatabases: adding --abort-source-on-error to mysql call
fixed
Reseller overselling not restoringIf the reseller.conf had an overselling option set, it will now be restored.
fixed
(SECURITY)There was a report of an exploit, and a CVE was created (not by us)
https://nvd.nist.gov/vuln/detail/CVE-2019-9625
https://github.com/ManhNho/CVEs/blob/master/New-Requests/DirectAdmin-CSRF
We tested the issue, but were unable to reproduce it, and reported back to Secunia with our results.
During testing, other factors were considered and a different issue was found/fixed.
So the original report appears to be false, but a new/unrelated/unpublished issue was discovered.
Once a short period of testing on this fix has had time to confirm it doesn't break other things, we'll release 1.56.0.
CVE-2019-11193
Credit:
Bartosz Kwitniewski
https://www.hekko.pl/