TCP Proxy Setup – How to Create a Persistent TCP Gender-Changer Proxy

PROXYsocattcp

I have a provider (A) that wants to send us data through an incoming TCP connection. Unfortunately the consuming service (B) cannot receive inbound TCP connections. Also it does not have a static IP, another requirement.

One way to solve this would be a service that connects the incoming TCP A port to another TCP port B, so that the consumer can make an outbound connection to B.

This is not a unique problem [1] [2], and with socat I can make something very close to what I want:

socat -d -d -d -u TCP4-LISTEN:PORT-A,reuseaddr TCP4-LISTEN:PORT-B,reuseaddr

However, this has the following problems:

  • If B disconnects, it cannot re-connect. With TCP4-LISTEN:PORT-B,reuseaddr,fork, it can connect but does not receive data.
  • B cannot connect before A has established a connection (surmountable)
  • Only one connection can be established to PORT-B (surmountable)

Is there a way to adjust the command so that is becomes "permament" and resistent to failures?

Best Answer

The important question is, how will A react to loss of connection, or to connection being refused? Anything that just assumes that a single TCP connection will stay up forever is going to be fragile; that's just the nature of internet.

How about setting up the socat as a [x]inetd service?

You would set xinetd to listen in PORT-B, and start the socat -u TCP4-LISTEN:PORT-A,reuseaddr STDIO as soon as the B-side connects.

xinetd will pass the incoming traffic from B-side to standard input of socat, and catch the standard output of socat and pass it to the B-side.

If B disconnects, then the socat process can be allowed to end; xinetd will start a new one as soon as B connects again. While B is disconnected, A will be getting "connection refused" errors.

I once had to do something quite similar on an old HP-UX system.