Version 1.61.4
Released: 2020-09-18
new
Script to help reset the da_admin passwordProposed script: /usr/local/directadmin/scripts/reset_da_admin_password.sh
Usage:
reset_da_admin_password.sh --stdin - the password will be passed on stdin
reset_da_admin_password.sh --random - pick a new random password
reset_da_admin_password.sh --password='newpass'
reset_da_admin_password.sh - this help page
The script should attempt to use the mysql= value from the setup.txt if it exists, (else use current da_admin user/pass), and make an attempt to connect, taking into account the host value, if exist in the mysql.conf NOTE: it currently only support localhost resets
If it's able to connect, change the password normally via mysql call, and update the mysql.conf and my.cnf.
TODO:
If it's not able to connect, attempt to shut down mysqld, and restart it with the --skip-grant-tables, as per guide: https://help.directadmin.com/item.php?id=45 and again, reset the da_admin pass, followed by restarted mysqld back into normal mode.
After setting the password, also udpate the mysql.conf my.cnf.
API
Should the script be successful, a possible API call may be added to call the script through 2222. To be determined.
T24253
new
Per-Domain php.ini settings through GUI (TEMPLATES)(SKINS)Per-User control, for per-domain php.ini settings. Currently only saves the changes to the "DOMAIN CONFIG" listed below (more usage to follow shortly)
For "Enhanced" style skins, you'd view the domain's settings at: CMD_PHP_SETTINGS?domain=domain.com
NOTES
php-fpm only supporst 1 php-fpm.conf file (one per User) You'll need to set the desired php settings on the "Main Domain" of the account to alter php settings for this User. Other php modes like mod_php+mod_ruid2, or fastcgi support per-domain php settings.
VIEW SETTINGS (JSON)
GET: CMD_PHP_SETTINGS?domain=domain.com&json=yes returns JSON list with 2 sub-lists: "domain_php_ini" : containing all php.ini settings, based on the DOMAIN CONFIG below "template_php_ini" : contains the json from the template['ini'] item with info on each php.ini that can be set.
The domain_php_ini is a basic php.ini json array without sub-arrays. The template_php_ini has each index as the php.ini name, with the value being an array. Each template php ini item sub-array will have a "type" and "default" value set. See the next section for info on template types.
DISABLE
Should you want to disable the User's ability to use this feature, the commands.deny could be used, or use the never commands, eg:
/usr/local/directadmin/direcadmin set never_commands CMD_PHP_SETTINGS
service directadmin restart
TEMPLATE TYPES
-"bool": Can be "On" or "Off" (note the upper case first letter).
- "list": will have a sub-array called "values" being the values which can be chosen from.
- "value": basic input text. There are some character restrictions done on the back-end.
- "int": will have a sub-array called "range", which is an integer array with 2 items, the low and the high values.
See the TEMPLATE below for more samples.
DOMAIN CONFIG
/usr/local/directadmin/data/users/username/domains/domain.com.php.ini
In a standard php.ini syntax: name=value ...
ADDING A SETTING
Let's say we want to save: max_execution_time=45
To save a change, use:
CMD_PHP_SETTINGS
method: POST
action=add
domain=domain.com
max_execution_time=45
save_max_execution_time=anytext
Where DA only notices which values are to be saved when "save_" is prefixed to the front. For json/API calls, multiple save_max_execution_time type values can be passed in the same post. Enhanced just uses 1 at a time.
DELETE A SETTING
CMD_PHP_SETTINGS
method: POST
action=delete
domain=domain.com
select0=max_execution_time
(select1=max_input_vars)
SKINS
Enhanced: /usr/local/directadmin/data/skins/enhanced/user/php_settings.html
with a link to CMD_PHP_SETTINGS?domain=domain.com in enhanced/user/modify_domain.html to the right of the PHP on/off checkbox, called "Php Settings"
TEMPLATES
- virtual_host2*.conf: added: |CLI_PHP_SETTINGS| within the |*if CLI="1"| section.
- user_virtual_host.conf: added: |CLI_PHP_SETTINGS| within the |*if USER_CLI="1"| section.
- php-fpm.conf: added |FPM_PHP_SETTINGS| before |CUSTOM2|
- php-cron.ini: added |CRON_PHP_SETTINGS| at the bottom (php_settings.json and php-cron.ini values must not overlap)
- openlitespeed_vhost.conf: added |CLI_PHP_SETTINGS| after |CLI_PHP_MAIL_LOG|
NEW: /usr/local/directadmin/data/templates/php_settings.json
Contents, at the time of this writing:
{
"ini" : {
"allow_url_fopen" : {
"default" : "On",
"type" : "bool"
},
"display_errors" : {
"default" : "On",
"type" : "bool"
},
"error_reporting" : {
"default" : "E_ALL & ~E_NOTICE",
"type" : "list",
"values" : \[
"~E_ALL",
"E_ALL & ~E_NOTICE",
"E_ALL"
\]
},
"file_uploads" : {
"default" : "On",
"type" : "bool"
},
"include_path" : {
"default" : "\\".;/path/to/php/pear\\"",
"type" : "value"
},
"log_errors" : {
"default" : "Off",
"type" : "bool"
},
"mail.force_extra_parameters" : {
"default" : "",
"type" : "value"
},
"max_execution_time" : {
"default" : 30,
"type" : "int",
"range" : \[ 0, 14400 \]
},
"max_input_time" : {
"default" : 60,
"type": "int",
"range" : \[ 0, 14400 \]
},
"max_input_vars" : {
"default" : 1000,
"type": "int",
"range" : \[ 1, 100000 \]
},
"memory_limit" : {
"default" : "128M",
"type" : "list",
"values" : \[
"64M",
"128M",
"192M",
"256M",
"368M",
"512M",
"768M",
"1024M"
\]
},
"post_max_size" : {
"default" : "8M",
"type" : "list",
"values" : \[
"2M",
"4M",
"8M",
"16M",
"32M",
"64M",
"128M"
\]
},
"register_globals" : {
"default" : "Off",
"type" : "bool",
"require" : {
"php_ver" : "<5.4.0"
}
},
"session.gc_maxliftime" : {
"default" : 1440,
"type" : "int",
"range" : \[ 1, 1209600 \]
},
"short_open_tag" : {
"default" : "On",
"type" : "bool"
},
"upload_max_filesize" : {
"default" : "2M",
"type" : "list",
"values" : \[
"2M",
"4M",
"8M",
"16M",
"32M",
"64M",
"128M",
"256M",
"512M",
"1G"
\]
},
"zlib.output_compression" : {
"default" : "Off",
"type" : "bool"
}
}
}
EVO1927
new
Optional zstd compression for backup/restoreDirectAdmin now supports the tar.zst format, using the zstd compression, which is far better than gzip in terms of space used, as well as compression and decompression performance.
To enable, ensure it's installed, using CustomBuild:
cd /usr/local/directadmin/custombuild
./build zstd
Then tell DA you have it, and enable it for backups:
cd /usr/local/directadmin
./directadmin set zstd 1
./directadmin set backup_gzip 2
The backup_gzip may get renamed to backup_compression at some point, as the above isn't entirely clear it's no longer using gzip.
new
Backup: Option to exclude Trash (SKINS)Both the Admin Level and User Level backups will now offer a "Deleted Trash Data" checkbox. This controls the inclusion of ~/.trash in the backup/home.tar.gz, within the main backup file.
The CMD_ADMIN_BACKUP and CMD_SITE_BACKUP will now be upgraded from: form_version=3
to: form_version=4
Where any form_version less than 4 will automatically have "select13=trash" selected, if "select0=domain" is selected. Anything from 4 an up will require select13=trash to be checked/passed if that value is desired.
There is also a new internal directadmin.conf option: skip_trash_in_backups=0 where it can be set to 1 to always exclude it for all backups, regardless checkbox.
Keep in mind that the 13 in "select13" is not important. Only that there are not any duplciate selectX numbers, as DA does not handle duplicate select[] form values, unless told to do so in the back-end (FileManager)
BACKUPS
The user.admin.fred.tar.gz backup files will now include:
- trash
- trash_aware
with or without "trash", depending on the checkbox, but this version of DA an onwards will include the trash_aware option. Absence of trash WITH trash_aware will eventually exclude ~/.trash from being restored. Currently (1.61.4) the ~/.trash folder will always be restored as the home.tar.gz is simply extracted into /home/user, without any per-file choices. So for the restore (at the moment), trash will always be restored if present in the backup.
UPDATE
the scripts/update.sh will call the action=convert&cronbackups, as it always does, but the code this triggers will now update all crons to enable "trash" if "domain" is enabled.
SKINS
- /usr/local/directadmin/data/skins/enhanced/user/site_backup.html
- /usr/local/directadmin/data/skins/enhanced/admin/admin_backup.html
- /usr/local/directadmin/data/skins/enhanced/admin/admin_backup_modify.html
Update the form_version=4 and include select13=trash. The control token is called |TRASHON| to have it check or not in the modify page.
R27277 EVO1932
new
Suspension notifications for manual suspension (SKINS)Previously, only the automated suspensions would send a notice for bandwidth over-usage. Manual suspensions would not send any notice, as it would be triggered by the creator.
This new feature will provide a method to send a notice to the Message System (thus E-Mail) as to why they've been manually suspended. Features will include:
- a new page to allow management of the default message to use.
- Inclusion of a |REASON| token that can be used in this message
- Ability to use if-then-else syntax on this |REASON| to control full sentences based on it's value.
- Default option to send this message upon manual suspension or not.
With the Evolution skin, upon suspension intent, a new modal pop-up will offer the choice of the reason (as before), but will also include the choice if the message should be sent or not. This modal will also include the full default subject and message, which can either be left as-is or altered for this one message delivery (without affecting the default).
The creator of the account will also get a duplicate. Note that if an Admin suspends the User, but that Admin did not create the account, the Reseller that did create the account will get a copy of the email.
Enhanced will rely on the default page for the message and delivery choice.
TOKENS
When saving a message, the following tokens are available. Note that the message is tokenized first, allowing you to set tokens which are passed to the subject (if ever needed)
USERNAME: account being suspended
USERTYPE: type of account being suspended: user|reseller|admin (useful mainly only for message overrides, see SUSPENSION below).
CREATOR: creator of this User, even if the account doing the suspension is not the creator.
EMAIL: email address of the User, from the user.conf (may differ from the User's message system email).
DOMAIN: main domain of the User (user.conf), may be blank if they have 0 domains.
HOSTNAME: hostname of the server.
REASON: reason for the suspension passed. If no reason is passed, will be set to "none"
REASON_STR: Human text from the data/templates/suspension_reason.txt or data/templates/custom/suspension_reason.txt). May be blank if REASON is not in there.
MSG_FOOTER: recommended to leave as last text in the message. Standard footer is added.
You can use the standard if-then-else syntax on any of the tokens, and even set your own tokens if needed.
eg:
|*if REASON="spam"|
You sir, are a spammer.
|*else|
You were suspended. Reason: |REASON|
|*endif|
API
VIEW MESSAGE / SETTINGS
View the current settings: CMD_SUSPENSION_MESSAGE?level=1
View the current message for the User.
- level=1 User suspensions.
- 2, 3, are for Reseller, Admins.
Add &json=yes for the subject, message, and "settings['notify'] == 'yes'|'no'"
SAVE MESSAGE / SETTINGS
CMD_SUSPENSION_MESSAGE
method: POST
save=<any text>
level=1|2|3 (Resellers can only use 1)
subject=Subject text
message=message text
notify=yes|no (checkbox, so not passed is 'no')
RESET MESSAGE / SETTINGS
To undo whatever you've done for this given level, pass:
CMD_SUSPENSION_MESSAGE
method: POST
reset=<anytext>
level=1|2|3
and that level will be deleted.
SUSPENSION
The usual suspension is still the same, but extra optional values can be passed. Without adding the extra values during suspension, if "notify=yes" was set in the settings, the message will be sent. The only way to override this would be to pass "notify=no' along with the suspension request, eg:
CMD_SELECT_USERS
method: POST
dosuspend=<anytext>
(reason=<suspend reason>)
select0=fred
(select1=george)
OVERRIDES / optional:
notify=yes|no
subject=subject text
message=message text
where all 3 options extras are optional. You do not need to pass all 3.. can be any of them, or all of them, or 2, etc.. The subject/message texts are still tokenized normally.
The reason is optional, but we highly recommend setting it if a message is to be sent out. Without a reason, it will be set to "none", which may cause confusion.
Keep in mind, that the Admin Level -> Show All Users page can suspend all 3 types of accounts in 1 request. if the subject/message is passed along with the suspension, this will not be type-specific. In that case, you can use the |USERTYPE| token to do some if-then-else statements in the message
FILES
The files saved on disk will be at:
- /usr/local/directadmin/data/users/creator/u_suspension.json
- /usr/local/directadmin/data/users/creator/r_suspension.json
- /usr/local/directadmin/data/users/creator/a_suspension.json
TEMPLATE
Unlike other email notices, we've opted to not use a default template for this tool. Instead, it makes use of the internal "gettext" .pot lang files for easier translation.
SKINS
/usr/local/directadmin/data/skins/enhanced/reseller/edit_message.conf
The edit_message.conf file already existed for editing the welcome messages, but it was re-used with if-then-else to accommodate the new feature. There were no changes to files_reseller.conf to point to it.
EVO1938
new
templates/custom/additional_forbidden_domains.listRelating to the existing forbidden_domains.list template, this new optional template can be used to add a custom supplementary list of domains, without needing to worry about adding new domains if the default template is modified.
Thus, with this change, the new recommended way to add domains to the list is to create the template: /usr/local/directadmin/data/templates/custom/additional_forbidden_domains.list
and simply include the extra domains you wish to add to this file (one domain per line)
new
User controlled per-domain ModSecurity flags (TEMPLATES)(SKINS)CMD_MODSECURITY
Feature that enables Users to skip some mod_security rules, or fully disable them when needed.
<ID>
below are rule skip IDs, called SecRuleRemoveById in ModSecurity must be a positive integer, but ranges are allowed, as long as they're "quoted", e. g.:
- 1234
- 1234-1239
"1234-1239"
Quotes for ranges are dropped in 1.670.
VIEW RULES:
CMD_MODSECURITY?domain=domain.com
When called by an Admin, absence of the domain will return the global modsecurity_rules file.
DISABLE
Should you want to disable the User's ability to use this feature, the commands.deny could be used, or use the never commands, eg:
/usr/local/directadmin/direcadmin set never_commands CMD_MODSECURITY
service directadmin restart
VIEW LOGS
JSON output only of the modsec_audit.log
REQUIRES modsec_audit.log to use the new one-json-per-line format.
Users/Admins: CMD_MODSECURITY?action=log&domain=domain.com
Only show entries matching this domain. For Users, the domain must be in the domains.list. For Admins, can be any host value they want. Sub-domains will be included in the output. Blank hosts are not included.
Admins: CMD_MODSECURITY?action=log
Shows entries with any Host value (or no Host)
To reduce the log output, you should include: &lines=1000 to any value. DA starts from the end of the log, parsing lines backwards. It stops after this number of ENTRIES has been added to the log (was a tail, but it's now entries)
There is also an internal max_time=15 (which is dynamic, timeout / 4, assuming timeout=60) You can pass &max_time=5 or any other number of seconds, to have the parser stop after this number of seconds if you wish to speed up the display, at the cost of losing some older entries. For very large logs, there is no point in parsing the entire thing if a timeout will happen.
The logs will be output in a "logs" array, filled with a list of transaction arrays. The top-level json also includes a "summary" array, giving info on how the parser actually went eg:
"summary":
{
"max_time": "15",
"requested_lines": "500",
"returned_lines": "375",
"time_abort": "yes"
}
where if you see "time_abort" ; "yes", it would mean that time ran out before actually finding that number of lines/entries.
SAVE FLAGS
action: CMD_MODSECURITY
method: POST
domain=domain.com
action=save
SecFilterScanPOST=On|Off
SecRuleEngine=On|Off
optional, can also include to save a call if saving and skipping in 1 request:
SecRuleRemoveById=<ID>
When called by an Admin, absence of the domain will save to the global modsecurity_rules file. Same for the rule skips below.
ADD RULE SKIP
action: CMD_MODSECURITY
method: POST
domain=domain.com
action=add
SecRuleRemoveById=<ID>
REMOVE RULE SKIP
action: CMD_MODSECURITY
method: POST
domain=domain.com
action=select
SecRuleRemoveById=<ID>
AND/OR
select0=<ID>
(select1)=<ID>
JSON VIEW:
CMD_MODSECURITY?domain=domain.com&json=yes
returns 2 arrays, one for On/Off flags, and the other for skip IDs, eg:
{
"SecRuleRemoveById" :
[
"1234"
],
"flags":
{
"SecFilterScanPOST": "On",
"SecRuleEngine": "On"
}
}
You can learn if modsecurity=yes is set in the options.conf via: CMD_ADDITIONAL_DOMAINS?action=view&domain=domain.com.com&json=yes with the added value: modsecurity=yes|no
When called by an Admin, absence of the domain will return the global modsecurity_rules file.
You'll also get a "subdomain_select" array, which is a standard select-box for the available subdomains.
SUBDOMAINS
Any page can override just one subdomain, instead of the top domain with all sub-values by including "subdomain=sub" in the GET/POST values. The config will be at: /usr/local/directadmin/data/users/USER/domains/DOMAIN.COM.subdomains_modsecurity_rules/SUB.modsecurity_rules
CONFIG FILES
When saved to disk, the path will be: /usr/local/directadmin/data/users/USER/domains/DOMAIN.COM.modsecurity_rules based on the template, below.
If an Admin is making a call to CMD_MODSECURITY, they are allowed to either pass the domain of some other User, or no domain at all. The global config for mod security will be stored at: /usr/local/directadmin/data/admin/modsecurity_rules to be included by the webserver configs.
TEMPLATES
/usr/local/directadmin/data/templates/mod_security_rules.conf
Where flags are stored into |FLAGS| and the multi-line SecRuleRemoveById values are saved into |DISABLEDRULES| There template starts with |CUSTOM1| and ends with |CUSTOM2| but these tokens are currently blank for possible future expansion.
virtual_host2*.conf: added new token:
|MOD_SECURITY_RULES|
within the <Directory>
context.
nginx_server*.conf openlitespeed_vhost.conf
SKINS
New file: /usr/local/directadmin/data/skins/enhanced/user/mod_security.html
Modified: /usr/local/directadmin/data/skins/enhanced/user/modify_domain.html
to include a button when:
|*if HAS_MOD_SECURITY="yes"|
pointing to:
/CMD_MODSECURITY?domain=|domain|
Unrelated: also changed all class=list tables in modify_domain.html to use the cleaner <table class=list_alt>
which does not require extra tags for td entries, and uses th for table titles/footers.
EVO1936
new
LetsEncrypt: Lego dnsproviders for wildcard certs on various remote dns servicesWildcard certificates for LetsEncrypt requires DNS confirmation. If you're running at some remote DNS provider, not currently supported by the multi-server setup, then this tool lets you use wildcard certs with those DNS providers.
JSON
To get the list of dns providers, include &dnsproviders=yes in the request, eg: CMD_SSL?domain=domain.com&dnsproviders=yes&json=yes
as the file is somewhat large, so only load it if the given skin knows how to use it.
It will be loaded in a top-level array called:
dnsproviders["data"] = { "version" : "3.7.0", "acme-dns": ...}
and any info about the current domain settings will be in: dnsproviders["dnsprovider"] where the "dnsprovider" (singular) is a dump of the domain.com.dnsprovider file, used to auto-fill the pre-selected choice. If this file contains "inherit=creator" or "inherit=global", it will use the respective dnsprovider.conf file.
INHERIT DNS PROVIDER
An Admin/Creator can setup 2 possible inherit files: Global: /usr/local/directadmin/data/admin/dnsprovider.conf
Creator: /usr/local/directadmin/data/users/resellerbob/dnsprovider.conf
Should either of these exist, where creator=resellerbob is in the given User's user.conf, they'll be included in the list of dnsproviders["data"] output as:
- dnsproviders["data"]["inherit-creator"]
- dnsproviders["data"]["inherit-global"]
where each would still have the correct "Name" bug the type is prefixed, eg: dnsproviders["data"]["inherit-creator"]["name"] = "Inherit Creator : Cloudflare"
where the "Inherit Creator : " or "Inherit Global" would be prefixed, beside the name from the used type for that inherited dnsprovider.conf type.
The inherit-creator or inherit-global arrays will have an empty "credientials" array, and zero credentials are allowed to be passed if the master (including inherited configs) have zero creds.
If the "dnsprovider" is empty (nothing picked yet), check for: dnsproviders["settings"]["default"] to know which selection should be used by default. It should be either "local", "inherit-creator" or "inherit-global".
The Global/Creator dnsprovider.conf files may contain one of: default=inherit-creator default=inherit-global default=local
which is what specifies the default value for User to have selected.
RESELLERS/ADMINS: SETTING THE INHERITED VALUES
Resellers/Admins can set an 'inherit-creator' dnsprovider.conf file. Admins can also set the 'inherit-global' dnsprovider.conf file.
VIEW
Either can view that config (if exists) via: CMD_SSL?action=dnsprovider&json=yes
or: CMD_SSL?action=dnsprovider&json=yes&type=global
which provides a similar array, eg:
dnsproviders["data"]
dnsproviders["dnsprovider"]
dnsproviders["type"] = "creator" | "global"
SAVE
CMD_SSL
method: POST
action=dnsprovider
default=local|inherit-global|inherit-creator (optional)
dnsprovider=cloudflare
(type=global|creator)
CLOUDFLARE_EMAIL=foo@bar.com
CLOUDFLARE_API_KEY=sdgsd7681afn
where the last 3 depend on which "dnsprovider" was selected, similar to below for Users. The default is optional and is used to tell the User which default selection to use. Saved in creator/reseller dnsprovider.conf
If no "type" is passed, "creator" is used. A Reseller is not allowed to set type=global.
RESET
CMD_SSL
method: POST
action=dnsprovider
dnsprovider_reset=yes
(type=global|creator)
which simply deletes the given Admin/Reselelr dnsprovider.conf file.
POST
When saving data for a LetsEncrypt request for Users, include "dnsprovider=NAME" to activate the rest of the checks, eg:
CMD_SSL
method: POST
domain=domain.com
action=save
background=auto
type=create
request=letsencrypt
name=domain.com
wildcard=yes
keysize=secp384r1
encryption=sha256
le_wc_select0=domain.com
le_wc_select1=*.domain.com
submit=Save
dnsprovider=cloudflare
CLOUDFLARE_EMAIL=foo@bar.com
CLOUDFLARE_API_KEY=sdgsd7681afn
for example, assuming cloudflare is the desired remote dnsprovider.
Note, for inherited dnsprovider, do not pass a dnsprovider, else it will override the inherited value with the passed value.
ONLY SAVE DNSPROVIDER INFO
If you wish to only save the dnsprovider info, use:
CMD_SSL
method: POST
domain=domain.com
action=save
type=dnsprovider
dnsprovider=cloudflare
CLOUDFLARE_EMAIL=foo@bar.com
CLOUDFLARE_API_KEY=sdgsd7681afn
RESET
to remove the domain.com.dnsprovider file (resetting to Local), include: dnsprovider_reset=yes
to either of the above requests. The "dnsprovider=" nor it's related fields are needed when dnsprovider_reset=yes is passed.
Eg:
CMD_SSL
method: POST
domain=domain.com
action=save
type=dnsprovider
dnsprovider_reset=yes
USER / DOMAIN DATA
When a selection is made by a User (or by creator default choice), the domain's dns setting will be stored in: /usr/local/directadmin/data/users/USERNAME/domains/DOMAIN.COM.dnsprovider
sample data:
dnsprovider=cloudflare
CLOUDFLARE_EMAIL=foo@bar.com
CLOUDFLARE_API_KEY=sdgsd7681afn
OR: inherit=yes
(or something similar)
which is loaded into the ENV and passed onto the letsencrypt.sh script.
new
Hide old directadmin.conf mysql settings when mysql_detect_correct_methods=1New installs have been using mysql_detect_correct_methods=1 for a while now.
When this setting is enabled, the 2 older settings:
mysql_milestone_16
mysql_use_new_user_methods
have no effect and only cause confusion. When mysql_detect_correct_methods=1 is enabled (recommended), then those 2 older setting will be hidden from any output, eg: ./directadmin c
new
output main Admin usernameMany scripts require the top-level admin account name. This is not always going to be "admin" so to unifiy the value, new command: ./directadmin a
which would output nothing more than: admin
new
Default: disable_ip_check=1Relating to the disable_ip_check feature, we was previously set to 0, such that the incoming session IP must match for subsequent requests, the internal default is now set to 1, eg: disable_ip_check=1
This is due to IPv6 and IPv4 IPs commonly rotating for each request, causing confusing logouts.
T6652
new
Option to disable forwarder loop checkRelating to feature "Forwarder anti-loop check": Forwarder anti-loop check
this provides the option to disable it.
New internal default: forwarder_loop_check=1
to disable, type:
/usr/local/directadmin/directadmin set forwarder_loop_check 0
service directadmin restart
T27969
new
dkim_create.sh: new 'force' param to force new keysSometimes you might want to force the creation of new dkim keys. New optional "force" option with the dkim_create.sh script can be used to overwrite the old values.
Usage:
./dkim_create.sh <domain> (nodns) (force)
Options:
<domain>: Required. Name of the domain to enable dkim for.
nodns: Optional. Prevents adding the keys to the zone.
force: Optional. Force overwrite of the keys with new values.
T28148
new
FileManager: edit: optional: must_exist=no for error pages (SKINS)When viewing; HTM_ERROR_PAGES?domain=domain.com
the URLs to edit the 404.shtml (for example) would point to: /CMD_FILE_MANAGER/domains/domain.com/public_html/404.shtml?action=edit
The issue arises if the User has deleted or does not have that 404.shtml. The new option: must_exist=no has been added to the action=edit such that the file does not need to exist to open the edit page.
eg: /CMD_FILE_MANAGER/domains/domain.com/public_html/404.shtml?action=edit&must_exist=no
WORKAROUND
The check is due to the: fm_allow_binary_edit=0
option, where the file needs to exist to know if it's binary or not. To work-around the error, simply set:
./directadmin set fm_allow_binary_edit 1
service directadmin restart
and the file-exists check will not be done.
SKINS
/usr/local/directadmin/data/skins/enhanced/user/error_pages.html
added &must_exist=no to all action=edit URLs.
T28180
new
FileManager: Options to uncheck "move to trash" by defaultThe FileManager currently has a new Trash feature, and when deleting a file/folder, there is a checkbox for "Move to Trash", which is checked by default. This feature adds a new internal directadmin.conf value: fm_to_trash_default=1
which means the checkbox is checked by default (as it was before). If so desired, you can set this to 0 with: /usr/local/directadmin/directadmin set fm_to_trash_default 0 service directadmin restart
which will have the "Move to Trash" checkbox un-checked by default.
JSON
The general json['info]['fm_settings'] array will now include this fm_to_trash_default variable, so json-based file managers can set the default checkbox state accordingly.
EVO1962
new
File Manager: v2 OS-like controlsThe Evolution skin now comes with a new and improved File Manager. It supports ctrl, ctrl+shift, shift (cmd on mac instead of ctrl) 'shortcuts', drag and drop directly for uploads, drag and drop inside, right click, etc.
It should feel more like an typical operating system than a website and is far more intuitive to use.
new
ftp_list.php: ftp_list_run_as=nobody: option to change UserBy default, the ftp_list.php always runs as "nobody", when getting a list of files from an ftp server. The ftp_download.php and ftp_upload.php always run as "diradmin" when working in /home/tmp/admin.1234/*.
In some custom cases, you may want to be using ssh keys, or need all 3 scripts to run as the same account, so this change adds a new directadmin.conf option: ftp_list_run_as=nobody
which can be altered to be: ftp_list_run_as=diradmin
if needed (or any other account, if you wanted), eg:
/usr/local/directadmin/directadmin set ftp_list_run_as diradmin service directadmin restart
new
DNS: named templates: USERNAME tokenThe named.db and all dns_*.conf (dns_a.conf) files will now support the "USERNAME" token for all rewrites, assume you have one of these directadmin.conf value enabled: allow_ttl_override=1 or cluster=1
The ttl is enabled by default, so should be for everyone. Eg: You can confirm with:
./directadmin c | grep allow_ttl_override
Compile time: Sep 9 2020 at 14:10:23
new
CMD_FILE_MANAGER: action=parent_tree to include directory symlinksThe ~/public_html symlink is very often used for quick navigation to the domain's public_html directory. In Evolution, the top-level of directories is obtained with the request:
CMD_FILE_MANAGER?json=yes&filemanager_du=0&action=parent_tree&path=%2F
but because a symlink is a file when lstat is used, it was not shown in the list. This change will include a symlink, if it points to a directory, in the result, but will add "islink" and "linkpath" in the output, eg:
[
{ "path": "/.php", "dirs": 0, "files": 10, "files_size": 0 },
{ "path": "/admin_backups", "dirs": 0, "files": 0, "files_size": 0 },
{ "path": "/user_backups", "dirs": 0, "files": 0, "files_size": 0 },
{ "path": "/.ssh", "dirs": 0, "files": 1, "files_size": 0 },
{ "path": "/public_html", "dirs": 5, "files": 7, "files_size": 12477,"islink": "1", "linkpath": "./domains/domain.com/public_html" },
{ "path": "/domains", "dirs": 3, "files": 0, "files_size": 0 },
{ "path": "/imap", "dirs": 1, "files": 0, "files_size": 0 },
{ "path": "/.trash", "dirs": 2, "files": 0, "files_size": 0 }
]
where "islink' == 1 allows the skin to indicate that it's a symlink, rather than showing it as a full "directory" (eg: add a red arrow or some other indication on the icon)
EVO1966
new
Default Change: TTL from 14400 to 3600Lowered the default_ttl=14400 setting down to 3600. You can set it back, if needed, using: /usr/local/directadmin/directadmin set default_ttl 14400 service directadmin restart
new
Brute Force Monitor: modsec_audit.log Mod_Security (TEMPLATES)The BFM will now scan the modsecurity "modsec_audit.log" files (under /var/log/httpd or /var/log/nginx), when each line is json encoded, to block IPs.
DIRECTADMIN.CONF
This will be OFF by default in the internal directadmin.conf: brute_force_scan_mod_security_logs=0
This is to allow for more testing, although we not had any issues with the json log parser.
ENABLE:
./directadmin set brute_force_scan_mod_security_logs 1
service directadmin restart
The entry shown on the BFM page will only show a select number of entries from the full log.
- host: domain that was attacked (taken from the Host header)
- id: ModSecurity's unique log ID.
- uri: /the/bad?request=../etc/passwd
Note that there are 2 versions of ModSecurity (apache vs nginx), and the json log info varies slightly. DA figures this out automatically based on the 2 different brute_filters.conf entries, but will still try and place the ~same data into the 3 vars above, even if the uri format may differ slightly.
LOGS
either: /var/log/httpd/modsec_audit.log or /var/log/nginx/modsec_audit.log
CUSTOMBUILD
DA only parses those logs if the custombuild/options.conf has: modsecurity=yes
DIVISOR
The brute_filter.list now supports: count_divisor=## which lets you lower the max count needed in order to have it trigger. In this case, we've set it to 2, meaning it will require 1/2 the total number of hits to block. Eg: the default hit count is 100, so this would only need 50 hits to trigger a block.
TEMPLATE
brute_filter.conf, 2 new entries:
mod_security1=type=json&ip_tree=transaction:client_ip&host_tree=transaction:request:headers:host&uri_tree=transaction:request:uri&id_tree=transaction:unique_id&count_divisor=2
mod_security2=type=json&ip_tree=transaction:remote_address&host_tree=request:headers:Host&uri_tree=request:request_line&id_tree=transaction:transaction_id&count_divisor=2
which are type=json lines. The host/id/uri values are take based on the *_tree vars, where the values are those variables are levels down into the json array, the last value being a string.
new
setup.sh errors to return non-zero exit codeAs many installs are automated, it would be great to automatically know if something went wrong. This change to the directadmin binary, scripts/install.sh and setup.sh will all relay the exit code, should it be non-zero.
RETURN CODES
All codes below are possible. The sections just clarify where it might have occurred:
setup.sh:
0: success, help
1: must be root to run setup.sh
/usr/bin/perl missing
32-bit install on 64-bit-only OS
'n' answered for correct OS question
wrong PHP/CB setup choice
bad system date.
3: unable to download the scripts/files.sh for this OS (new unsupported OS?)
unable to download the update.tar.gz
4: update.tar.gz downloaded, but license not valid (possible license issue, similar to 71)
5: cannot find the /usr/local/directadmin/directadmin binary after update.tar.gz extraction
12: openssl.h missing. Ensure pre-install commands were run, before setup.sh or even during (with option to do so)
56: wrong number of ./setup.sh params passed
70: /root/.lid_info did not succeed in being filled for ./setup.sh auto
71: error=1 found in the /root/.lid_info (possible license download issue, expired, etc)
80: /usr/bin/wget is missing (FreeBSD: /usr/local/bin/wget)
install.sh : called via setup.sh, so setup.sh code will match it's return code:
1: FreeBSD: Cannot find diradmin after creation
'getLicense.sh auto' error. See 71.
scripts/packages/services.tar.gz download error
error extracting that services.tar.gz
call to scripts/doChecks.sh has failed
custombuild download error
custombuild build error
/usr/local/bin/php is minssing
/usr/local/directadmin/conf/directadmin.conf is missing after the ./directadmin i.
2XX: the return code of ./directadmin i, below.
2XX: ./directadmin i error:
Run this to check: "./directadmin i""
200: re-install, 'n' provided when asked to re-install.
201: installer run as non-root
202: cannot chdir to /usr/local/directadmin
203: cannot read ./scripts/setup.txt as root
204: data/templates/httpd.conf install issue (does not apply to CB2/Modern instals where custombuild/options.conf exists)
205: Tokenizer error from data/templates/directadmin.conf to conf/directadmin.conf
207: Failure in the creation of the admin account.
208: cannot read the newly installed conf/directadmin.conf
T29054
new
BubbleWrap for LiteSpeed (TEMPLATES)The LiteSpeed User httpd.conf templates now add: BubbleWrap On|Off
near the end of each VH, eg:
|*if WEBSERVER="litespeed"|
<IfModule Litespeed>
CacheRoot lscache
|BUBBLE_WRAP|
</IfModule>
|*endif|
Where |BUBBLE_WRAP| is swapped with the BubbleWrap On|Off text, based on the user.conf jail=ON setting.
TEMPLATES
the 4x virtual_host2.conf templates have the |BUBBLE_WRAP| token, as set above.
fixed
Large file uploads: error handlingPreviously, if a file was too large and one of the conditions happened:
- content-length exceeded the maxfilesize
- content-length exceeded free space on /home/tmp
if any error occurred, DA would immediately stop accepting the download, spit out the error message and close the connection. Since the client was still in the process of uploading the file, the browser would not have been listening for any output yet, so the browser would get a connection closed error. Browsers may have even re-attempted the upload, causing 2 full attempts before giving up.
As DA does not support "Except: 100-continue" header, the cleanest solution is to accept the remainder of the data, do not write it to disk, until the client is happy, and then output the proper error message. This is a waste of bandwidth, but is how other web-servers operate, so this brings DA into the norm of behavior.
As with the second condition, above, DA will now pre-check the available space with statvfs in the uploaded area after opening the file descriptor. If it won't have enough space, the file won't be saved to disk (but bandwidth will continue to be transmitted, as above, to allow a clean error output)
fixed
Debian: Backup without "domains directory" adds extra -C /home/userBug, likely added with this change: directadmin_imap_backup without domains directory throws error
ends up creating a tar backup command that ends in: -C /home/user
without any trailing information being added.
Tar, apparently only on Debian, would throw the message;
/bin/tar: The following options were used after any non-optional arguments in archive create or update mode. These options are positional and affect only arguments that follow them. Please, rearrange them properly.
fixed
gettext: LC_CTYPE to ""The LC_CTYPE was set to "C" but changing it to blank "" is required to allow special characters to be properly displayed.
T20639
fixed
Lower number of SSL key bit-size optionsThe new support for ECC certificates was previously adding all available options from the output of: openssl ecparam -list_curves
it was found that some OSs produce a very large (and confusing) list of possible choices.
Code has been changed to cap that output to only:
- secp384r1
- secp521r1
- prime256v1
and the "text" will be shown at, respectively:
- EC-384
- EC-521
- EC-256
to help make them look less scary.
fixed
Improved checking of forbidden domainsSlight logic change on how the forbidden_domains.list file is checked.
fixed
rspamd blacklist/whitelist to use ^$ string terminationRelating to the addition of wildcards to SpamAssassin/Rspamd: SpamAssassin: Allow wildcard using regex in exim filter, user rspamd.conf files
If you were to be blacklisting: *.com
it would imply that anything@something.com would be blocked, which it was. The issue is that it was adding it to the rspamd configs as: from = “/.*\\.com/â€
which would have also matched somethingcom@something.else, because the dot needed to be double escaped, and the start/end of the string defined. This change now swaps periods with \\. and adds ^ and $ to the start/end of the string, eg: from = "/^.*\\\\.com$/"
fixed
Show User: Additional Bandwidth field missingLiterally "lost in translation". Code was removed during translation. Re-added. Only affects Enhanced. Evolution unaffected.
T27434
fixed
BFM: wp-login.php from 4x to 50x count multiplierIncrease the Brute-force monitor's count limit for the 302 redirect cases on the wordpress wp-login.php from 4x the BFM limit, now to 50x the BFM count limit. This is to ensure there are no false positives, but still present to prevent DDOS style attacks that may hurt the system.
fixed
Use doveadm for CMD_API_POP?type=quota loadsThere are 2 types of loads for CMD_API_POP?type=quota
- CMD_API_POP?type=quota&domain=domain.com
This shows all Users.
If your system has: pop_disk_usage_dovecot_quota=1
For each User in the output, the sub-array data will now have:
usage = 142336
usage_bytes = 142336
quota = 10485760
sent = 5
limit = 10
Where, as doveadm does not return the disk space used (total block usage), but rather size of the files on disk, the usage will be lower than before. Also, the idea of using doveadmn is to greatly reduce load times, as it does not count the data in realtime, but does efficiently keep an up-to-date count of the Maildir.
The result is that the usage and usage_bytes will now always show the same (size of total files on disk), where the 'usage' will be lower than it was before (total size of blocks usage.. actual 'disk usage').
- Per-User usage will remain backwards compatible, as the read of one single account is "typically" not an issue (I'm sure there might be exceptions), but the odds of a timeout would be far less, vs the read of the entire list of accounts.
The per-Email call would usually be: CMD_API_POP?type=quota&domain=domain.com&user=fred
unless you now include: &pop_disk_usage_dovecot_quota=1
NOTE: I've included &json=yes in the example below:
The old way without pop_disk_usage_dovecot_quota=1 will still give all old output, as before, eg:
{
"imap": "270336",
"imap_bytes": "154854",
"inbox": "57344",
"inbox_bytes": "25573",
"quota": "10485760",
"spam": "36864",
"spam_bytes": "36864",
"total": "327680",
"total_bytes": "180427",
"webmail": "0",
"webmail_bytes": "0"
}
but when you add: pop_disk_usage_dovecot_quota=1
(requires pop_disk_usage_dovecot_quota=1 to be enabled in DA itself, which most current boxes probably already have) it should load much faster (most noticeable on very large Maildir accounts with many files), and that would show:
{
"imap": "142336",
"imap_bytes": "142336",
"inbox": "142336",
"inbox_bytes": "142336",
"quota": "10485760",
"total": "142336",
"total_bytes": "10628096",
"webmail": "0",
"webmail_bytes": "0"
}
where you'd lose out on the spam, spam_bytes, and so nothings breaks, and all of imap, imap_bytes, inbox, inbox_bytes will report the same value, as returned by doveadm (multiplied by 1024 to give us bytes). Previously, the "inbox" was only for the literal inbox folder, and "imap" was everything else. Now, they're both the sum of everything.
T27472
fixed
Hash URL: SSH: --create-login-url notifying Users when login_keys_notify_on_creation=1With this change: Option: login_keys_notify_on_creation=2 for locked on
Setting: login_keys_notify_on_creation=1
should have blocked the Message System notice on one-time hash login. (If login_keys_notify_on_creation=2 were set, then yes, the notice would have been sent).
Using login_keys_notify_on_creation=1 now properly suppresses the login hash use notice, when it was created from ssh with the --create-login-url method.
fixed
FileManager to show mtimeThe Filemanager was showing the ctime (last change) of a file/folder, rather than the more commonly used mtime (last modified).
T26895
fixed
Plugins path to 711The /usr/local/directadmin/plugins directory was previously 755. To prevent the listing of the directory, 700 was attempted, was insufficient, so we've settled on 711.
T27905
fixed
rspamd whitelist/blacklist: normal emails to use ^$ regex matchPreviously, a whitelist/blacklist entry would have been: from = "user@email.com"
changed to be: from = "/^user@email\\\\.com$/"
T27926
fixed
Clear Message not showing list of auto-fill subjectsWith the recent support to gettext, we've dropped the data/skins/enhanced/lang/en/internal folder, as it's no longer needed. In that folder was the file: clear_message_system_list.txt
with data:
1=8
2=-- anything --
3=Brute-Force Attack detected in service log
4=is currently down
5=Your backups are now ready
6=An error occurred during the backup
7=emails have just been sent by
8=Warning: The system load average is
which was used to fill the subject auto-fill when typing clearing messages from the Message System.
This resulted in an empty list. This has been fixed by gettext-izing this data into the binaries. If you need to translate them, the string values (=right side) are now visible in the data/lang/internal.pot file https://help.directadmin.com/item.php?id=2142
T27936
fixed
LiteSpeed: Always define php handler : REVERTEDUPDATE: Sept 15, 2020: with the changes below, errors were being thrown: "Your PHP installation appears to be missing the MySQL extension which is required by WordPress."
The changes below are no longer included in the DA binaries, updated on: Compile time: Sep 15 2020 at 15:11:10
OLD:
Requested by LS support: always define the php1/php2 handlers in the User httpd.conf files. Previously, it would have only been set if php versions were swapped .
Affects the setting of tokens:
- HAVE_PHP1_CLI=1
- HAVE_PHP2_CLI=1
which will be set anytime "lsphp" is enabled in the CustomBuild options.conf.
fixed
User creation/modification: ubandwidth=no | OFFAs the "ubandwidth" and other u* options are checkboxes, simply passing them triggered DA to assume they were set. However, setting ubandwdith=OFF (or =no) for example, would not be loggically correct in that DA would still set it to be unlimited.
This fix adds a check any u* option, if passed and set to "OFF" or "no", the checkbox will be ignored.
T28364
fixed
Bubblewrap jail: sendmail delivery to use smtp:587Because the real exim lives outside of the jail, things like php mail() commands cannot access it from inside the jail. They can connect to port 25, so we've crafted a custom /etc/exim.conf to be visible inside the jail, so all deliveries to the jailed exim get send through port 587.
- exim needs to be re-built, exim.pl updated and jailshell 0.3+ installed:
cd /usr/local/directadmin/custombuild
./build update
./build set eximconf yes
./build jailshell
- /etc/exim.jail files need to be generated:
echo "action=rewrite&value=jail" > /usr/local/directadmin/data/task.queue
/usr/local/directadmin/dataskq d
fixed
Trash: get list from true data, in case files were delete with full quotaIf a User moves a file to trash while they have full quota, the .trashinfo file cannot be viewed. Code changes to get the listing from the true data folder: ~/.trash/files/*
instead of: ~/.trash/info/*.trashinfo
The same data will be obtained if both files exist. But if only the ~/.trash/files/file.txt exists, then this will show the file (without specific data/restore info) and allow the file to be manually removed. It will not be automatically removed.
T27541
BUG: found/fixed on Sept 10, 2020 where directories were not shown.
fixed
LetsEncrypt: delete domain.com.letsencrypt_remaining_retries after successThe domain.com.letsencrypt_remaining_retries file will end up being set to 0 should it try 5 times without success. If another attempt does go through later on (manual request through GUI or ssh), this change will ensure the retry file is fully delete as this may have blocked subsequent renewals.
T28404
fixed
Do not install proftpd.conf with ./directadmin i. Rely on CBCustombuild installs the proftpd.conf when proftpd is installed (the default is pure-ftpd anyway). But if ftpd=proftpd was chose, CB would have installed it's proftpd.conf followed by DA installs the templates/proftpd.conf version. Code changed to NOT install the proftpd.conf via DirectAdmin, and simply rely on CustomBuild to do it for us.
T28394
fixed
Ensure no php-fpm#.conf is php=OFF in user.confWhen php=OFF is set in the user.conf, do not create a php-fpm#.conf file for the Uesr. Also ensure it's deleted during a rewrite if the User's php is not ON.
Also hide the php version selector if the domain.com.conf does not have php=OFF
fixed
Enhanced Skin: Default to en lang files if custom lang is missing translationThe internal language translations already did this, so do not apply here. This change only applies to the Enhanced mode of translations, where it looks for a matching .html file in the lang/en folder. The change is when the custom lang does not have said matching .html file, so it falls back to the "en" copy, should it exist. This prevents "none" from showing up, instead showing the correct English version of the string.
fixed
Optimization: string to jsonSwapped the result buffer to use our internal String class, which saves recounting the buffer length each time something is appended. This was implemented while debugging slow load time for the json=yes action=edit in the File Manager for "larger" files (this one was 0.6M)
Enhanced is not affected, as it uses html encoding, directly as it reads the file.
Further optimizations for this might be to read the save the json-encoded string, directly as it's read from disk. This is an edge case (only 1 report), so will omit for the time being.
Other options would be to read the html-encoded TEXT token, without json at all, eg: /CMD_FILE_MANAGER/index.html?action=edit&load_token=TEXT
where TEXT is the value within the Enhanced textarea, which is already html-encoded. With the load_token=TEXT option, the skin an all other tokens are not shown. Only the contents of |TEXT|
fixed
DNS: Pointers: Duplicate records with subdomain pointer cause issuesIntroduced here: Domain Pointers option to receive duplicate dns entries from master domain (SKINS)
when adding a record to a domain, there is an option to duplicate it to any domain pointers below it. With non-absolute records, say "www", this was fine, but extra code was needed if a full value was specified, say: sub.domain.com.
where the pointer.com. would need to receive: sub.pointer.com.
This worked fine, however if the pointer was pointer.domain.com (below pointer.com) this caused issues when editing the pointer's zone directly. Eg, adding a TXT record with left-name: pointer.domain.com.
in the pointer.domain.com. zone ended up with: pointer.pointer.domain.com. as DA was trying to snag the "subdomain" part of the zone to prefix to the pointer's zone.
Code changed to never do this subdomain swap if the end of the left-name ended with the current zone name. So adding pointer.domain.com. matches the pointer's zone name, thus is not touched.
In effect, adding: sub.pointer.domain.com. to the master, would result in adding the exact same record to both domain.com and pointer.domain.com's zones.
T28813
fixed
Do not allow CMD_SSL access if is not enabled in the given domainShould you access /CMD_SSL?domain=domain.com (or /user/ssl in Evolution), when ssl=ON is not present in the domain.com.conf file, you'll get an error:
Could not execute your request SSL is not enabled for this domain
In which case, you'd go to your "Domain Setup" area to enable SSL prior to managing your certificates.
With Enhanced skin, you'll get a direct URL below to: /CMD_ADDITIONAL_DOMAINS?action=view&domain=domain.com
T28864
fixed
ClamAV: freshclam has no reload for CMD_SHOW_SERVICES?json=yesRemove "reload" option for the actions list of the "freshclam" service, as it does not exist.
fixed
File Manager: action=parent_tree to respect filemanager_du=0The filemanager_du=0 can be set either via the directadmin.conf, user.conf, or via GET. The call to: /CMD_FILE_MANAGER?json=yes&filemanager_du=0&action=parent_tree&path=%2F
would expect to not recursively count each child directory usage. This fix will now ONLY show the directory (or dir listing for the current path.
Eg:, the above path=/ would show something like this, where the "dirs", "files", and "files_size" are NOT included in the output to greatly speed things up.
[
{ "path": "/.php" },
{ "path": "/admin_backups" },
{ "path": "/user_backups" },
{ "path": "/.ssh" },
{ "path": "/public_html" , "islink": "1", "linkpath": "./domains/domain.com/public_html" },
{ "path": "/domains" },
{ "path": "/Maildir" },
{ "path": "/imap" },
{ "path": "/.trash" }
]
fixed
doveadm expunge fails on overquota: fallback to old methodIf a User is over quota and has passed their grace period, the doveadm expunge call will fail and the emails will not be removed. If the User is over quota, but within the grace, the emails will still be removed, but the index re-write will still fail.
The solution is not the error, and use the old purge method as a fallback in either the above events.
ERROR
Email::doveadm_expunge: running: /usr/bin/doveadm expunge -u 'user@email.com' mailbox 'INBOX' all
dovecadmn expunge returned an error: doveadm(user@email.com): Error: Mailbox INBOX: write(/home/fred/imap/email.com/user/Maildir/dovecot-uidlist.tmp) failed: Disc quota exceeded
doveadm(user@email.com): Error: Syncing mailbox INBOX failed: Mailbox INBOX: write(/home/fred/imap/email.com/user/Maildir/dovecot-uidlist.tmp) failed: Disc quota exceeded
T29043