Do you know socat – Multipurpose relay?

Socat, evaluating possibilities

is another swiss army knife of networking. It incorporates an amazingly big set of use cases. There are yet some to be invented.

Socat’s README explains it function as follows:

socat is a relay for bidirectional data transfer between two independent data
channels. Each of these data channels may be a file, pipe, device (serial line
etc. or a pseudo terminal), a socket (UNIX, IP4, IP6 - raw, UDP, TCP), an
SSL socket, proxy CONNECT connection, a file descriptor (stdin etc.), the GNU
line editor (readline), a program, or a combination of two of these. 
These modes include generation of "listening" sockets, named pipes, and pseudo
terminals.

So what do with socat?

Use it on OpenWRT:
Socat’s binary on OpenWRT 15.05 is relatively small: 159 kilobytes. On Ubuntu 12.04 it’s size is about 290 kilobytes.

  • Use it as Teredo (Miredo) replacement – see below.
  • Use it as an alternative to OpenVPN – just the same way – see below.
  • Let it act as a proxy.
  • Replace netcat.
  • Use it to communicate with our mobile broadband modem.
    • Execute:

      socat - file:/dev/ttyUSB2,raw,echo=0,crtscts,crnl

      and you can send AT-commands, like minicom would do.Also for AT commands, you may want take a look here.

Miredo replacement

is an implementation of the teredo IPv6 tunneling mechanism.
Teredo uses UDP packets to a public teredo server or relay, which is a host with dual stack IP, that will easily trespass most firewalls and will grant one single IPv6 address per client.

Size:
It had only had only 21 kilobytes in OpenWRT Barrier Breaker, but OpenVPN’s binary, which I used too, had 249.4K there.
I could save space, if one tools could replace both, Miredo and OpenVPN on my router…

The idea:
So how about using socat as IPv6 transition mechansim for mobile clients behind NAT trunks instead of miredo (teredo)?

Cons of Teredo (Miredo):

  • You can’t (by design) really use the major advantages of IPv6 like hostnets – you only get one single /128, that is one IPv6 address.
  • It’s metrics are always subsidiary to ‘real’ IPv6 routes, you can’t therefore use it to link a network through it. On the other hand that wouldn’t make sense at all – would it?
  • Some of Miredo’s relays are only for experimental use and therefore are unstable.
  • The Microsoft variant does work well (for me) with implementations like Miredo.
  • Miredo’s packages have recently been dropped from the OpenWRT stable repository, because they seemed to be unmaintained.
  • Teredo works with public relays, as a result your IPv6 address will always change, dependent of server, port and other factors.
  • Teredo servers have a requirement for two static IPv4 addresses and require a T1 or better line.

Pros:

  • Teredo is quite a practical thing: – It’s small, it’s quick and it’s quickly configured.
  • It easily trespasses firewalls allowing for outgoing UDP packets, which is especially good in cases of NAT trunks commonly used by mobile network providers.(Such NAT trunks make it nearly impossible to use e.g. Hurricane Electric (he.net) Tunnelbroker, because they require gateways to be pingable – for a good reason PMTU discovery will otherwise fail regularly. Sixxs/Aiccu will probably work, but I’d prefer not to be abundant to their services for various reasons.)

If you don’t want to setup your very own public teredo server, but you have some other host with -preferrably native- IPv6 support, you could just use socat on both backends to delegate a sub prefix of your hostnet to your other host – which is impossible with teredo design principles.

OpenVPN

OpenVPN is one of the classical and robust tunneling solutions.
As mentioned above, it takes quite some space of flash on my OpenWRT router.
Furthermore, OpenWRT hat various depencies for OpenVPN. Packages compiled against EasyRSA, OpenSSL and PolarSSL exist, as well as a nossl variant.
On AR71xx socat’s .ipk is 80 kilobytes of size, OpenVPN can take from 11 kilobytes to 142 kilobytes of flash in it’s OpenSSL version.
Unpacked this is 154.9 kilobytes for socat, 249.2 kilobytes for OpenVPN (+OpenSSL).

Netcat

netcat hat about 22.5 kilobytes on my OpenWRT’s /rom. socat “is netcat on steroids”.

Minicom

You’d use minicom to talk to your modem. Of course chat -in most cases- will do, too.

