Do you use let's encrypt?

6387 votes ~ 21 comments


Offering IPv4-only services over IPv6

Posted by Steve on Sun 29 Nov 2015 at 08:06

Although IPv6 is clearly the way of the future there are some software services which only support IPv4 access. Here we'll show a simple approach to exporting them to IPv6-based clients.

Although they are becoming rarer there are still some network services which don't support IPv6, which you might wish to use. I see examples of this reasonably often as a result of having a couple of virtual machines with IPv6-only connectivity.

There are a couple of different ways you can provide IPv6 support to IPv4-only systems, for example you can use NAT64 if you have a dual-homed server to act as a bridge, similarly you could sidestep the problem by running a small/local VPN giving your IPv6-only hosts a IPv4 address each.

As a simple solution though it is hard to beat the use of socat. The socat package is a program which will allow bi-direction data transfer, and supports many useful options.

Install it as per usual:

# aptitude install socat

Now we'll configure it to run - we'll assume we have a dual-stack system running Puppet on an IPv4-only address. Puppet is accessed over port 8140, so we want to make sure:

  • IPv6 connections to port 8140 are forwarded to

To do that we'll run this:

# socat TCP6-LISTEN:8140,reuseaddr,fork TCP4:

This will listen on the IPv6 port 8140, thanks to the use of TCP6-LISTEN, and traffic which comes in will be sent to, via TCP4. Perfect.

As these are "high ports" this can be executed by any user, and doesn't need root-permissions. The example above will bind port 8140 on all available IPv6 addresses, if you prefer to listen upon a single address then you can add it explicitly:

~$ socat TCP6-LISTEN:8140,reuseaddr,fork,bind=[2001:41c8:123:123:123:123] TCP4:

Because this is a simple one-line command it is pretty simple to turn into a service. If you're running systemd, for example, you can create the file /lib/systemd/system/puppet-proxy.service with the following content:

Description=Puppet Proxy Application

ExecStart=/usr/bin/socat TCP6-LISTEN:8140,reuseaddr,fork TCP4:


With that file saved you enable it, and start it, via:

# systemctl enable puppet-proxy.service
# systemctl start puppet-proxy.service

Note that I'm explicitly specifying a user to run the command as, via the "User=puppet" line. There's no reason to run socat as root, and it is best avoided.

I should also note that I'm not intending to pick on puppet here. The puppet server/master does support IPv6 natively, although historically there have been many users who had problems running a master upon both IPv6 and IPv4.

Finally it should be noted that by swapping the arguments around you can provide services in the reverse direction - using socat to proxy from IPv4 to IPv6 systems.



Re: Offering IPv4-only services over IPv6
Posted by Anonymous (124.197.xx.xx) on Sun 29 Nov 2015 at 10:08
Thanks for the article. I've been working a bit on what I call an SSH botnet, and all I can tell you is that socat is awesome and (in combination with SSH) could (should) replace all the NIH-transports invented by automation and monitoring tools all around…

[ Parent | Reply to this comment ]

Re: Offering IPv4-only services over IPv6
Posted by Anonymous (80.50.xx.xx) on Wed 29 Jun 2016 at 09:55
Puppet works with Ipv6

On master add to config:
#listen ipv6 and ipv4

[ Parent | Reply to this comment ]

Re: Offering IPv4-only services over IPv6
Posted by Anonymous (217.82.xx.xx) on Thu 23 Mar 2017 at 22:42

Unless you create a package for it: put the systemd unit into /etc, not /lib. That way you can see your local configuration with find /etc/systemd/ -type f.

SEE ALSO: FHS, Debian policy

[ Parent | Reply to this comment ]