1

I have the following network:

~~~~~~~ MACHINE A ~~~~~~~                   ~~~~~~~~ MACHINE B ~~~~~~~~

+--------+                                                   +--------+
| client |----(a)                               (b)----------| server |
+--------+     |                                 |   [port Z]+--------+
               |                                 |
               |                                 |
               |[port X]                         |
        +---------------+                   +---------------+
        | interceptor A |-------------------| interceptor B |
        +---------------+           [port Y]+---------------+

For context:

  • All machines are Raspberry Pi's running Raspberry Pi OS, Linux kernel 5.15.
  • The solution should be language agnostic, if possible. However, I am using C.
  • IP addresses are statically assigned.
  • There are more than two machines on the network that need to communicate in this fashion.
  • All processes need to run in user space.

On Machine A, process client needs to communicate with process server (listening on port Z) on Machine B on the same local network. This would normally occur via a simple TCP socket. However, I want to intercept the bytes sent from client to server (and vice versa, since TCP is bidirectional) and do some "magic" with processes interceptor A and interceptor B before "forwarding" the data to server. Importantly, the actual TCP connection between the machines must be independently handled by client interceptor A and server interceptor B (listening on port Y). However, client and server need to think they're communicating with each other directly.

My initial solution is the following:

  1. Use nftables at point (a) to modify destination IP/port so that packets are redirected to interceptor A (listening on port X) instead of server. So, when client attempts to connect to server on port B, it actually connects to interceptor A (acting as server) on port X.
  2. interceptor A then connects to interceptor B. It does any processing before "forwarding" the bytes from client.
  3. interceptor B connects to server. However, at point (b), also use nftables to transform source IP/port to that of client instead of interceptor B. So server thinks it just accepted a connection with client.

TL;DR: I need to redirect an outgoing socket connection to localhost, do some processing with the bytes and retransmit those bytes over a new connection to endpoint. Endpoints should not know there are intermediate processes managing the real inter-machine connection.

Questions:

  1. Is setting NAT rules in nftables a proper solution? It seems that the normal usage of NAT (transforming private IP to global IP) does the operations in the opposite order, but it seems that it would work.
  2. More importantly, how can interceptor A, as an application-layer process, know which IP address client was originally trying to communicate with? This is necessary so it can create a connection to interceptor B on the correct machine.

This project is in the planning phase, so I don't have a minimum working example. I'm willing to edit the question to add one, but I think the minimum working example is really just what I'm trying to achieve.

ClausWorks
  • 33
  • 4

0 Answers0