mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2024-11-21 17:16:54 +02:00
[Web] add mTLS Authentication
This commit is contained in:
parent
a794c1ba6c
commit
75eb1c42d5
@ -204,6 +204,17 @@ chown -R 82:82 /web/templates/cache
|
||||
# Clear cache
|
||||
find /web/templates/cache/* -not -name '.gitkeep' -delete
|
||||
|
||||
# list client ca of all domains for
|
||||
CA_LIST="/etc/nginx/conf.d/client_cas.crt"
|
||||
# Clear the output file
|
||||
> "$CA_LIST"
|
||||
# Execute the query and append each value to the output file
|
||||
mysql --socket=/var/run/mysqld/mysqld.sock -u ${DBUSER} -p${DBPASS} ${DBNAME} -e "SELECT ssl_client_ca FROM domain;" | while read -r ca; do
|
||||
echo "$ca" >> "$CA_LIST"
|
||||
done
|
||||
echo "SSL client CAs have been appended to $CA_LIST"
|
||||
|
||||
|
||||
# Run hooks
|
||||
for file in /hooks/*; do
|
||||
if [ -x "${file}" ]; then
|
||||
|
@ -13,6 +13,8 @@
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_tickets off;
|
||||
|
||||
include /etc/nginx/conf.d/includes/ssl_client_auth.conf;
|
||||
|
||||
add_header Strict-Transport-Security "max-age=15768000;";
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
@ -101,6 +103,10 @@
|
||||
include /etc/nginx/fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||
fastcgi_param TLS_SUCCESS $ssl_client_verify;
|
||||
fastcgi_param TLS_ISSUER $ssl_client_i_dn;
|
||||
fastcgi_param TLS_DN $ssl_client_s_dn;
|
||||
fastcgi_param TLS_CERT $ssl_client_cert;
|
||||
fastcgi_read_timeout 3600;
|
||||
fastcgi_send_timeout 3600;
|
||||
}
|
||||
|
4
data/conf/nginx/includes/ssl_client_auth.conf
Normal file
4
data/conf/nginx/includes/ssl_client_auth.conf
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
ssl_verify_client optional;
|
||||
ssl_client_certificate /etc/nginx/conf.d/client_cas.crt;
|
||||
|
23
data/conf/nginx/templates/ssl_client_auth.template.sh
Executable file
23
data/conf/nginx/templates/ssl_client_auth.template.sh
Executable file
@ -0,0 +1,23 @@
|
||||
apk add mariadb-client
|
||||
|
||||
# List client CA of all domains
|
||||
CA_LIST="/etc/nginx/conf.d/client_cas.crt"
|
||||
> "$CA_LIST"
|
||||
|
||||
# Define your SQL query
|
||||
query="SELECT DISTINCT ssl_client_ca FROM domain WHERE ssl_client_ca IS NOT NULL;"
|
||||
result=$(mysql --socket=/var/run/mysqld/mysqld.sock -u ${DBUSER} -p${DBPASS} ${DBNAME} -e "$query" -B -N)
|
||||
if [ -n "$result" ]; then
|
||||
echo "$result" | while IFS= read -r line; do
|
||||
echo -e "$line"
|
||||
done > $CA_LIST
|
||||
#tail -n 1 "$CA_LIST" | wc -c | xargs -I {} truncate "$CA_LIST" -s -{}
|
||||
echo "
|
||||
ssl_verify_client optional;
|
||||
ssl_client_certificate /etc/nginx/conf.d/client_cas.crt;
|
||||
" > /etc/nginx/conf.d/includes/ssl_client_auth.conf
|
||||
echo "SSL client CAs have been appended to $CA_LIST"
|
||||
else
|
||||
> /etc/nginx/conf.d/includes/ssl_client_auth.conf
|
||||
echo "No SSL client CAs found"
|
||||
fi
|
@ -233,6 +233,75 @@ function user_login($user, $pass, $extra = null){
|
||||
|
||||
return false;
|
||||
}
|
||||
function user_mutualtls_login() {
|
||||
global $pdo;
|
||||
|
||||
if (empty($_SERVER["TLS_SUCCESS"]) || empty($_SERVER["TLS_DN"]) || empty($_SERVER["TLS_ISSUER"])) {
|
||||
// missing info
|
||||
return false;
|
||||
}
|
||||
if (!$_SERVER["TLS_SUCCESS"]) {
|
||||
// mutual tls login failed
|
||||
return false;
|
||||
}
|
||||
|
||||
// parse dn
|
||||
$pairs = explode(',', $_SERVER["TLS_DN"]);
|
||||
$dn_details = [];
|
||||
foreach ($pairs as $pair) {
|
||||
$keyValue = explode('=', $pair);
|
||||
$dn_details[$keyValue[0]] = $keyValue[1];
|
||||
}
|
||||
// parse dn
|
||||
$pairs = explode(',', $_SERVER["TLS_ISSUER"]);
|
||||
$issuer_details = [];
|
||||
foreach ($pairs as $pair) {
|
||||
$keyValue = explode('=', $pair);
|
||||
$issuer_details[$keyValue[0]] = $keyValue[1];
|
||||
}
|
||||
|
||||
$user = $dn_details['emailAddress'];
|
||||
if (empty($user)){
|
||||
// no user specified
|
||||
return false;
|
||||
}
|
||||
|
||||
$search = "";
|
||||
ksort($issuer_details);
|
||||
foreach ($issuer_details as $key => $value) {
|
||||
$search .= "{$key}={$value},";
|
||||
}
|
||||
$search = rtrim($search, ',');
|
||||
if (empty($search)){
|
||||
// incomplete issuer details
|
||||
return false;
|
||||
}
|
||||
|
||||
$user_split = explode('@', $user);
|
||||
$local_part = $user_split[0];
|
||||
$domain = $user_split[1];
|
||||
// search for match
|
||||
$stmt = $pdo->prepare("SELECT * FROM `domain` AS d1
|
||||
INNER JOIN `mailbox` ON mailbox.domain = d1.domain
|
||||
INNER JOIN `domain` AS d2 ON mailbox.domain = d2.domain
|
||||
WHERE `kind` NOT REGEXP 'location|thing|group'
|
||||
AND d2.`ssl_client_issuer` = :search
|
||||
AND d2.`active`='1'
|
||||
AND mailbox.`active`='1'
|
||||
AND mailbox.`username` = :user");
|
||||
$stmt->execute(array(
|
||||
':search' => $search,
|
||||
':user' => $user
|
||||
));
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
// user not found
|
||||
if (!$row){
|
||||
return false;
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
function apppass_login($user, $pass, $app_passwd_data, $extra = null){
|
||||
global $pdo;
|
||||
|
||||
|
@ -2522,6 +2522,31 @@ function clear_session(){
|
||||
session_destroy();
|
||||
session_write_close();
|
||||
}
|
||||
function is_valid_ssl_cert($cert) {
|
||||
if (empty($cert)) {
|
||||
return false;
|
||||
}
|
||||
$cert_res = openssl_x509_read($cert);
|
||||
if ($cert_res === false) {
|
||||
return false;
|
||||
}
|
||||
openssl_x509_free($cert_res);
|
||||
|
||||
return true;
|
||||
}
|
||||
function has_ssl_client_auth() {
|
||||
global $pdo;
|
||||
|
||||
$stmt = $pdo->query("SELECT domain FROM `domain`
|
||||
WHERE `ssl_client_ca` IS NOT NULL
|
||||
AND `ssl_client_issuer` IS NOT NULL");
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if (!$row){
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function get_logs($application, $lines = false) {
|
||||
if ($lines === false) {
|
||||
|
@ -528,11 +528,24 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
);
|
||||
return false;
|
||||
}
|
||||
$active = (isset($_data['active'])) ? intval($_data['active']) : $DOMAIN_DEFAULT_ATTRIBUTES['active'];
|
||||
$active = (isset($_data['active'])) ? intval($_data['active']) : $DOMAIN_DEFAULT_ATTRIBUTES['active'];
|
||||
$relay_all_recipients = (isset($_data['relay_all_recipients'])) ? intval($_data['relay_all_recipients']) : $DOMAIN_DEFAULT_ATTRIBUTES['relay_all_recipients'];
|
||||
$relay_unknown_only = (isset($_data['relay_unknown_only'])) ? intval($_data['relay_unknown_only']) : $DOMAIN_DEFAULT_ATTRIBUTES['relay_unknown_only'];
|
||||
$backupmx = (isset($_data['backupmx'])) ? intval($_data['backupmx']) : $DOMAIN_DEFAULT_ATTRIBUTES['backupmx'];
|
||||
$gal = (isset($_data['gal'])) ? intval($_data['gal']) : $DOMAIN_DEFAULT_ATTRIBUTES['gal'];
|
||||
$relay_unknown_only = (isset($_data['relay_unknown_only'])) ? intval($_data['relay_unknown_only']) : $DOMAIN_DEFAULT_ATTRIBUTES['relay_unknown_only'];
|
||||
$backupmx = (isset($_data['backupmx'])) ? intval($_data['backupmx']) : $DOMAIN_DEFAULT_ATTRIBUTES['backupmx'];
|
||||
$gal = (isset($_data['gal'])) ? intval($_data['gal']) : $DOMAIN_DEFAULT_ATTRIBUTES['gal'];
|
||||
$ssl_client_ca = (is_valid_ssl_cert(trim($_data['ssl_client_ca']))) ? trim($_data['ssl_client_ca']) : null;
|
||||
$ssl_client_issuer = "";
|
||||
if (isset($ssl_client_ca)) {
|
||||
$ca_issuer = openssl_x509_parse($ssl_client_ca);
|
||||
if (!empty($ca_issuer) && is_array($ca_issuer['issuer'])){
|
||||
$ca_issuer = $ca_issuer['issuer'];
|
||||
ksort($ca_issuer);
|
||||
foreach ($ca_issuer as $key => $value) {
|
||||
$ssl_client_issuer .= "{$key}={$value},";
|
||||
}
|
||||
$ssl_client_issuer = rtrim($ssl_client_issuer, ',');
|
||||
}
|
||||
}
|
||||
if ($relay_all_recipients == 1) {
|
||||
$backupmx = '1';
|
||||
}
|
||||
@ -588,22 +601,33 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
':domain' => '%@' . $domain
|
||||
));
|
||||
// save domain
|
||||
$stmt = $pdo->prepare("INSERT INTO `domain` (`domain`, `description`, `aliases`, `mailboxes`, `defquota`, `maxquota`, `quota`, `backupmx`, `gal`, `active`, `relay_unknown_only`, `relay_all_recipients`)
|
||||
VALUES (:domain, :description, :aliases, :mailboxes, :defquota, :maxquota, :quota, :backupmx, :gal, :active, :relay_unknown_only, :relay_all_recipients)");
|
||||
$stmt->execute(array(
|
||||
':domain' => $domain,
|
||||
':description' => $description,
|
||||
':aliases' => $aliases,
|
||||
':mailboxes' => $mailboxes,
|
||||
':defquota' => $defquota,
|
||||
':maxquota' => $maxquota,
|
||||
':quota' => $quota,
|
||||
':backupmx' => $backupmx,
|
||||
':gal' => $gal,
|
||||
':active' => $active,
|
||||
':relay_unknown_only' => $relay_unknown_only,
|
||||
':relay_all_recipients' => $relay_all_recipients
|
||||
));
|
||||
try {
|
||||
$stmt = $pdo->prepare("INSERT INTO `domain` (`domain`, `description`, `aliases`, `mailboxes`, `defquota`, `maxquota`, `quota`, `backupmx`, `gal`, `active`, `relay_unknown_only`, `relay_all_recipients`, `ssl_client_issuer`, `ssl_client_ca`)
|
||||
VALUES (:domain, :description, :aliases, :mailboxes, :defquota, :maxquota, :quota, :backupmx, :gal, :active, :relay_unknown_only, :relay_all_recipients, :ssl_client_issuer, :ssl_client_ca)");
|
||||
$stmt->execute(array(
|
||||
':domain' => $domain,
|
||||
':description' => $description,
|
||||
':aliases' => $aliases,
|
||||
':mailboxes' => $mailboxes,
|
||||
':defquota' => $defquota,
|
||||
':maxquota' => $maxquota,
|
||||
':quota' => $quota,
|
||||
':backupmx' => $backupmx,
|
||||
':gal' => $gal,
|
||||
':active' => $active,
|
||||
':relay_unknown_only' => $relay_unknown_only,
|
||||
':relay_all_recipients' => $relay_all_recipients,
|
||||
':ssl_client_issuer' => $ssl_client_issuer,
|
||||
'ssl_client_ca' => $ssl_client_ca
|
||||
));
|
||||
} catch (PDOException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => $e->getMessage()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
// save tags
|
||||
foreach($tags as $index => $tag){
|
||||
if (empty($tag)) continue;
|
||||
@ -654,15 +678,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
}
|
||||
if (!empty($restart_sogo)) {
|
||||
$restart_response = json_decode(docker('post', 'sogo-mailcow', 'restart'), true);
|
||||
if ($restart_response['type'] == "success") {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => array('domain_added', htmlspecialchars($domain))
|
||||
);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if ($restart_response['type'] != "success") {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'warning',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
@ -671,6 +687,18 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!empty($ssl_client_ca) && !empty($ssl_client_issuer)) {
|
||||
// restart nginx
|
||||
$restart_response = json_decode(docker('post', 'nginx-mailcow', 'restart'), true);
|
||||
if ($restart_response['type'] != "success") {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'warning',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => 'nginx_restart_failed'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
@ -2673,7 +2701,22 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
$maxquota = (!empty($_data['maxquota'])) ? $_data['maxquota'] : ($is_now['max_quota_for_mbox'] / 1048576);
|
||||
$quota = (!empty($_data['quota'])) ? $_data['quota'] : ($is_now['max_quota_for_domain'] / 1048576);
|
||||
$description = (!empty($_data['description'])) ? $_data['description'] : $is_now['description'];
|
||||
$tags = (is_array($_data['tags']) ? $_data['tags'] : array());
|
||||
$tags = (is_array($_data['tags']) ? $_data['tags'] : array());
|
||||
$ssl_client_ca = (is_valid_ssl_cert(trim($_data['ssl_client_ca']))) ? trim($_data['ssl_client_ca']) : $is_now['ssl_client_ca'];
|
||||
$ssl_client_issuer = $is_now['ssl_client_issuer'];
|
||||
if (is_valid_ssl_cert(trim($_data['ssl_client_ca']))){
|
||||
if (isset($ssl_client_ca)) {
|
||||
$ca_issuer = openssl_x509_parse($ssl_client_ca);
|
||||
if (!empty($ca_issuer) && is_array($ca_issuer['issuer'])){
|
||||
$ca_issuer = $ca_issuer['issuer'];
|
||||
ksort($ca_issuer);
|
||||
foreach ($ca_issuer as $key => $value) {
|
||||
$ssl_client_issuer .= "{$key}={$value},";
|
||||
}
|
||||
$ssl_client_issuer = rtrim($ssl_client_issuer, ',');
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($relay_all_recipients == '1') {
|
||||
$backupmx = '1';
|
||||
}
|
||||
@ -2773,35 +2816,47 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare("UPDATE `domain` SET
|
||||
`relay_all_recipients` = :relay_all_recipients,
|
||||
`relay_unknown_only` = :relay_unknown_only,
|
||||
`backupmx` = :backupmx,
|
||||
`gal` = :gal,
|
||||
`active` = :active,
|
||||
`quota` = :quota,
|
||||
`defquota` = :defquota,
|
||||
`maxquota` = :maxquota,
|
||||
`relayhost` = :relayhost,
|
||||
`mailboxes` = :mailboxes,
|
||||
`aliases` = :aliases,
|
||||
`description` = :description
|
||||
WHERE `domain` = :domain");
|
||||
$stmt->execute(array(
|
||||
':relay_all_recipients' => $relay_all_recipients,
|
||||
':relay_unknown_only' => $relay_unknown_only,
|
||||
':backupmx' => $backupmx,
|
||||
':gal' => $gal,
|
||||
':active' => $active,
|
||||
':quota' => $quota,
|
||||
':defquota' => $defquota,
|
||||
':maxquota' => $maxquota,
|
||||
':relayhost' => $relayhost,
|
||||
':mailboxes' => $mailboxes,
|
||||
':aliases' => $aliases,
|
||||
':description' => $description,
|
||||
':domain' => $domain
|
||||
));
|
||||
try {
|
||||
$stmt = $pdo->prepare("UPDATE `domain` SET
|
||||
`relay_all_recipients` = :relay_all_recipients,
|
||||
`relay_unknown_only` = :relay_unknown_only,
|
||||
`backupmx` = :backupmx,
|
||||
`gal` = :gal,
|
||||
`active` = :active,
|
||||
`quota` = :quota,
|
||||
`defquota` = :defquota,
|
||||
`maxquota` = :maxquota,
|
||||
`relayhost` = :relayhost,
|
||||
`mailboxes` = :mailboxes,
|
||||
`aliases` = :aliases,
|
||||
`description` = :description,
|
||||
`ssl_client_ca` = :ssl_client_ca,
|
||||
`ssl_client_issuer` = :ssl_client_issuer
|
||||
WHERE `domain` = :domain");
|
||||
$stmt->execute(array(
|
||||
':relay_all_recipients' => $relay_all_recipients,
|
||||
':relay_unknown_only' => $relay_unknown_only,
|
||||
':backupmx' => $backupmx,
|
||||
':gal' => $gal,
|
||||
':active' => $active,
|
||||
':quota' => $quota,
|
||||
':defquota' => $defquota,
|
||||
':maxquota' => $maxquota,
|
||||
':relayhost' => $relayhost,
|
||||
':mailboxes' => $mailboxes,
|
||||
':aliases' => $aliases,
|
||||
':description' => $description,
|
||||
':ssl_client_ca' => $ssl_client_ca,
|
||||
':ssl_client_issuer' => $ssl_client_issuer,
|
||||
':domain' => $domain
|
||||
));
|
||||
}catch (PDOException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => $e->getMessage()
|
||||
);
|
||||
}
|
||||
// save tags
|
||||
foreach($tags as $index => $tag){
|
||||
if (empty($tag)) continue;
|
||||
@ -4416,7 +4471,8 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
`relay_unknown_only`,
|
||||
`backupmx`,
|
||||
`gal`,
|
||||
`active`
|
||||
`active`,
|
||||
`ssl_client_ca`
|
||||
FROM `domain` WHERE `domain`= :domain");
|
||||
$stmt->execute(array(
|
||||
':domain' => $_data
|
||||
@ -4484,6 +4540,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
$domaindata['relay_unknown_only_int'] = $row['relay_unknown_only'];
|
||||
$domaindata['created'] = $row['created'];
|
||||
$domaindata['modified'] = $row['modified'];
|
||||
$domaindata['ssl_client_ca'] = $row['ssl_client_ca'];
|
||||
$stmt = $pdo->prepare("SELECT COUNT(`address`) AS `alias_count` FROM `alias`
|
||||
WHERE (`domain`= :domain OR `domain` IN (SELECT `alias_domain` FROM `alias_domain` WHERE `target_domain` = :domain2))
|
||||
AND `address` NOT IN (
|
||||
|
@ -3,7 +3,7 @@ function init_db_schema() {
|
||||
try {
|
||||
global $pdo;
|
||||
|
||||
$db_version = "08012024_1442";
|
||||
$db_version = "08022024_1302";
|
||||
|
||||
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
|
||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
@ -256,6 +256,8 @@ function init_db_schema() {
|
||||
"gal" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||
"relay_all_recipients" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||
"relay_unknown_only" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||
"ssl_client_issuer" => "TEXT",
|
||||
"ssl_client_ca" => "TEXT",
|
||||
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
|
||||
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
|
||||
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
|
||||
|
@ -26,6 +26,26 @@ if ($iam_provider){
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_GET['mutual_tls_login'])) {
|
||||
$mutual_login_user = user_mutualtls_login();
|
||||
if ($mutual_login_user != false) {
|
||||
$_SESSION['mailcow_cc_username'] = $mutual_login_user;
|
||||
$_SESSION['mailcow_cc_role'] = "user";
|
||||
|
||||
$http_parameters = explode('&', $_SESSION['index_query_string']);
|
||||
unset($_SESSION['index_query_string']);
|
||||
if (in_array('mobileconfig', $http_parameters)) {
|
||||
if (in_array('only_email', $http_parameters)) {
|
||||
header("Location: /mobileconfig.php?only_email");
|
||||
die();
|
||||
}
|
||||
header("Location: /mobileconfig.php");
|
||||
die();
|
||||
}
|
||||
header("Location: /user");
|
||||
}
|
||||
}
|
||||
|
||||
// SSO Domain Admin
|
||||
if (!empty($_GET['sso_token'])) {
|
||||
$username = domain_admin_sso('check', $_GET['sso_token']);
|
||||
|
@ -29,7 +29,8 @@ $template_data = [
|
||||
'oauth2_request' => @$_SESSION['oauth2_request'],
|
||||
'is_mobileconfig' => str_contains($_SESSION['index_query_string'], 'mobileconfig'),
|
||||
'login_delay' => @$_SESSION['ldelay'],
|
||||
'has_iam_sso' => ($iam_provider) ? true : false
|
||||
'has_iam_sso' => ($iam_provider) ? true : false,
|
||||
'has_ssl_client_auth' => has_ssl_client_auth()
|
||||
];
|
||||
|
||||
$js_minifier->add('/web/js/site/index.js');
|
||||
|
@ -345,6 +345,8 @@
|
||||
"service_id": "Service ID",
|
||||
"source": "Source",
|
||||
"spamfilter": "Spam filter",
|
||||
"ssl_client_auth": "mTLS",
|
||||
"ssl_client_ca": "CA for mTLS Login",
|
||||
"subject": "Subject",
|
||||
"success": "Success",
|
||||
"sys_mails": "System mails",
|
||||
|
@ -91,12 +91,18 @@
|
||||
<input type="number" class="form-control" name="maxquota" value="{{ (result.max_quota_for_mbox / 1048576) }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-4">
|
||||
<div class="row mb-2">
|
||||
<label class="control-label col-sm-2" for="quota">{{ lang.edit.domain_quota }}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="number" class="form-control" name="quota" value="{{ (result.max_quota_for_domain / 1048576) }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-4">
|
||||
<label class="control-label col-sm-2" for="quota">{{ lang.admin.ssl_client_ca }}</label>
|
||||
<div class="col-sm-10">
|
||||
<textarea class="form-control" id="ssl_client_ca" name="ssl_client_ca" style="height: 200px;">{{ result.ssl_client_ca }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<label class="control-label col-sm-2">{{ lang.edit.backup_mx_options }}</label>
|
||||
<div class="col-sm-10">
|
||||
|
@ -49,6 +49,9 @@
|
||||
{% if has_iam_sso %}
|
||||
<li><a class="dropdown-item" href="/?iam_sso=1"><i class="bi bi-cloud-arrow-up-fill"></i> {{ lang.admin.iam_sso }}</a></li>
|
||||
{% endif %}
|
||||
{% if has_ssl_client_auth %}
|
||||
<li><a class="dropdown-item" href="/?mutual_tls_login=1"><i class="bi bi-cloud-arrow-up-fill"></i> {{ lang.admin.ssl_client_auth }}</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
{% if not oauth2_request %}
|
||||
|
@ -489,6 +489,13 @@
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="row mb-4">
|
||||
<label class="control-label col-sm-2 text-sm-end text-sm-end" for="ssl_client_ca">{{ lang.admin.ssl_client_ca }}</label>
|
||||
<div class="col-sm-10">
|
||||
<textarea class="form-control" id="ssl_client_ca" name="ssl_client_ca" style="height: 200px;"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="row mb-4">
|
||||
<label class="control-label col-sm-2 text-sm-end text-sm-end">{{ lang.add.backup_mx_options }}</label>
|
||||
<div class="col-sm-10">
|
||||
|
@ -380,6 +380,7 @@ services:
|
||||
. /etc/nginx/conf.d/templates/server_name.template.sh > /etc/nginx/conf.d/server_name.active &&
|
||||
. /etc/nginx/conf.d/templates/sites.template.sh > /etc/nginx/conf.d/sites.active &&
|
||||
. /etc/nginx/conf.d/templates/sogo_eas.template.sh > /etc/nginx/conf.d/sogo_eas.active &&
|
||||
. /etc/nginx/conf.d/templates/ssl_client_auth.template.sh &&
|
||||
nginx -qt &&
|
||||
until ping phpfpm -c1 > /dev/null; do sleep 1; done &&
|
||||
until ping sogo -c1 > /dev/null; do sleep 1; done &&
|
||||
@ -387,6 +388,9 @@ services:
|
||||
until ping rspamd -c1 > /dev/null; do sleep 1; done &&
|
||||
exec nginx -g 'daemon off;'"
|
||||
environment:
|
||||
- DBNAME=${DBNAME}
|
||||
- DBUSER=${DBUSER}
|
||||
- DBPASS=${DBPASS}
|
||||
- HTTPS_PORT=${HTTPS_PORT:-443}
|
||||
- HTTP_PORT=${HTTP_PORT:-80}
|
||||
- MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
|
||||
@ -406,6 +410,7 @@ services:
|
||||
- ./data/web/inc/functions.auth.inc.php:/mailcowauth/functions.auth.inc.php:z
|
||||
- ./data/web/inc/sessions.inc.php:/mailcowauth/sessions.inc.php:z
|
||||
- sogo-web-vol-1:/usr/lib/GNUstep/SOGo/
|
||||
- mysql-socket-vol-1:/var/run/mysqld/
|
||||
ports:
|
||||
- "${HTTPS_BIND:-}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}"
|
||||
- "${HTTP_BIND:-}:${HTTP_PORT:-80}:${HTTP_PORT:-80}"
|
||||
|
Loading…
Reference in New Issue
Block a user