Perdition Leaks Socket On Invalid Login
|This article applies to the following ZCS versions.|
Dedicated perdition server
In ZCS 4.5.10 or earlier releases, on a dedicated perdition server where there was no fallback server running locally (i.e. no mailbox service running) when an invalid user connected to perdition and the LDAP query failed, perdition tried to fall back to localhost (port pop3|pop3s|imap|imaps), and since the mailbox service wasn't running there, it failed, but leaked the socket that represented the failed connection to the service on the fallback host, which wasn't there. *This* problem has been fixed in ZCS 4.5.11 (see bug 21937for details).
Non-dedicated perdition server
In the case when there is the mailbox service running on the fallback localhost, upon an invalid login, the LDAP query fails, and perdition falls back to localhost. But it tries to use STARTTLS when talking with the fallback host, because zmperditionctl starts perdition with --ssl_mode tls_all.
Note: tls_all indicates that perdition should allow STARTTLS from the client, as well as it should talk STARTTLS with the proxy
When there is an invalid login and the fallback service is present, and perdition talks STARTTLS with the fallback host, then in this case, the SSL session is not terminated cleanly. The packet dump shows a TCP RST flowing from the backend mailbox service to perdition, and this causes the perdition end of the socket to go into the (equivalent of *) CLOSE_WAIT state, which will never be cleared unless perdition closes() it, or till the perdition thread dies.
*Equivalent of CLOSE_WAIT means that the leaked socket is the closest thing to a CLOSE_WAIT socket (since perdition bound the pre-connected socket to AF_UNSPEC, the leaked socket does not show up in a netstat session, so it is impossible to verify its true state).
To fix this, please modify /opt/zimbra/bin/zmperditionctl to run perdition with "tls_listen" instead of "tls_all" -- This will still enable clients to talk STARTTLS with perdition, but perdition itself will not use STARTTLS with the backend server -- flip side being, the chatter between perdition and backend is not secure from network snooping. Please make sure that traffic between perdition and the backend is behind a firewall.
All other cases work cleanly -- if the fallback server is present, and if perdition does not talk STARTTLS with it (either in valid or invalid login), there is no leaking socket. If the fallback server is present, and perdition talks STARTTLS with it, there is a clean shutdown on logout of a valid login.
Note: This wiki is not applicable to ZCS 5.0, as ZCS 5.0 uses nginx instead of perdition.