Linux TCP accept without SYN|ACK - linux

I'm trying to write a TCP transparent proxy to run on Linux.
I want to, upon receipt of an incoming connection, initiate a corresponding outgoing connection, but only accept (SYN|ACK) the incoming connection if the outgoing connection is successful.
TCP_DEFERRED_ACCEPT doesn't do what I want -- it always sends a SYN|ACK.
The question is: how do I accept TCP connections, but defer the SYN|ACK, with the Linux sockets API?

You can do that with Linux, but not via the socket API. You would use the NFQUEUE target which allows you to redirect some packets to userspace and decide their fate from within your program.
Obiously, you'd still have to parse the packet in userspace, but searching for a few TCP flags should not be that hard and not require a complete TCP stack. And this way Linux still does the whole network job.
In your case, it would seem possible that you both use NFQUEUE and classical sockets API. The first will give you early decisions, the latter TCP stream data access. Although I never tried it.
See https://home.regit.org/netfilter-en/using-nfqueue-and-libnetfilter_queue/ for instance.

Related

What does the ESTABLISHED indicator mean after running lsof

I ran the command sudo lsof -i -n -P | grep TCP and I was wondering if I could get some more clarification on its output.
Specifically, in this image:
Why do I have an IP:PORT pointing to another IP:PORT and then back at itself with the label 'ESTABLISHED'? I am confused on what this means exactly.
I'm not sure how familiar you are with networking and TCP in general, so I'll try to provide a brief description with a couple of details. From your question, it appears that you're not very familiar with networking internals, so it may be hard to understand some of these concepts, but I hope this helps:
The TCP protocol has various states. Think of it as a state machine. States on the client side include CLOSED, SYN_SENT, ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2 and TIME_WAIT.
Thus, the ESTABLISHED label means that the TCP connection is in the ESTABLISHED state. Being in the established state means that both hosts successfully completed the TCP 3-way handshake (and in doing so, transitioned from SYN_SENT to ESTABLISHED). The transition from CLOSED to SYN_SENT happens when the client side sends the TCP SYN request to the server.
In an established connection, both sides transmit and receive application specific data. Basically, a session is established and a bidirectional stream of bytes flows between the two end systems.
TCP sockets are uniquely identified by the 4-tuple (source-ip, source-port, destination-ip, destination-port). The IP identifies an end system's network interface, and the port number is used to multiplex and demultiplex packet arrival at that network interface (so that the target system knows which service to deliver the packets to). That's the meaning of the IP:PORT fields.
I'm not sure why you have two entries for the same connection. This might be system-dependent, although it's odd (in my system I get only one entry per socket). But sockets are bidirectional, so it may be the case that your system shows you each packet flow direction as a distinct entry. This might also depend on how the system implements sockets.
ESTABLISHED means that the TCP connection has completed the 3-way handshake. (Not sure though whether accept must have been called). See TCP state diagram.
Why do I have an IP:PORT pointing to another IP:PORT and then back at itself
That mean you have two TCP sockets open in your process. Most likely, one listens on port 9092, and another one that connected from port 57633 to that listening socket. Port 57633 belongs to the ephemeral port range, i.e. the range of ports that the OS automatically assigns to the sockets that call connect but did not call bind to assign a specific port.

How do I prevent Linux kernel from responding to incoming TCP packets?

For my application, I need to intercept certain TCP/IP packets and route them to a different device over a custom communications link (not Ethernet). I need all the TCP control packets and the full headers. I have figured out how to obtain these using a raw socket via socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)); This works well and allows me to attach filters to just see the TCP port I'm interested in.
However, Linux also sees these packets. By default, it sends a RST when it receives a packet to a TCP port number it doesn't know about. That's no good as I plan to send back a response myself later. If I open up a second "normal" socket on that same port using socket(PF_INET, SOCK_STREAM, 0); and listen() on it, Linux then sends ACK to incoming TCP packets. Neither of these options is what I want. I want it to do nothing with these packets so I can handle everything myself. How can I accomplish this?
I would like to do the same thing. My reason is from a security perspective… I am wanting to construct a Tarpit application. I intent to forward TCP traffic from certain source IPs to the Tarpit. The Tarpit must receive the ACK. It will reply with a SYN/ACK of its own. I do not want the kernel to respond. Hence, a raw socket will not work (because the supplied TCP packets are teed), I need to also implement a Divert socket. That's about all I know so far… have not yet implemented.

Can I get TCP window size for current connection before I send data with Linux API send or sendto

Is there Linux API available that I can retrieve TCP window size for current TCP connection before I send data with Linux API send or sendto?
The reason I need this is if current TCP window size is less than the length of data I need to send, I can release CPU manually and do something else in other threads or processes.
Maybe there's a better method but, actuallly, only the use of a RAW SOCKET comes in my mind.
Handling data at transport layer allows you to access to TCP header (and then the window 16 bit field).
The counterpart is that you have to handle TCP stack between you and the peer, that is a bit crazy and laborious.
This is an example about what you need to do in order to JUST send a SYN to a host. Avoid the final loop, otherwise it starts a syn-flood attack against your peer :)
TCP with RAW SOCKETS

TCP Traffic Generator

I am searching for a TCP traffic generator. The problem is that I do not simply want to send TCP traffic as it can be done with e.g. Iperf. I want to be able to configure the flags and other header fields and I want to react on incoming packets e.g. a TCP SYN.
So for example I want to send a TCP FIN packet if a TCP SYN arrives.
I prefer Linux tools but it would be also ok if the tool only runs under other OS.
I have looked into hping3, it looks promising. But I would like to look into other tools before choosing it.
SendIP can generate TCP packets, with options to manipulate SYN/FIN bits as well as other fields.
This sort of question really belongs on Server Fault.

When using a raw socket for TCP traffic, keep kernel from receiving incoming packets

I am running some security tests which require the use of a non-standard TCP socket, to generate a behaviour that a normal TCP stack would not follow. I use a raw socket to generate such traffic.
When the reply from the other end point is received, the TCP connection is unknown to the kernel and issues a RESET. To prevent this from happening, the normal solution is to define an iptables rule that drops all outgoing RESET (e.g. iptables -A OUTPUT -p tcp -dport 50000 --tcp-flags RST RST -j DROP).
However, in my particular case, RESET is also a valid segment to generate during the testing. What I need is a way to filter out all segments from that connection so the kernel TCP stack is not involved and yet have access to all the segments in my raw socket.
Any ideas how can I achieve this? Is this possible with iptables?
Thanks in advance
Luis
Trying to use the host's IP address and fighting Linux's TCP/IP stack is calling for trouble.
Instead, I would use a separate IP address, route that to a tun device and get the raw IP packets from the tun device instead of using a raw socket (some sample code to interface a tun device is available from http://www.secdev.org/projects/tuntap_udp/). That way the Linux TCP/IP stack won't get in your way (except for routing puposes).

Resources