Skip to content

Commit b115533

Browse files
author
Till Brehm
committed
Merge branch 'certbot_cleanup' into 'develop'
Let's Encrypt: auto cleanup & ECC Closes #5226, #6563, and #6746 See merge request ispconfig/ispconfig3!1937
2 parents 93dbe67 + 1452159 commit b115533

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2200
-758
lines changed

install/lib/installer_base.lib.php

Lines changed: 217 additions & 181 deletions
Large diffs are not rendered by default.

install/tpl/server.ini.master

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,11 @@ vhost_proxy_protocol_enabled=n
142142
vhost_proxy_protocol_protocols=ipv4
143143
vhost_proxy_protocol_http_port=880
144144
vhost_proxy_protocol_https_port=8443
145+
le_signature_type=ECDSA
146+
le_delete_on_site_remove=y
147+
le_auto_cleanup=y
148+
le_revoke_before_delete=y
149+
le_auto_cleanup_denylist=[server_name]
145150

146151
[dns]
147152
bind_user=root

interface/lib/classes/validate_domain.inc.php

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,5 +278,115 @@ function _wildcard_limit() {
278278
return true; // admin may always add wildcard domain
279279
}
280280

281+
/**
282+
* Parses $expression to check if it is a valid shell glob pattern.
283+
* Does not support extended glob matching syntax.
284+
*
285+
* @see https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html
286+
* @param string $expression
287+
* @param string $allowed_chars regexp of allowed characters in expression. ? and * are always allowed
288+
* @param string|null $allowed_brace_chars regexp of allowed characters in brace ([...]). Dash is always allowed. If empty, then $allowed_chars will be used
289+
* @return bool
290+
*/
291+
private function validate_glob($expression, $allowed_chars = '/^.$/u', $allowed_brace_chars = null) {
292+
$escaping = false;
293+
$in_brace = false;
294+
$brace_content = [];
295+
$chars = preg_split('//u', $expression, -1, PREG_SPLIT_NO_EMPTY);
296+
foreach($chars as $i => $c) {
297+
if($in_brace) {
298+
// the first char after brace start can be a ].
299+
if(($c == ']' && empty($brace_content)) || $c != ']') {
300+
$brace_content[] = $c;
301+
} else {
302+
$in_brace = false;
303+
$last_is_dash = false;
304+
foreach($brace_content as $bi => $bc) {
305+
// dashes are always allowed
306+
if($bc == '-') {
307+
// ... but we consider consecutive dashes as invalid
308+
if($last_is_dash) {
309+
return false;
310+
}
311+
// ... and need to validate it as allowed char when it is first or last
312+
if(($bi == 0 || $bi == count($brace_content) - 1) && !preg_match($allowed_brace_chars ?: $allowed_chars, '-')) {
313+
return false;
314+
}
315+
$last_is_dash = true;
316+
} else {
317+
$last_is_dash = false;
318+
// negate chars are always allowed
319+
if($bi == 0 && ($bc == '^' || $bc == '!') && count($brace_content) > 1) {
320+
continue;
321+
}
322+
if(!preg_match($allowed_brace_chars ?: $allowed_chars, $bc)) {
323+
return false;
324+
}
325+
}
326+
}
327+
}
328+
} else {
329+
$peek = $i == count($chars) - 1 ? '' : $chars[$i + 1];
330+
if($c == '\\' && in_array($peek, ['[', ']', '*', '?'])) {
331+
$escaping = true;
332+
continue;
333+
} elseif($c == '[' && !$escaping) {
334+
$in_brace = true;
335+
$brace_content = [];
336+
} elseif($escaping || ($c != '?' && $c != '*')) {
337+
if(!preg_match($allowed_chars, $c)) {
338+
return false;
339+
}
340+
}
341+
$escaping = false;
342+
}
343+
}
344+
return !$in_brace && !$escaping;
345+
}
346+
347+
/**
348+
* Validates that input is a comma separated list of domain globs.
349+
* Can be used for fnmatch() as input.
350+
*/
351+
function domain_glob_list($field_name, $field_value, $validator) {
352+
global $app;
353+
$allowempty = $validator['allowempty'] ?: 'n';
354+
$exceptions = $validator['exceptions'] ?: [];
355+
$allow_exception_as_substring = $validator['allow_exception_as_substring'] ?: 'y';
356+
if(!$field_value) {
357+
if($allowempty == 'y') {
358+
return '';
359+
}
360+
return $this->get_error($validator['errmsg']);
361+
}
362+
$parts = explode(',', $field_value);
363+
foreach($parts as $part) {
364+
$part = trim($part);
365+
// an empty part means there is a stray comma
366+
if(empty($part)) {
367+
return $this->get_error($validator['errmsg']);
368+
}
369+
// allow list placeholders that you will replace with real values at evaluation
370+
if(in_array($part, $exceptions, true)) {
371+
continue;
372+
}
373+
// optionally do not allow placeholders to be part of an expression
374+
if($allow_exception_as_substring == 'n') {
375+
foreach($exceptions as $exception) {
376+
if(strpos($part, $exception) !== false) {
377+
return $this->get_error($validator['errmsg']);
378+
}
379+
}
380+
}
381+
// A domain glob needs to:
382+
// * be a valid glob with only a-z0-9._- as characters
383+
// * have at least one dot in it
384+
// * not have two consecutive dots
385+
if(!$this->validate_glob($part, '/^[a-z0-9._-]$/ui') || strpos($part, '.') === false || strpos($part, '..') !== false) {
386+
return $this->get_error($validator['errmsg']);
387+
}
388+
}
389+
return '';
390+
}
281391

