Bug Description
Auth: OIDC enabled, external IdP (Authentik)
Reverse proxy: Caddy, sets X-Forwarded-For and X-Real-IP to the real client IP
App reached only via the proxy (ASPNETCORE_URLS=http://+:5000)
Summary
In the activity log, OIDC login events record the reverse proxy's internal IP (e.g. ::ffff:10.0.0.2), while logout events and failed-login events record the correct real client IP. So the client IP is captured inconsistently depending on the code path.
Evidence (activity log, IPs anonymized)
timestamp user type information
21:34 Login IP: ::ffff:10.0.0.2 <- reverse proxy IP
21:33 Logout IP: <- correct
21:33 Login IP: ::ffff:10.0.0.2 <- reverse proxy IP
21:24 Logout IP: <- correct
Failed local logins also log the correct real client IP.
Analysis
The application already uses UseForwardedHeaders and clearly trusts the proxy (KnownProxies/KnownNetworks), because logout and failed-login events resolve to the real client IP. If the proxy were not trusted, every event would show the proxy IP, which is not the case.
The login path is the outlier. This strongly suggests a middleware ordering issue: the OIDC callback / authentication middleware captures and logs the client IP before UseForwardedHeaders has rewritten HttpContext.Connection.RemoteIpAddress. Regular requests (logout) pass through the full pipeline first, so they see the corrected IP.
Expected behavior
OIDC login events should log the real client IP, consistent with logout and failed-login events.
Suggested fix
Ensure app.UseForwardedHeaders(...) runs before the authentication middleware (and before any OIDC sign-in event logging) in the pipeline, so the corrected RemoteIpAddress is available when the login event is recorded.
Note: cause inferred from behavior plus a symbol scan of MailArchiver.dll, not from source, so the exact call site may differ.
Steps to Reproduce
Run Mail-Archiver behind a reverse proxy that sets X-Forwarded-For / X-Real-IP to the real client IP (here: Caddy), with the app only reachable through the proxy.
Enable OIDC with an external IdP and log in via the OIDC button.
Open the activity log and look at the Login entry: the IP shown is the reverse proxy's internal IP (::ffff:10.0.0.2), not the client's.
Log out, then look at the Logout entry: the IP shown is the real client IP.
Compare both entries for the same session, the IPs are inconsistent.
Application Version
2607.2
Installation Type
Standalone
Management Tools
No response
Host System
No response
Mail Provider
No response
Relevant Log Output
Evidence (activity log, IPs anonymized)
timestamp user type information
21:34 <user> Login IP: ::ffff:10.0.0.2 <- reverse proxy IP
21:33 <user> Logout IP: <real client IP> <- correct
21:33 <user> Login IP: ::ffff:10.0.0.2 <- reverse proxy IP
21:24 <user> Logout IP: <real client IP> <- correct
Bug Description
Auth: OIDC enabled, external IdP (Authentik)
Reverse proxy: Caddy, sets X-Forwarded-For and X-Real-IP to the real client IP
App reached only via the proxy (ASPNETCORE_URLS=http://+:5000)
Summary
In the activity log, OIDC login events record the reverse proxy's internal IP (e.g. ::ffff:10.0.0.2), while logout events and failed-login events record the correct real client IP. So the client IP is captured inconsistently depending on the code path.
Evidence (activity log, IPs anonymized)
timestamp user type information
21:34 Login IP: ::ffff:10.0.0.2 <- reverse proxy IP
21:33 Logout IP: <- correct
21:33 Login IP: ::ffff:10.0.0.2 <- reverse proxy IP
21:24 Logout IP: <- correct
Failed local logins also log the correct real client IP.
Analysis
The application already uses UseForwardedHeaders and clearly trusts the proxy (KnownProxies/KnownNetworks), because logout and failed-login events resolve to the real client IP. If the proxy were not trusted, every event would show the proxy IP, which is not the case.
The login path is the outlier. This strongly suggests a middleware ordering issue: the OIDC callback / authentication middleware captures and logs the client IP before UseForwardedHeaders has rewritten HttpContext.Connection.RemoteIpAddress. Regular requests (logout) pass through the full pipeline first, so they see the corrected IP.
Expected behavior
OIDC login events should log the real client IP, consistent with logout and failed-login events.
Suggested fix
Ensure app.UseForwardedHeaders(...) runs before the authentication middleware (and before any OIDC sign-in event logging) in the pipeline, so the corrected RemoteIpAddress is available when the login event is recorded.
Note: cause inferred from behavior plus a symbol scan of MailArchiver.dll, not from source, so the exact call site may differ.
Steps to Reproduce
Run Mail-Archiver behind a reverse proxy that sets X-Forwarded-For / X-Real-IP to the real client IP (here: Caddy), with the app only reachable through the proxy.
Enable OIDC with an external IdP and log in via the OIDC button.
Open the activity log and look at the Login entry: the IP shown is the reverse proxy's internal IP (::ffff:10.0.0.2), not the client's.
Log out, then look at the Logout entry: the IP shown is the real client IP.
Compare both entries for the same session, the IPs are inconsistent.
Application Version
2607.2
Installation Type
Standalone
Management Tools
No response
Host System
No response
Mail Provider
No response
Relevant Log Output