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:
To do that we'll run this:
# socat TCP6-LISTEN:8140,reuseaddr,fork TCP4:127.0.0.1:8140
This will listen on the IPv6 port 8140, thanks to the use of TCP6-LISTEN, and traffic which comes in will be sent to 127.0.0.1:8140, 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:127.0.0.1:8140
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:
[Unit] Description=Puppet Proxy Application [Service] User=puppet ExecStart=/usr/bin/socat TCP6-LISTEN:8140,reuseaddr,fork TCP4:127.0.0.1:8140 [Install] WantedBy=multi-user.target
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.