282392
}

interface/web/admin/form/server_config.tform.php

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -574,15 +574,6 @@
574574
'default' => '2048',
575575
'value' => array('1024' => 'weak (1024)', '2048' => 'normal (2048)', '4096' => 'strong (4096)')
576576
),
577-
'relayhost_password' => array(
578-
'datatype' => 'VARCHAR',
579-
'formtype' => 'TEXT',
580-
'default' => '',
581-
'value' => '',
582-
'width' => '40',
583-
'maxlength' => '255'
584-
),
585-
586577
'pop3_imap_daemon' => array(
587578
'datatype' => 'VARCHAR',
588579
'formtype' => 'SELECT',
@@ -1642,6 +1633,49 @@
16421633
'width' => '40',
16431634
'maxlength' => '255'
16441635
),
1636+
'le_signature_type' => array(
1637+
'datatype' => 'VARCHAR',
1638+
'formtype' => 'SELECT',
1639+
'default' => 'ECDSA',
1640+
'value' => array('RSA' => 'RSA (RSA encryption with SHA-256)', 'ECDSA' => 'ECDSA (Elliptic Curve Digital Signature Algorithm)')
1641+
),
1642+
'le_delete_on_site_remove' => array(
1643+
'datatype' => 'VARCHAR',
1644+
'formtype' => 'CHECKBOX',
1645+
'default' => 'y',
1646+
'value' => array(0 => 'n', 1 => 'y')
1647+
),
1648+
'le_auto_cleanup' => array(
1649+
'datatype' => 'VARCHAR',
1650+
'formtype' => 'CHECKBOX',
1651+
'default' => 'y',
1652+
'value' => array(0 => 'n', 1 => 'y')
1653+
),
1654+
'le_auto_cleanup_denylist' => array(
1655+
'validators' => array(
1656+
array (
1657+
'type' => 'CUSTOM',
1658+
'class' => 'validate_domain',
1659+
'function' => 'domain_glob_list',
1660+
'allowempty' => 'y',
1661+
'exceptions' => array('[server_name]'),
1662+
'allow_exception_as_substring' => 'n',
1663+
'errmsg'=> 'le_auto_cleanup_denylist_error_custom'
1664+
),
1665+
),
1666+
'datatype' => 'VARCHAR',
1667+
'formtype' => 'TEXT',
1668+
'default' => '[server_name]',
1669+
'value' => '',
1670+
'width' => '40',
1671+
'maxlength' => '255'
1672+
),
1673+
'le_revoke_before_delete' => array(
1674+
'datatype' => 'VARCHAR',
1675+
'formtype' => 'CHECKBOX',
1676+
'default' => 'y',
1677+
'value' => array(0 => 'n', 1 => 'y')
1678+
),
16451679
//#################################
16461680
// END Datatable fields
16471681
//#################################

