6

Dear Serverfault community,

I have the following problem: I need to reset (disconnect) tcp connections on both network sides immediately if a certain string is encountered in the packet data. I don't have control over the applications on both sides and can only use linux iptables (or similar tools) to do the connection abort.

My first idea was to use the following iptables rule to achieve what I was looking for:

/usr/sbin/iptables -A INPUT -p tcp --dport 1234 -m string --algo bm --string 'BAD STRING' -j REJECT --reject-with tcp-reset

This works perfectly on the remote side by sending a TCP RST packet to the client which will therefore be disconnected immediately. Unfortunately the local side will not be notified upon the forced disconnect and the server process (connection) hangs forever.

I thought the requirement to immediately disconnect an already established connection on both sides on a certain condition (a string match in an IP packet in this case) isn't very unusual. So I did a Google search but to my surprise couldn't find anything usable in a reasonable amount of time.

Is there a way to achieve a tcp disconnect on both network sides using iptables? If not, what other tools could I use (bear in mind I don't have control over the client/server applications)?

Thank you very much in advance for your valuable answers!

Best regards,

Jens

Jens Moser
  • 83
  • 2
  • 6
  • Have you solved this problem? I've encountered it on my own and couldn't find viable solution as well – Nikrom Apr 14 '18 at 06:22
  • @Nikrom No, unfortunately I couldn't solve the problem. I thought about implementing my own netfilter module, but didn't have the time to implement. But I think Lourival Vieira Neto's answer is exactly what I was looking for. Give it a try. If it works, I will accept his answer! – Jens Moser Apr 16 '18 at 22:10

3 Answers3

1

You can configure your application to have a timeout.

Another solution is to configure TCP KeepAlive and have more frequent checks, like each 10 min.

Some applications implement a KeepAlive at the application level. E.g. SSH, apache.

When the keep alive is send, and connection is closed at remote end you will receive a RST, from remote end.

Statefull firewalls will forget the connection after a period of inactivity. This means that you can get discarded packets and half open connections when you do not have traffic for a while (30min or 1h).

I think is better to ask about your particular problem you are trying to solve, than about the particular solution you are trying to implement.

Mircea Vutcovici
  • 16,706
  • 4
  • 52
  • 80
1

You can use xt_RESET, e.g., -j RESET

0

Unfortunately the local side will not be notified upon the forced disconnect

It should be, a tcp-reset means the client should be told the connection is being closed. If your client is hanging when the reset is sent, this implies that it is not properly handling the reset being sent back from your host running IPTables. Unless you have a means to address that problem, I cannot think of any way you can achieve this.

GeoSword
  • 1,647
  • 12
  • 16
  • No, it's not the client which hangs, it's the server (the host on which the iptables rule is defined). The problem is, the above mentioned rule will send back a TCP RST packet to the client (which is immediately disconnected), but not to the server socket on the same host running iptables. How could that be done? I should add, the problem wouldn't exist if the server sent something back to the client after the client-side close, because then the client tcp/ip stack would send a TCP RST to the server. But in my case the server only waits for input and therefore doesn't notice the disconnect. – Jens Moser Sep 13 '13 at 20:16