Linux close all connections

Рабочий метод разрыва конкретного активного соединения из командной строки linux (drop/kill/cut/close ESTABLISHED connection)

Иногда бывает необходимо принудительно разорвать активное соединение. Самый распространенный способ:

netstat -na
kill PID

Проблема в том, что один воркер может одновременно обслуживать несколько соединений, поэтому правильнее будет убить соединение а не воркер. Для этого на многих форумах рекомендуют использовать tcpkilll, cutter или awk+hping3. Однако, хоть эти утилиты и находятся в официальных репозиториях, мне не удалось заставить их разрывать соединения.

После продолжительных поисков был обнаружен perl скрипт killcx, разрывающий соединение по удаленному хосту и порту.

killcx 94.133.119.242:4403

[PARENT] checking connection with [94.133.119.242:4403]
[PARENT] found connection with [78.220.184.126:80] (ESTABLISHED)
[PARENT] forking child
[CHILD] interface not defined, will use [eth0]
[CHILD] setting up filter to sniff ACK on [eth0] for 5 seconds
[CHILD] hooked ACK from [77.220.184.126:80]
[CHILD] found AckNum [3091573605] and SeqNum [3105164779]
[CHILD] sending spoofed RST to [78.220.184.126:80] with SeqNum [3091573605]
[CHILD] sending RST to remote host as well with SeqNum [3105164779]
[CHILD] all done, sending USR1 signal to parent [13723] and exiting
[PARENT] received child signal, checking results.
=> success : connection has been closed !

Для его работы требуется целый набор библиотек.

apt-get install \
libpcap0.8 \
libpcap-dev \
libnet-pcap-perl \
libyaml-perl \
libyaml-dev \
libyaml-0-1 \
-y

cpan -i \
Net::RawIP \
NetPacket::Ethernet

Источник

TCP close() vs shutdown() in Linux OS

I know there are already a lot similar questions in stackoverflow, but nothing seems convincing. Basically trying to understand under what circumstances I need to use one over the other or use both. Also would like to understand if close() & shutdown() with shut_rdwr are the same.

3 Answers 3

Closing TCP connections has gathered so much confusion that we can rightfully say either this aspect of TCP has been poorly designed, or is lacking somewhere in documentation.

Short answer

To do it the proper way, you should use all 3: shutdown(SHUT_WR) , shutdown(SHUT_RD) and close() , in this order. No, shutdown(SHUT_RDWR) and close() are not the same. Read their documentation carefully and questions on SO and articles about it, you need to read more of them for an overview.

Longer answer

The first thing to clarify is what you aim for, when closing a connection. Presumably you use TCP for a higher lever protocol (request-response, steady stream of data etc.). Once you decide to «close» (terminate) connection, all you had to send/receive, you sent and received (otherwise you would not decide to terminate) — so what more do you want? I’m trying to outline what you may want at the time of termination:

  1. to know that all data sent in either direction reached the peer
  2. if there are any errors (in transmitting the data in process of being sent when you decided to terminate, as well as after that, and in doing the termination itself — which also requires data being sent/received), the application is informed
  3. optionally, some applications want to be non-blocking up to and including the termination

Unfortunately TCP doesn’t make these features easily available, and the user needs to understand what’s under the hood and how the system calls interact with what’s under the hood. A key sentence is in the recv manpage:

What the manpage means here is, orderly shutdown is done by one end (A) choosing to call shutdown(SHUT_WR) , which causes a FIN packet to be sent to the peer (B), and this packet takes the form of a 0 return code from recv inside B. (Note: the FIN packet, being an implementation aspect, is not mentioned by the manpage). The «EOF» as the manpage calls it, means there will be no more transmission from A to B, but application B can, and should continue to send what it was in the process of sending, and even send some more, potentially (A is still receiving). When that sending is done (shortly), B should itself call shutdown(SHUT_WR) to close the other half of the duplex. Now app A receives EOF and all transmission has ceased. The two apps are OK to call shutdown(SHUT_RD) to close their sockets for reading and then close() to free system resources associated with the socket (TODO I haven’t found clear documentation taht says the 2 calls to shutdown(SHUT_RD) are sending the ACKs in the termination sequence FIN —> ACK, FIN —> ACK, but this seems logical).

Читайте также:  Принтер canon l11121e драйвер для windows 10

