Cameron Simpson
2021-06-01 00:25:38 UTC
Can I enforce or implement TCP keep alives on a TCP stream via my
firewall?
Background:
I've got a client with an OpenBSD firewall and a Telstra NBN modem as
their modem.
Their IMAP server is upstream in the cloud (Unbuntu, courier imap). I
have this odd problem which I am beginning to suspect is the NBN modem
getting bored and dropping its NAT entries. Let me explain...
At the firewall end I see about 30 ESTABLISHED connections to the IMAP
server. At the IMAP server I see over 500, which is about where the IMAP
service stops accepting new connections, leading to errors from the
client mail readers.
My current theory is that the IMAP client connections issue the IMAP
IDLE command and go passive, waiting for email notifications from the
server. So we have an idle TCP connection across the firewall and
across the NBN modem (which NATs).
My conjecture is that at some point the modem discards idle connection
states. (This could just as well happen at any other intermediate
stateful router too.) After that event, the client end does something
which tries to use the connection, gets an RST from the modem, clean
tidyup happens on the client and in the firewall.
At the server end, none of this is seen and the imapd just sits around
idle, never releasing the connection and never stopping the matching
daemon process. This gradually rises to hit the server's configured
connection limit and it stops accepting new things.
If I had TCP keep alive turned on, both ends might tidy themselves up.
I can't enable that on the clients (various mail readers) or,
apparently, on the server configuration. I can't do it in PF because PF
just copies packets. I can't seem to do it in relayd either, though that
seems the obvious way to intercept the connection for this purpose.
Any suggestions?
I haven't fully validated my conjecture yet, BTW. It just fits the
symptoms I see.
Plan B is to build the latest courier-imap from source if I find the
time, but there may be no build option for this. I guess a single
setsockopt() call in the source would be enough, _if_ that can be done
on the accept end, which I haven't checked.
Plan B0 might be to disable IMAP IDLE support. Hmm.
Cheers,
Cameron Simpson <***@cskk.id.au>
firewall?
Background:
I've got a client with an OpenBSD firewall and a Telstra NBN modem as
their modem.
Their IMAP server is upstream in the cloud (Unbuntu, courier imap). I
have this odd problem which I am beginning to suspect is the NBN modem
getting bored and dropping its NAT entries. Let me explain...
At the firewall end I see about 30 ESTABLISHED connections to the IMAP
server. At the IMAP server I see over 500, which is about where the IMAP
service stops accepting new connections, leading to errors from the
client mail readers.
My current theory is that the IMAP client connections issue the IMAP
IDLE command and go passive, waiting for email notifications from the
server. So we have an idle TCP connection across the firewall and
across the NBN modem (which NATs).
My conjecture is that at some point the modem discards idle connection
states. (This could just as well happen at any other intermediate
stateful router too.) After that event, the client end does something
which tries to use the connection, gets an RST from the modem, clean
tidyup happens on the client and in the firewall.
At the server end, none of this is seen and the imapd just sits around
idle, never releasing the connection and never stopping the matching
daemon process. This gradually rises to hit the server's configured
connection limit and it stops accepting new things.
If I had TCP keep alive turned on, both ends might tidy themselves up.
I can't enable that on the clients (various mail readers) or,
apparently, on the server configuration. I can't do it in PF because PF
just copies packets. I can't seem to do it in relayd either, though that
seems the obvious way to intercept the connection for this purpose.
Any suggestions?
I haven't fully validated my conjecture yet, BTW. It just fits the
symptoms I see.
Plan B is to build the latest courier-imap from source if I find the
time, but there may be no build option for this. I guess a single
setsockopt() call in the source would be enough, _if_ that can be done
on the accept end, which I haven't checked.
Plan B0 might be to disable IMAP IDLE support. Hmm.
Cheers,
Cameron Simpson <***@cskk.id.au>