interface/web/admin/lib/lang/ar_server_config.lng

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,3 +363,10 @@ $wb['sysbackup_copies_txt'] = 'Número de copias de seguridad del sistema';
363363
$wb['sysbackup_copies_error_empty'] = 'El número de copias de seguridad del sistema no debe estar vacío';
364364
$wb['sysbackup_copies_error_regex'] = 'El número de copias de seguridad del sistema debe ser un número entre 1 y 3';
365365
$wb['sysbackup_copies_note_txt'] = '(0 = desactivado)';
366+
$wb['le_signature_type_txt'] = 'Certificate signature type';
367+
$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates';
368+
$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged';
369+
$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged. <br>E.g. <code>mail.*, externally-managed.example.com</code> <br>Placeholders:';
370+
$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs';
371+
$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal';
372+
$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)';

interface/web/admin/lib/lang/bg_server_config.lng

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,3 +363,10 @@ $wb['sysbackup_copies_txt'] = 'Number of ISPConfig backups';
363363
$wb['sysbackup_copies_error_empty'] = 'Number of ISPConfig backups must not be empty';
364364
$wb['sysbackup_copies_error_regex'] = 'Number of ISPConfig backups must be a number between 1 and 3';
365365
$wb['sysbackup_copies_note_txt'] = '(0 = off)';
366+
$wb['le_signature_type_txt'] = 'Certificate signature type';
367+
$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates';
368+
$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged';
369+
$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged. <br>E.g. <code>mail.*, externally-managed.example.com</code> <br>Placeholders:';
370+
$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs';
371+
$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal';
372+
$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)';

interface/web/admin/lib/lang/br_server_config.lng

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,3 +364,10 @@ $wb['sysbackup_copies_error_empty'] = 'O número de copias de seguridad do siste
364364
$wb['sysbackup_copies_error_regex'] = 'O número de copias de seguridad do sistema deve ser um número entre 1 e 3';
365365
$wb['sysbackup_copies_note_txt'] = '(0 = desativado)';
366366

367+
$wb['le_signature_type_txt'] = 'Certificate signature type';
368+
$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates';
369+
$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged';
370+
$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged. <br>E.g. <code>mail.*, externally-managed.example.com</code> <br>Placeholders:';
371+
$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs';
372+
$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal';
373+
$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)';

interface/web/admin/lib/lang/ca_server_config.lng

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,3 +363,10 @@ $wb['sysbackup_copies_txt'] = 'Number of ISPConfig backups';
363363
$wb['sysbackup_copies_error_empty'] = 'Number of ISPConfig backups must not be empty';
364364
$wb['sysbackup_copies_error_regex'] = 'Number of ISPConfig backups must be a number between 1 and 3';
365365
$wb['sysbackup_copies_note_txt'] = '(0 = off)';
366+
$wb['le_signature_type_txt'] = 'Certificate signature type';
367+
$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates';
368+
$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged';
369+
$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged. <br>E.g. <code>mail.*, externally-managed.example.com</code> <br>Placeholders:';
370+
$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs';
371+
$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal';
372+
$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)';

