3

This is probably a very basic question.

Wanted to know in Linux if there is a command that could work like the tee command but for forwarding TCP/UDP packets. Basically it should listen at one port and ‘tee’/ forward the same data/packets to all the other hosts configured behind this ‘tee’ like component.

If not a command what would be a recommended setup for the same?

Would netcat or socat be able to do this?

1
  • 2
    You found netcat and socat, what is your question exactly?
    – D. SM
    Jun 28, 2020 at 7:34

2 Answers 2

8

Network communication is usually bidirectional while tee and shell pipelines only work in a uni-directional way.

But, if you have some network services that only receive and never send back data, you can send the same stream of bytes to all of them over TCP with zsh + socat with something like:

generate-stream > >(socat -u - tcp:host:8001) > >(socat -u - tcp:host:8002)

Or with other shells with support for process substitution, but no multios support:

generate-stream | tee >(socat -u - tcp:host:8001) | socat -u - tcp:host:8002

Now to hook that into a service that takes incoming connections and forward the received traffic in that teeed way, you could do something like:

CODE='
  cat > >(socat -u - tcp:host:8001) > >(socat -u - tcp:host:8002)
' socat -u tcp-listen:8000,fork,reuseaddr \
           exec:'zsh -c eval\\ $CODE',nofork

Here starting a service that receives traffic over TCP port 8000 (in a unidirectional way) and forwarding it to servers at TCP port 8001 and 8002 on host.

The nofork is not necessary, it's just an optimisation to have zsh's stdin directly be the network socket.

Or if you don't have zsh but have bash:

CODE='
  tee >(socat -u - tcp:host:8001) | socat -u - tcp:host:8002
' socat -u tcp-listen:8000,fork,reuseaddr \
           exec:'bash -c eval\\ \\\"$CODE\\\"',nofork

That can be adapted to any of the many other transport protocols supported by socat.

You could write a zsh helper function for that like:

ntee() (
  src=$1; shift
  export CODE=cat
  for dst do
    CODE+=" > >(socat -u - ${(qq)dst})"
  done
  socat -u "$src" exec:'zsh -c eval\\ $CODE',nofork
)

And use it as:

ntee tcp-listen:8000,reuseaddr,fork \
       tcp:host1:8001 \
       udp-sendto:host2:8002 \
       file:file.log,creat,append

for instance.

3

The netcat or socat tools are great for dealing with application layer streams of data. To forward copies of network packets to other destinations on a Linux machine you want to look at kernel-level iptables.

The tee functionality you're looking for could be implemented using the TEE extension: iptables TEE extension documentation

The specific iptables rules you'd want to configure will depend on your network interfaces, the number of ports to forward, etc.

Not the answer you're looking for? Browse other questions tagged .