Onwards to our aims, for (1) and (2) basically the application must somehow wait for the shutdown sequence to happen, and observe its outcome. Notice how if we follow the small protocol above, it is clear to both apps that the termination initiator (A) has sent everything to B. This is because B received EOF (and EOF is received only after everything else). A also received EOF, which is issued in reply to its own EOF, so A knows B received everything (there is a caveat here — the termination protocol must have a convention of who initiates the termination — so not both peers do so at once). However, the reverse is not true. After B calls shutdown(SHUT_WR) , there is nothing coming back app-level, to tell B that A received all data sent, plus the FIN (the A->B transmission had ceased!). Correct me if I’m wrong, but I believe at this stage B is in state «LAST_ACK» and when the final ACK arrives (step #4 of the 4-way handshake), concludes the close but the application is not informed unless it had set SO_LINGER with a long-enough timeout. SO_LINGER «ON» instructs the shutdown call to block (be performed in the forground) hence the shutdown call itself will do the waiting.

In conclusion what I recommend is to configure SO_LINGER ON with a long timeout, which causes it to block and hence return any errors. What is not entirely clear is whether it is shutdown(SHUT_WR) or shutdown(SHUT_RD) which blocks in expectation of the LAST_ACK, but that is of less importance as we need to call both.

Blocking on shutdown is problematic for requirement #3 above where e.g. you have a single-threaded design that serves all connections. Using SO_LINGER may block all connections on the termination of one of them. I see 3 routes to address the problem:

  1. shutdown with LINGER, from a different thread. This will of course complicate a design
  2. linger in background and either

2A. «Promote» FIN and FIN2 to app-level messages which you can read and hence wait for. This basically moves the problem that TCP was meant to solve, one level higher, which I consider hack-ish, also because the ensuing shutdown calls may still end in a limbo.

2B. Try to find a lower-level facility such as SIOCOUTQ ioctl described here that queries number of unACKed bytes in the network stack. The caveats are many, this is Linux specific and we are not sure if it aplies to FIN ACKs (to know whether closing is fully done), plus you’d need to poll taht periodically, which is complicated. Overall I’m leaning towards option 1.

I tried to write a comprehensive summary of the issue, corrections/additions welcome.

Источник

How does one close all _existing_ TCP connections on some ports using IPTables?

Say I have a quick network partition test that I’d like to run, like disconnecting two halves of a ReDiS cluster from each other, and I want to use IPTables to temporarily disconnect one group of servers from another group.

This is very similar to the question asked on the fedora mailing list:

If I don’t see an EXISTING,RELATED in the output from iptables —list , do I have to worry about this?

The following answer on the fedora mailing list seems to say that yes, existing connections will close if I don’t see an EXISTING,RELATED in the output from iptables —list .

A note for the reflexive flaggers, out there: This question, and, more importantly, its answers, would discuss whether IPTables drops existing connections upon updates to its rules.

Читайте также:  Minecraft windows 10 установка текстур

So far as I can tell, other questions on this site, on this subject, do not address the differences between existing and attempted connections:

I found most of my research results from the Google search at the page at the following URL link:

1 Answer 1

No iptables rule will ever close an existing TCP connection as that involves actively transmitting a message with the FIN bit. That is done by the application and not by a packet filter.

On the other hand iptables can, at any moment, block your application from receiving or transmitting new packets over any existing connection and it can also deny any new connections from getting established.

That is regardless of wether you have a stateful firewall or not.

It all depends on where exactly you insert your new firewall rules. Because, remember, your firewall rules are checked in the order they are listed and processing will stop at the first dispositive match.

I.e. a simple stateful firewall:

Now if you want a new rule:

and insert it at position #1 all packets received from that host will be blocked.

Insert that rule at position #2 and packets on existing connections will still be allowed but no new connections can be established.

Inserting that particular new rule at position #3 is useless, as the effect is the same as not having specific policy for 10.0.0.89 at all, but that would be the right place to place a rule to granting access to 10.0.0.89 to additional ports.

And using iptables -A INPUT to append a new rule to the INPUT chain is useless as that will place the rule at position #4 where all traffic is already rejected by the INPUT -j REJECT —reject-with icmp-host-prohibited rule.

In short: use the rule number option in iptables -I (instead of ipatbles -A ) to place the new (temporary) rule where it will have the desired effect:

If, with the same stateful firewall configuration, you want to stop allowing plain HTTP, you can Delete the rule allowing traffic to port 80

but doing so will not empty the session state table used by iptables and existing connections to port 80 will still be allowed by the rule -A INPUT -m state —state RELATED,ESTABLISHED -j ACCEPT

You can solve that by simply stopping/restarting the webserver, that will properly close those open sessions by sending FIN messages and clear them from the session state table.

Alternatively you can add a rule blocking packets to port 80 at position #1.

Источник

Killing tcp connection in linux

I have some dead connection in one application which is in hanged state if client machine is dead.

Is there a way to terminate these option from linux command line without restarting the server?

After search I found solution called as tcpkill. But it will not work for me. As it permanently blocks that ip.

10 Answers 10

On linux kernel >= 4.9 you can use the ss command from iproute2 with key -K

the kernel have to be compiled with CONFIG_INET_DIAG_DESTROY option enabled.

To «kill» a socket, you must send a TCP reset packet. To send it (and be accepted by the other side), you must know the actual TCP sequence number.

1) The already mentioned tcpkill method learns the SEQ number by passively sniffing on the network and waiting for valid packets of this connection to arrive. Then it uses the learned SEQ number to send RSET packets to both sides. However if the connection is idle/hanged and no data flows, it won’t do anything and will wait forever.