interface/web/admin/lib/lang/cn_server_config.lng

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,8 @@ $wb['relayhost_txt'] = '中继主机';
5252
$wb['relayhost_user_txt'] = '中继主机用户名';
5353
$wb['relayhost_password_txt'] = '中继主机密码';
5454
$wb['reject_sender_login_mismatch_txt'] = '拒绝发件人和登录用户不匹配';
55-
$wb['reject_unknown_txt'] = '拒绝未知主机名';
56-
$wb['tooltip_reject_unknown_txt'] = '需要主机名通过DNS检查。对经过身份验证的用户不进行检查。';
5755
$wb['reject_unknown_txt'] = '拒绝未知的helo主机名';
5856
$wb['tooltip_reject_unknown_txt'] = '需要主机名通过DNS检测。对已认证用户不进行检查。';
59-
$wb['reject_unknown_helo_txt'] = '拒绝未知的 helo 主机名';
60-
$wb['reject_unknown_client_txt'] = '拒绝未知的客户端主机名';
61-
$wb['reject_unknown_client_helo_txt'] = '拒绝未知的helo和客户端主机名';
6257
$wb['reject_unknown_helo_txt'] = '拒绝未知的helo主机名';
6358
$wb['reject_unknown_client_txt'] = '拒绝未知的客户端主机名';
6459
$wb['reject_unknown_client_helo_txt'] = '拒绝未知的helo和客户端主机名';
@@ -241,13 +236,12 @@ $wb['overquota_db_notify_threshold_txt'] = 'DB配额警告使用水平';
241236
$wb['overquota_db_notify_admin_txt'] = '向管理员发送DB配额警告';
242237
$wb['overquota_db_notify_reseller_txt'] = '向经销商发送DB配额警告';
243238
$wb['overquota_db_notify_client_txt'] = '向客户发送DB配额警告';
244-
$wb['monitor_system_updates_txt'] = '检查Linux更新';
239+
$wb['monitor_system_updates_txt'] = '检查 Linux 更新';
245240
$wb['php_handler_txt'] = '默认的 PHP 处理器';
246241
$wb['php_fpm_default_chroot_txt'] = '默认的 PHP-FPM chroot';
247242
$wb['php_fpm_incron_reload_txt'] = '安装 incron 触发器文件以重新加载 PHP-FPM';
248243
$wb['disabled_txt'] = '已禁用';
249244
$wb['dkim_strength_txt'] = 'DKIM 强度';
250-
$wb['monitor_system_updates_txt'] = '检查 Linux 更新';
251245
$wb['invalid_apache_user_txt'] = '无效的 Apache 用户。';
252246
$wb['invalid_apache_group_txt'] = '无效的 Apache 组。';
253247
$wb['backup_dir_error_regex'] = '无效的备份目录。';
@@ -363,3 +357,16 @@ $wb['sysbackup_copies_txt'] = 'Number of ISPConfig backups';
363357
$wb['sysbackup_copies_error_empty'] = 'Number of ISPConfig backups must not be empty';
364358
$wb['sysbackup_copies_error_regex'] = 'Number of ISPConfig backups must be a number between 1 and 3';
365359
$wb['sysbackup_copies_note_txt'] = '(0 = off)';
360+
$wb['dkim_path_txt'] = 'DKIM Path';
361+
$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix';
362+
$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix';
363+
$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.';
364+
$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.';
365+
$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on';
366+
$wb['le_signature_type_txt'] = 'Certificate signature type';
367+
$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates';
368+
$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged';
369+
$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged. <br>E.g. <code>mail.*, externally-managed.example.com</code> <br>Placeholders:';
370+
$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs';
371+
$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal';
372+
$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)';

interface/web/admin/lib/lang/cz_server_config.lng

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ $wb['php_fpm_socket_dir_error_empty'] = 'PHP-FPM adresář pro socket je prázdn
150150
$wb['try_rescue_txt'] = 'Povolit monitorování služeb a restartovat při selhání';
151151
$wb['do_not_try_rescue_mysql_txt'] = 'Zakázat MySQL monitorování';
152152
$wb['do_not_try_rescue_mail_txt'] = 'Zakázat E-mail monitorování';
153-
$wb['rescue_description_txt'] = '<b>Informace:</b> Pokud chcete např. vypnout MySQL službu zatrhněte políčko \"Zakázat MySQL monitorování\" změna se provede do 2-3 minut.<br>Pokud nepočkáte 2-3 minuty, monitorování nastartuje službu MySQL automaticky znovu !';
153+
$wb['rescue_description_txt'] = '<b>Informace:</b> Pokud chcete např. vypnout MySQL službu zatrhněte políčko "Zakázat MySQL monitorování" změna se provede do 2-3 minut.<br>Pokud nepočkáte 2-3 minuty, monitorování nastartuje službu MySQL automaticky znovu !';
154154
$wb['enable_sni_txt'] = 'Aktivovat SNI (Server Name Indication)';
155155
$wb['do_not_try_rescue_httpd_txt'] = 'Zakázat HTTPD monitorování';
156156
$wb['set_folder_permissions_on_update_txt'] = 'Nastavení oprávnění složky při aktualizaci';
@@ -363,3 +363,10 @@ $wb['sysbackup_copies_txt'] = 'Number of ISPConfig backups';
363363
$wb['sysbackup_copies_error_empty'] = 'Number of ISPConfig backups must not be empty';
364364
$wb['sysbackup_copies_error_regex'] = 'Number of ISPConfig backups must be a number between 1 and 3';
365365
$wb['sysbackup_copies_note_txt'] = '(0 = off)';
366+
$wb['le_signature_type_txt'] = 'Certificate signature type';
367+
$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates';
368+
$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged';
369+
$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged. <br>E.g. <code>mail.*, externally-managed.example.com</code> <br>Placeholders:';
370+
$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs';
371+
$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal';
372+
$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)';

0 commit comments

Comments
 (0)