How do I break an arbitrary TCP/IP connection on Linux? - linux

Is there any command that can be used to break an existing TCP/IP connection from some program?
Is there anything in a TCP connection the OS is aware of, or do the OS only see TCP transfer on local sockets and doensn't know which request is served to which socket?
For example, if Firefox sends a request to some server's port 80 and is waiting for the answer. Is it possible then to find Firefox listening port and trick Firefox into showing ERR_CONNECTION_REFUSED or something similar.
I would like a solution that does not prevent the data flow and lets the application handle this situation in its way, but rather close the socket or the TCP/IP connection (which should be possible as the socket is something the OS is responsible for I think? Is the connection also a OS property or just something the application does?) so the application would react immediately.

Use tcpkill.

Cutter
Cutter will send packets to both ends of a TCP/IP connection to close the connection. It is designed to be used on a Linux router to disconnect unwanted connections.
Website: http://www.digitage.co.uk/digitage/software/linux-security/cutter
Debian has a package of it: https://packages.debian.org/stable/cutter

My take on this is by using the `iproute2 framework.
Create a blockhole/unreachable bucket routing table (in my example table id 33) through a rule and give it high prio:
# ip rule add from all lookup 33 prio 1
Now find the connections you're trying to block. In my case I have used Chromium to connect to google.com:
# ss -n -e -p | grep "chrom" | grep "173.194.*:443"
ESTAB 0 0 10.211.55.4:46710 173.194.35.2:443 timer: (keepalive,38sec,0) users:(("chromium-browse",8488,106)) uid:1000 ino:38318 sk:f6a4f800
ESTAB 0 0 10.211.55.4:49288 173.194.35.18:443 timer:(keepalive,34sec,0) users:(("chromium-browse",8488,109)) uid:1000 ino:38047 sk:f6a4cb00
So, let's add 173.194.0.0/16 to table 33 and flush the cache:
# ip route add unreachable 173.194.0.0/16 table 33
# ip route flush cache
Try to connect to google.com now in your browser and you will get a ERR_CONNECTION_REFUSEDin your browser.
To lift the veil of your self-imposed blockage, you simple flush the bucket:
# ip route flush table 33
Of course, if you need a more granular distinction, you can use tc and u32 classifier to flag the exact IP:PORT combo (and other packet aspects) and add an fw rule to the bucket (untested):
# tc filter add dev eth1 parent ffff: protocol ip prio 1 u32 \
match ip src 173.194.0.0/16 match ip dport 443 classid :1
# ip rule add fwmark 1 table 33 prio 1 realms 3/4

Related

DOES router or linux kernel change the tcp headers and ip headers of packets

I was looking into raw sockets. so I created one raw socket client and other one is server. on two different computers. I am using ISP provided router. so I sent spoofed packet (with iphdr struct's saddr of different computer on same network) from client but when the packet received at the server the source ip in packet's ip header was correct (the real sender address=client address) plus the source port and destination port of tcphdr were something different too (which really didnt make sense). So I assumed that my ISP provided router is doing something funny -- OR I am completely wrong correct if this is a normal ip protocol. if I am correct then what steps should i take to configure my router so it does not mess up with tcp and ip headers of incoming packets plus the sync=1 at sender's end became sync=0 of tcphdr. I am using local IPs plus I am trying to implement tcp using raw socket server. I have configured iptables on server as well with sync allowed on my bounded port
iptables -I INPUT -p tcp --dport xxxx --syn -j ACCEPT
WHat settings do I need to do on server in iptables so my socket incoming packets wont be dropped nor any header be touched so I can get all packets required for tcp to keep coming in. plus what setting do I need to do on router so,if its cause problem then, it wont
Update 1:
after spending some time to the problem I found that one cause could be my kernel tcp stack dropping the incoming sync packets. so I looked around and found that in the tcp stack there is work done to make this happening. So I changed the sysctl.conf in /etc to allow sync packets to come in through by adding or uncommenting this line
net.ipv4.tcp_syncookies=1
Then I rebooted the system but still no difference. is it because somehow I have to reload my sysctl.conf file. if this is the case or any related case then please fill in.
Update 2
I have reloaded sysctl.conf after allowing syn packets and now I am getting syn packets from client application. but the destination port different. also along with syn=1, ack=1 is also coming in same packet. is this also something kernel is doing. please explain. as long as I know this is not how tcp works (tcp handshake) and I am connecting from client using stream socket

Trying to capture unidirectional tcp data on a server

I'm trying to test linux behavior for unidirectional tcp capture using tcpdump.
The scenario is that Server A is sending packets to destination Y through a switch M. At the same time, M will also be sending the same packets to destination Z, where I'd like to capture all packets. The connection A to Y is a tcp connection.
In order to synthesize the above scenario, I have 3 terminals open on server Z running the following commands:
nc -l 0.0.0.8 4444
telnet -b 0.0.0.10 0.0.0.8 4444
tcpdump -i <interface name associated with 0.0.0.8> port 4444
0.0.0.8 and 0.0.0.10 are separate NIC cards in separate slots, slot 1 and slot 6 in this case.
From the telnet session, i'm successful in sending data, however, tcpdump isn't capturing any packets. If I remove the port 4444 from the terminal 3, I'm seeing data from within my network, but never anything from the telnet session. I should also note that I'm not receiving an error message either.
I'm assuming, b/c I read it on the internet, that telnet creates a tcp connection, which is why I believe that tcpdump should work. Am I wrong here? Should I be doing something else? Can't use WireShark or the like on this server.
Also, on terminal 3 I've also tried tcpdump host 0.0.0.8 port 4444 to no avail. Many thanks for any suggestions.
If node M is truly a switch and not a hub, then node Z should never receive the TCP packets destined for node Y.
TCP is a connection based protocol. That is to say that when node A wants to talk to node Y, it will first broadcast an ARP request asking for node Y's MAC address (note that all nodes attached to the switch will see this packet). When node Y responds directly to node A with it's MAC address, then node A will initiate a TCP connection directly to node Y.
If node M is a switch, it will only forward packets destined for MAC address F directly to the port which it knows to be attached to the node having MAC address F. It will never forward that packet to all ports, but only to the destination node's port.
On the other hand, if node M is a hub, it will always forward all packets to all ports regardless of destination.

linux tcp connection established on client, invisible on server

on one of my linux hosts, one tcp socket seems to be visible on one side and invisble on the other side. I mean netstat displays this socket when I am on one of the hosts and not when I am on the other (linux too):
# netstat -anp|grep 37674
udp 0 0 169.254.192.2:37674 169.254.192.1:8649 ESTABLISHED 22644/xxxxx
# ssh 169.254.192.1
Last login: Mon Jan 13 15:22:54 CET 2014 from xxxxxx on ssh
# netstat -anp|grep 8649
#
If I undestand correctly, netstat reads connections from /proc/net/tcp. Apparently, local ip address and ports are given as 0123ABCD:1234 in /proc/net/tcp in second column.
37674(10) = 932A(16)
Thus, I tried to find 932A in /proc/net/tcp, ignoring case but found nothing.
IP address is not truncated as I have no other 169.254.192.1xx host on my network.
This connection is still visible after three hours, thus I don't think it's timeout related.
The output of netstat says UDP. (Look in /proc/net/udp)
This means means 169.254.192.2 has called connect() to 169.254.192.1:8649. UDP is however connectionless, so this info is just recorded locally on a socket on the 169.254.192.2 machine.
Calling connect() on an UDP socket just enables you to call send() on that socket without specifying the destination address for each packet with sendto()/sendmsg() - no actual connection created between the two machines.
If the 169.254.192.1 machine isn't listening/receiving packets on port 8649, it isn't meaningful for the 169.254.192.1 machine to set up a socket that can send packets there though.

tcpdump returns 0 packets captured, received and dropped

I am currently trying to debug a networking problem that has been plaguing me for almost three weeks. I'm working with openstack and can create virtual machines and networks fine but cannot connect to them at all. When I run this command from the server, i have to ctrl+c to stop the time-out and it returns:
[root#xxxxxx ~(keystone_admin)]# tcpdump -i any -n -v 'icmp[icmptype] = icmp-echoreply or icmp[icmptype] = icmp-echo'
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel
I'm not sure if this is exclusively and OpenStack problem or just a networking problem in general, but i know that 'tcpdump' is supposed to return something other than 0 packets captured, received or dumped. I am new to networking and therefore do not have much experience so please be gentle. Any help is appreciated. Thanks.
tcpdump is the right tool to dump ip packets. But if your openstack security group rules blocks ICMP, 0 ICMP packets are expected.
I just want to understand what do you mean by "cannot connect to the virtual machines at all". ping command doesn't work? or other protocol like ssh or HTTP.
Generally the first common problem when connecting to OpenStack VM is the security group rules. the default one disallow ICMP protocol. You can run the following command to see the rules:
nova secgroup-list: it usually returns a default one
nova secgroup-rules-list default: it will show the defined rules. where there must be at least one rule to allow ICMP protocol.
Here's the official doc to tell how to add rules allowing ICMP and SSH.

How can i externally connect to a service running on 127.0.0.1 (rather than 0.0.0.0)?

I'm trying to connect to a service, and to debug it, I ran
netstat -nap | grep LISTEN
The results should rows of two types :
tcp 0 0 127.0.0.1:8020 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:57140 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:11000 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:8088 0.0.0.0:* LISTEN
unix 2 [ ACC ] STREAM LISTENING 4512 -
unix 2 [ ACC ] STREAM LISTENING 9760 -
I have 3 questions :
1) I want to connect to the process running on 127.0.0.1 --- how can I do this externally ? I have read elsewhere that 127.0.0.1 processes are only allowed to communicate with other localhost processes.
2) What is the difference between the "tcp 0" netstat records and the "unix 2" ones ? Im somewhat naive about networking, so feel free to overexplain this one :)
In short, your process is bound to a loopback interface which cannot receive packets from an external network. You'll need to reconfigure the process bound to port 8020 to bind to an external interface to be able to connect to it from another host.
The long answer is that the two addresses you site (127.0.0.1 and 0.0.0.0) are both special in certain ways, and it is useful to understand what you're seeing.
Addresses in the 127.0.0.0/8 Internet Protocol address block (of which 127.0.0.1 is one) are reserved for use internally on a host. See rfc5735 for details, but there's nothing special about these addresses except that all IP hosts use the same rules and aren't setup to route these addresses outside a host or router.
On your computer, you'll usually see a special "loopback" network interface that has 127.0.0.1 assigned.
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
This interface is special and never connected to an external network. It is used when a program wants to connect to a service on the local machine as 127.0.0.1 will almost always be configured as an active network interface. Packets will only arrive on this interface if they are sent from a local process.
The other address you site, 0.0.0.0 is special and usually represents all IP addresses mapped to any network interface on your computer. When a program wants to listen for connections arriving on any network interface or IP address, it will bind a TCP/UDP port to 0.0.0.0 to listen for connections.
In your case, however, you're reporting netstat output listing 0.0.0.0 on lines describing TCP sockets in a LISTEN state. In this case, netstat is listing sockets listening for connections and using 0.0.0.0:* as a place holder for the foreign address field of it's output. In this case, 0.0.0.0:* signifies that the socket is waiting for a connection from any host.
Regarding your question on "tcp 0" vs. "unix 2", these are the first two columns of your netstat output. A look at the column headers from your netstat command is useful:
# netstat -nap | head -2
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
What you're reporting as "tcp 0" simply means a socket using the TCP protocol has zero bytes in the received queue waiting for the program connected to this socket to consume. Similarly, "unix 2" is what's called a unix socket with two bytes waiting in its receive queue for the connected process to consume.
TCP sockets are part of the TCP/IP stack that can be used locally or across IP networks for processes to communicate. UNIX sockets, on the other hand, are simpler and only used for what's called IPC or inter-process communication which only happens between two processes both running on the local system, and there's no networking involved (no addresses and ports anyway). UNIX sockets are considered to be more efficient than TCP sockets, but they are obviously more limited in function. On UNIX-like systems UNIX sockets are implemented as a file on the file system of a special "socket" type that both processes using the socket read and write to as a communication channel.
1) Without binding it to 0.0.0.0, you can still access the service through a tunnel. This is similar to using a proxy as David Schwartz mentioned. There's a few assumptions I'm making for this example:
The server is running a service bound to 127.0.0.1:8020, we'll call it 'myservice'.
The server is running OpenSSH server 'sshd' on the default port of TCP 22, and the user can log in with the username 'myusername'.
The client is running a system with OpenSSH client installed.
The server is accessible via the IP address of 10.20.30.40.
On the client, SSH to the server with the following command:
ssh -L 12345:localhost:8020 myusername#10.20.30.40
Once you log in, minimize the SSH window. In another window on the client, run netstat to find listening ports. You should see 127.0.0.1:12345, just like on the server.
On the client, connect to the service on 127.0.0.1:12345. You should now be connected to the 'myservice' instance on the server, even though you made the connection to the client's local loopback interface.
The trick here is that SSH is tunneling a listening socket on the client to the listening socket on the server. I've made the port numbers different for clarity.
1) You would either need to modify the server to bind to a publicly accessible address (or 0.0.0.0) or run a local proxy to handle the connection.
2) TCP connections use the TCP protocol, the one used for connection-oriented traffic on the Internet. UNIX connections use a strictly local protocol that is much simpler than TCP (because it doesn't have to deal with dropped packets, lost routes, corrupted data, out of order packets, and so on).
1) You cannot (if you mean from another machine - 127.0.0.1 is localhost and by definition you can only connect to it from the local machine
2) The first column shows the domain of the sockets - tcp are tcp sockets and unix are unix domain sockets.
And as for the answer to you question 3 ;-)
3) 42

Resources