2) Another method uses perl script called killcx (link to Sourceforge). This actively sends spoofed SYN packets and learns the SEQ number from the answer. It then sends RSET packets the same way as tcpkill .

Alternatively approach (based on what you want to achieve) is to use gdb debugger to attach to a process owning this socket/connection and issue close() syscall on its behalf — as detailed in this answer.

Читайте также:  Как скрыть жесткий диск зарезервировано системой windows

If you want to deal only with hanged connections (the other side is dead), there are various timeouts (TCP keepalive for example), which should automatically close such connections if configured properly on the system.

Источник

How to forcibly close a socket in TIME_WAIT?

I run a particular program on linux which sometimes crashes. If you open it quickly after that, it listens on socket 49201 instead of 49200 as it did the first time. netstat reveals that 49200 is in a TIME_WAIT state.

Is there a program you can run to immediately force that socket move out of the TIME_WAIT state?

7 Answers 7

Actually there is a way to kill a connection — killcx. They claim it works in any state of the connection (which I have not verified). You need to know the interface where communication happens though, it seems to assume eth0 by default.

UPDATE: another solution is cutter which comes in some linux distros’ repositories.

Let me elaborate. Transmission Control Protocol (TCP) is designed to be a bidirectional, ordered, and reliable data transmission protocol between two end points (programs). In this context, the term reliable means that it will retransmit the packets if it gets lost in the middle. TCP guarantees the reliability by sending back Acknowledgment (ACK) packets back for a single or a range of packets received from the peer.

This goes same for the control signals such as termination request/response. RFC 793 defines the TIME-WAIT state to be as follows:

TIME-WAIT — represents waiting for enough time to pass to be sure the remote TCP received the acknowledgment of its connection termination request.

See the following TCP state diagram:

TCP is a bidirectional communication protocol, so when the connection is established, there is not a difference between the client and the server. Also, either one can call quits, and both peers needs to agree on closing to fully close an established TCP connection.

Let’s call the first one to call the quits as the active closer, and the other peer the passive closer. When the active closer sends FIN, the state goes to FIN-WAIT-1. Then it receives an ACK for the sent FIN and the state goes to FIN-WAIT-2. Once it receives FIN also from the passive closer, the active closer sends the ACK to the FIN and the state goes to TIME-WAIT. In case the passive closer did not received the ACK to the second FIN, it will retransmit the FIN packet.

RFC 793 sets the TIME-OUT to be twice the Maximum Segment Lifetime, or 2MSL. Since MSL, the maximum time a packet can wander around Internet, is set to 2 minutes, 2MSL is 4 minutes. Since there is no ACK to an ACK, the active closer can’t do anything but to wait 4 minutes if it adheres to the TCP/IP protocol correctly, just in case the passive sender has not received the ACK to its FIN (theoretically).

In reality, missing packets are probably rare, and very rare if it’s all happening within the LAN or within a single machine.

To answer the question verbatim, How to forcibly close a socket in TIME_WAIT?, I will still stick to my original answer:

Practically speaking, I would program it so it ignores TIME-WAIT state using SO_REUSEADDR option as WMR mentioned. What exactly does SO_REUSEADDR do?

This socket option tells the kernel that even if this port is busy (in
the TIME_WAIT state), go ahead and reuse it anyway. If it is busy, but with another state, you will still get an address already in use error. It is useful if your server has been shut down, and then restarted right away while sockets are still active on its port. You should be aware that if any unexpected data comes in, it may confuse your server, but while this is possible, it is not likely.

Источник

Оцените статью