Tunneling (OpenVPN replacement + IPv6)

The socat way is a little bit tricky for IPv6 (version 1.7.2.3), but it can be done!
You may want to read socat’s tunneling basics from here.

And that’s the way it it intended to do it:
Server side:
socat -d -d UDP-LISTEN:4711,reuseaddr TUN:[2001:DB8:abcd:eeee::1]/64,iff-up,iff-broadcast,iff-pointopoint

Client side:
socat UDP:myserver.mydomain:4711 TUN:[2001:DB8:abcd:eeee::2]/64,iff-up,iff-broadcast,iff-pointopoint

Unfortunately, this will throw the following error with the version included with OpenWRT 15.05:
2015/09/27 19:11:02 socat[11748] E netmask "[2001:DB8:abcd:eeee::2]/64" is too large
It seems, that socat only accepts IPv4 addresses for TUN-addresses at this stage of development. I had to work around it, but I only tested it with TCP in the first place:
Server:
socat TCP-LISTEN:4711,reuseaddr TUN,iff-up,iff-broadcast,iff-pointopoint; ip a a
2001:DB8:abcd:eeee::1/64 dev tun0

Client:
socat TCP:myserver.mydomain:4711 TUN,iff-up,iff-broadcast,iff-pointopoint; ip a a
2001:DB8:abcd:eeee::2/64 dev tun0;
ip link set dev tun0 link up
Of course, you can do that with UDP as well. Take care, that at your server’s site UDP packages get forwarded correctly.

If you’d like to combine these ways, the lines may read like this:
Server:
socat UDP-LISTEN:4711,reuseaddr TUN:
172.16.12.1/24,up,iff-up,iff-broadcast,iff-pointopoint; ip a a 2001:DB8:abcd:eeee::1/64 dev tun0

Client:
socat UDP:myserver.mydomain:4711 TUN:
172.16.12.2/24,up,iff-up,iff-broadcast,iff-pointopoint; ip a a 2001:DB8:abcd:eeee::2/64 dev tun0;
But that again won’t work, since tun0 is not yet up at the time the command is being executed.
Server:
socat UDP-LISTEN:4711,reuseaddr,fork TUN:172.16.12.1/24,iff-up,iff-broadcast,iff-pointopoint

Client:
socat UDP:myserver.mydomain:4711 TUN:172.16.12.2/24,iff-up,iff-broadcast,iff-pointopoint,up & sleep 2 && ifconfig tun0 up

This will set our tun devices up and establish an IPv4 virtual (but not private) network.
On the (OpenWRT) Client:
socat UDP:myserver.mydomain:4711 TUN:172.16.12.2/24,iff-up,iff-broadcast,iff-pointopoint,up & sleep 2 && ifconfig tun0 up && ip a a 2001:DB8:abcd:eeee::2/64 dev tun0

will do well.

On the server we have a problem: tun0 can only be assigned an address, if it’s up. It isn’t, at least until the client connects to our socat port.

For the server, we can make use of /etc/network/if-up.d (or on OpenWRT /etc/hotplug.d/). If the tun0 devices get up, a script gets executed.

If we need to make sure to access to correct device, we can change it’s name:
socat UDP-LISTEN:4711,reuseaddr,fork TUN:172.16.12.1/24,iff-up,iff-oadcast,iff-pointopoint,tun-name=vpntunnel,tun-type=tun,up
Create /etc/network/if-up.d/vpntunnel
#!/bin/sh
# filename: vpntunnel-up
logger "device vpntunnel created"
if [ "$IFACE" = vpntunnel ]; then
ip a a 2001:DB8:abcd:eeee::1/64 dev vpntunnel
fi

and make it executable:
chmod +x /etc/network/if-up.d/vpntunnel-up
Likewise you can create /etc/network/if-down.d/vpntunnel-down.

Now edit /etc/config/interfaces and add
auto vpntunnel
iface vpntunnel inet manual

If you don’t, the ifup and ifdown script won’t be called.
Logger will make sure a note is added to /var/log/syslog.

Now it should all be working – but remember: that tunnel isn’t secure.

Proxying

socat TCP-LISTEN:80,fork TCP:[proxied server IPv4 address here]:80

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s