howto make locally terminated tcp connections go through prerouting and postrouting? - linux

I am developing an application that filters and mangles packets using netfilter queue's. It's rather complicated and needs to perform well so I would like to automate some rigorous testing. To do this I need to be to be able to route some TCP connections through my system, however, I don't want to have to rely on two other machines to act as client and server. I would prefer to run a local client that sends data and a local server that checks the mangled result.
The problem is that my application needs to intercept packets at the PREROUTING stage and so packets generated by the local client can't just be routed to the loopback interface.
So I need some way to inject packets before the prerouting stage and intercept them back after postrouting. If I could somehow use stream sockets to send and receive the data that would be great!

The most straightforward way I can think of doing this is to use a tun device. The tun device allows you to inject packets from userspace that appear to arrive through the tun interface. You could either write code to create and manipulate the tun interface yourself, or you can make use of an application like OpenVPN that already does this. With OpenVPN it would be easy: no special raw sockets or anything: you just send it IP packets encapsulated in UDP and it will make them arrive through a tun interface.

I've been thinking a bit about this and using the tun devices my client and server test applications should be able to use plain linux sockets. I will explain how this can work by describing the path of a packet sent by the test client.
Prerequisites:
a) Two tun devices each providing access to a distinct subnetwork
b) routing table was set up to route traffic to the correct tun device
1) the client sends a packet to an address in the tun1 subnetwork
2) the app attached to tun1 (tun1app) will translate the dst address of the packet to an address in tun2 subnetwork and the source address to an address in the tun1 subnetwork different from the address of the tun1 interface
3) tun1app will send the modified packet back out
4) after routing tun2app will receive the packet and translate the destination address to the tun2 interface and the source address to an address in the tun2 network different from the interface address
5) tun2app will send it back out and the server will receive the packet assuming the destination port is the one the server is listening on
Packets from the server will follow the inverse path.
This seems like the core idea of a very useful tool. Does anyone know of a tool that is able to do this?

All connections from-and-to localhost itself do go over PREROUTING and POSTROUTING. Whoever tells something else is mistaken. (You can verify that with ip6tables -t raw -I OUTPUT -j TRACE, and you will see that it passes through OUTPUT-POSTROUTING-PREROUTING-INPUT when, for example, you ping6 ::1 yourself.)

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

I am working with vlan, I have to write a server which used vlan interface to accept the packet?

Hints about working with VLAN? I have to write a client-server program, where the client will send a packet through eth0 and the server will receive the packet on VLAN, and to send it to a concerned VLAN client should parse on which command line VLAN will receive it?
Usually there is nothing to do in the application to work with a VLAN. The VLAN is realized using a virtual network interface with its own IP address. From the perspective of the application this is not different from a real network interface with own IP address. The OS will take care about routing and encapsulation of packets and there is nothing to do from the application itself.

Respond to a Packet Received in The NetFilter at Kernel

I'm working on Linux 4.13.x. And I'm considering to send a packet response in the kernel.
Consider an echo TCP or UDP server running in the userland and there is also another node running a TCP or UDP client. Clients are sending requests to the server. I want to send the packet response back to the client without any involvement of server application running at userspace.
Here is my thoughts about this problem:
I started thinking how it is possible and I come across to a solution like netfilter. If I can capture the packets in NF_INET_PRE_ROUTING and then try to swap the source and destination IP addresses of IP header and also swapping the ports in the TCP header, then according to this answers and this presumably modified packet should be forwarded to the originator throughout the routing system.
Actually, I tried this scenario and it seems it is not possible to do so from netfilter hooks, however, I'm not sure of it. I thought that it is not working since it has problem with checksums because I'm manipulating packets so I did another experiment to figure this issue out. I just change the packet data and everything worked well. I think checksums don't have any problem since they will be check at NIC while receiving and also same situation while sending so manipulation in between doesn't make anything wrong. I also activate the IPv4 forwarding at the server host(sysctl.config) still nothing changes.
I don't want to create new packet, I only want to alter this packet and send it back. There is another similar question which is creating another packet. Moreover, I'm just thinking why this scenario is not working? But based on the netfilter's architecture it should work.
Thank you
I am also working on this, actually kernel validate the source ip address after ip_rcv function in NF_HOOK which check the source ip address. So just try below command:-
sudo sysctl -w "net.ipv4.conf.all.rp_filter=0"
after doing this also disable your interface from which you send and receive packet just like below:-
sudo sysctl -w "net.ipv4.conf.enp2s0.rp_filter=0"

Linux socket UDP server - exchanging messages between 2 servers on 2 machines

I am working on a small linux socket project. The goal is to have multiple servers (ie. 1,2,3,4,5) that listen for send get and ACK packets from each of their respective clients. I am currently attempting to implement a routing table protocol whereby 2 servers (A, B) exchange their routing tables (vectors containing respective clients, server name, and number of hops). The issue I am having is with binding a socket to B's external address from A and vice-versa. From what I have read you do not bind to anything other than a local address except in certain cases. What I am wondering is how do I simply fire off a UDP packet from one server to another knowing the (static) IP address of each server?
What I am wondering is how do I simply fire off a UDP packet from one
server to another knowing the (static) IP address of each server?
The short answer is, you can't. At least on the Internet proper, only unicast is widely supported, which means that in order to send a UDP packet to another machine, you'll need to know its IP address (somehow).
The longer answer is: The first thing you often need to do is discover the target machines' IP addresses. That might be a matter of having the user manually enter a list of IP addresses, or if the target machines are on the same LAN, you can program a mechanism for auto-discovering them by having your program send out a broadcast or multicast UDP query packet. Make sure any instances of your program running on the same LAN receive that packet and respond to it by sending back a response UDP packet (the responses can be sent by by unicast or multicast or broadcast, your choice), and then your query-originating computer can know from the responses it receives which other IP addresses your program is presently also running on.
Note that a lot of computers and network devices run firewalls that reject incoming UDP packets by default, so if you packets don't seem to be getting through that is a likely reason why.

is it possible to mimic source/destination IP of UDP packets?

I capture network packets of specific protocol (over UDP if this matters) and I need to repeat them to different destination. Just sending captured packets will lose original source/destination IPs but I need to preserve them.
That new destination is 3rd-party tool so I cannot supply original source/destination IPs in custom format. It's connected directly with my ethernet card, so I'm thinking about using raw sockets.
I have IP packets. Can I send them over raw sockets directly to one of my ethernet cards so device connected to this ethernet card will receive them in exactly original view (at least on IP level)? Any other solution?
P.S.
It's intended for completely legal usage if you worry about this, for remote monitoring/recording purposes.
If you have the packets captured in pcap format (tcpdump, wireshark, ...), you can use tcpreplay to replay them.

Resources