[Nginx][Web] Client address and autodiscover adjustments

This commit is contained in:
FreddleSpl0it committed 2026-10-28 16:36:16 +01:00
1 parent 1b6fec6a89
commit 085d10118d
3 files changed
+53 -46

No files matched your search

+7
View File
@@ -47,6 +47,13 @@ http {
default ""; default "";
} }
# Client address for PHP: on the internal sogo-auth listener nginx itself is the client,
# the real address comes from the X-Real-IP header set by /sogo-auth-verify
map $sogo_auth_internal $mailcow_client_ip {
"1" $http_x_real_ip;
default $remote_addr;
}
{% if HTTP_REDIRECT %} {% if HTTP_REDIRECT %}
# HTTP to HTTPS redirect # HTTP to HTTPS redirect
server { server {
@@ -116,7 +116,8 @@ location ~ \.php$ {
include /etc/nginx/fastcgi_params; include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param HTTP_X_REAL_IP $remote_addr; fastcgi_param REMOTE_ADDR $mailcow_client_ip;
fastcgi_param HTTP_X_REAL_IP $mailcow_client_ip;
# trusted internal-auth marker; empty for external clients (see nginx.conf map) # trusted internal-auth marker; empty for external clients (see nginx.conf map)
fastcgi_param SOGO_AUTH_INTERNAL $sogo_auth_internal; fastcgi_param SOGO_AUTH_INTERNAL $sogo_auth_internal;
fastcgi_read_timeout 3600; fastcgi_read_timeout 3600;
+44 -45
View File
@@ -144,6 +144,38 @@ try {
} }
$username = trim((string)$email); $username = trim((string)$email);
if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
try {
$json = json_encode(
array(
"time" => time(),
"ua" => $_SERVER['HTTP_USER_AGENT'],
"user" => "none",
"ip" => $_SERVER['REMOTE_ADDR'],
"service" => "Error: invalid email address in request"
)
);
$redis->lPush('AUTODISCOVER_LOG', $json);
$redis->lTrim('AUTODISCOVER_LOG', 0, 100);
$redis->publish("F2B_CHANNEL", "Autodiscover: Invalid mailbox attempt by " . $_SERVER['REMOTE_ADDR']);
error_log("Autodiscover: Invalid mailbox attempt by " . $_SERVER['REMOTE_ADDR']);
}
catch (RedisException $e) {
// Silently fail
}
list($usec, $sec) = explode(' ', microtime());
?>
<Response>
<Error Time="<?=date('H:i:s', $sec) . substr($usec, 0, strlen($usec) - 2);?>" Id="<?=rand(1000000000, 9999999999);?>">
<ErrorCode>600</ErrorCode>
<Message>Invalid Request</Message>
<DebugData />
</Error>
</Response>
</Autodiscover>
<?php
exit(0);
}
try { try {
$stmt = $pdo->prepare("SELECT `mailbox`.`name`, `mailbox`.`active` FROM `mailbox` $stmt = $pdo->prepare("SELECT `mailbox`.`name`, `mailbox`.`active` FROM `mailbox`
INNER JOIN `domain` ON `mailbox`.`domain` = `domain`.`domain` INNER JOIN `domain` ON `mailbox`.`domain` = `domain`.`domain`
@@ -169,8 +201,8 @@ catch(PDOException $e) {
exit(0); exit(0);
} }
// Mailbox not found or not active - return generic error to prevent user enumeration $email = $username;
if (empty($MailboxData)) { $displayname = $email;
try { try {
$json = json_encode( $json = json_encode(
array( array(
@@ -178,49 +210,16 @@ if (empty($MailboxData)) {
"ua" => $_SERVER['HTTP_USER_AGENT'], "ua" => $_SERVER['HTTP_USER_AGENT'],
"user" => $email, "user" => $email,
"ip" => $_SERVER['REMOTE_ADDR'], "ip" => $_SERVER['REMOTE_ADDR'],
"service" => "Error: mailbox not found or inactive" // The answer is the same, only the log tells unknown or inactive mailboxes apart
"service" => (empty($MailboxData)) ? "Error: mailbox not found or inactive" : $autodiscover_config['autodiscoverType']
) )
); );
$redis->lPush('AUTODISCOVER_LOG', $json); $redis->lPush('AUTODISCOVER_LOG', $json);
$redis->lTrim('AUTODISCOVER_LOG', 0, 100); $redis->lTrim('AUTODISCOVER_LOG', 0, 100);
if (empty($MailboxData)) {
$redis->publish("F2B_CHANNEL", "Autodiscover: Invalid mailbox attempt by " . $_SERVER['REMOTE_ADDR']); $redis->publish("F2B_CHANNEL", "Autodiscover: Invalid mailbox attempt by " . $_SERVER['REMOTE_ADDR']);
error_log("Autodiscover: Invalid mailbox attempt by " . $_SERVER['REMOTE_ADDR']); error_log("Autodiscover: Invalid mailbox attempt by " . $_SERVER['REMOTE_ADDR']);
} }
catch (RedisException $e) {
// Silently fail
}
list($usec, $sec) = explode(' ', microtime());
?>
<Response>
<Error Time="<?=date('H:i:s', $sec) . substr($usec, 0, strlen($usec) - 2);?>" Id="<?=rand(1000000000, 9999999999);?>">
<ErrorCode>600</ErrorCode>
<Message>Invalid Request</Message>
<DebugData />
</Error>
</Response>
</Autodiscover>
<?php
exit(0);
}
if (!empty($MailboxData['name'])) {
$displayname = $MailboxData['name'];
}
else {
$displayname = $email;
}
try {
$json = json_encode(
array(
"time" => time(),
"ua" => $_SERVER['HTTP_USER_AGENT'],
"user" => $email,
"ip" => $_SERVER['REMOTE_ADDR'],
"service" => $autodiscover_config['autodiscoverType']
)
);
$redis->lPush('AUTODISCOVER_LOG', $json);
$redis->lTrim('AUTODISCOVER_LOG', 0, 100);
} }
catch (RedisException $e) { catch (RedisException $e) {
$_SESSION['return'][] = array( $_SESSION['return'][] = array(
@@ -243,7 +242,7 @@ if ($autodiscover_config['autodiscoverType'] == 'imap') {
<Server><?=$autodiscover_config['imap']['server'];?></Server> <Server><?=$autodiscover_config['imap']['server'];?></Server>
<Port><?=$autodiscover_config['imap']['port'];?></Port> <Port><?=$autodiscover_config['imap']['port'];?></Port>
<DomainRequired>off</DomainRequired> <DomainRequired>off</DomainRequired>
<LoginName><?=$email;?></LoginName> <LoginName><?=htmlspecialchars($email, ENT_XML1 | ENT_QUOTES, 'UTF-8');?></LoginName>
<SPA>off</SPA> <SPA>off</SPA>
<SSL>on</SSL> <SSL>on</SSL>
<AuthRequired>on</AuthRequired> <AuthRequired>on</AuthRequired>
@@ -253,7 +252,7 @@ if ($autodiscover_config['autodiscoverType'] == 'imap') {
<Server><?=$autodiscover_config['smtp']['server'];?></Server> <Server><?=$autodiscover_config['smtp']['server'];?></Server>
<Port><?=$autodiscover_config['smtp']['port'];?></Port> <Port><?=$autodiscover_config['smtp']['port'];?></Port>
<DomainRequired>off</DomainRequired> <DomainRequired>off</DomainRequired>
<LoginName><?=$email;?></LoginName> <LoginName><?=htmlspecialchars($email, ENT_XML1 | ENT_QUOTES, 'UTF-8');?></LoginName>
<SPA>off</SPA> <SPA>off</SPA>
<SSL>on</SSL> <SSL>on</SSL>
<AuthRequired>on</AuthRequired> <AuthRequired>on</AuthRequired>
@@ -265,15 +264,15 @@ if ($autodiscover_config['autodiscoverType'] == 'imap') {
?> ?>
<Protocol> <Protocol>
<Type>CalDAV</Type> <Type>CalDAV</Type>
<Server>https://<?=$autodiscover_config['caldav']['server'];?><?php if ($autodiscover_config['caldav']['port'] != 443) echo ':'.$autodiscover_config['caldav']['port']; ?>/SOGo/dav/<?=$email;?>/</Server> <Server>https://<?=$autodiscover_config['caldav']['server'];?><?php if ($autodiscover_config['caldav']['port'] != 443) echo ':'.$autodiscover_config['caldav']['port']; ?>/SOGo/dav/<?=htmlspecialchars($email, ENT_XML1 | ENT_QUOTES, 'UTF-8');?>/</Server>
<DomainRequired>off</DomainRequired> <DomainRequired>off</DomainRequired>
<LoginName><?=$email;?></LoginName> <LoginName><?=htmlspecialchars($email, ENT_XML1 | ENT_QUOTES, 'UTF-8');?></LoginName>
</Protocol> </Protocol>
<Protocol> <Protocol>
<Type>CardDAV</Type> <Type>CardDAV</Type>
<Server>https://<?=$autodiscover_config['carddav']['server'];?><?php if ($autodiscover_config['caldav']['port'] != 443) echo ':'.$autodiscover_config['carddav']['port']; ?>/SOGo/dav/<?=$email;?>/</Server> <Server>https://<?=$autodiscover_config['carddav']['server'];?><?php if ($autodiscover_config['caldav']['port'] != 443) echo ':'.$autodiscover_config['carddav']['port']; ?>/SOGo/dav/<?=htmlspecialchars($email, ENT_XML1 | ENT_QUOTES, 'UTF-8');?>/</Server>
<DomainRequired>off</DomainRequired> <DomainRequired>off</DomainRequired>
<LoginName><?=$email;?></LoginName> <LoginName><?=htmlspecialchars($email, ENT_XML1 | ENT_QUOTES, 'UTF-8');?></LoginName>
</Protocol> </Protocol>
<?php <?php
} }
@@ -288,7 +287,7 @@ if ($autodiscover_config['autodiscoverType'] == 'imap') {
<Culture>en:en</Culture> <Culture>en:en</Culture>
<User> <User>
<DisplayName><?=htmlspecialchars($displayname, ENT_XML1 | ENT_QUOTES, 'UTF-8');?></DisplayName> <DisplayName><?=htmlspecialchars($displayname, ENT_XML1 | ENT_QUOTES, 'UTF-8');?></DisplayName>
<EMailAddress><?=$email;?></EMailAddress> <EMailAddress><?=htmlspecialchars($email, ENT_XML1 | ENT_QUOTES, 'UTF-8');?></EMailAddress>
</User> </User>
<Action> <Action>
<Settings> <Settings>