Enabling IPv6 support for IPv4 only apps on Linux

To prove point that IPv6 is ready for production use I've been using IPv6 only setup on my Ubuntu PC for more then 4 months. To access legacy IPv4 Internet I use NAT64 gateway based on Tayga deployed on RockPro64 SBC in my cupboard:

RockPro64 is ARM64 based SBC with dedicated 1G Ethernet and PCI-E slot

Most of the apps I use support IPv6 but there are some cases when lack of IPv4 connectivity on my machine negatively affects experience.

One of the cases which affects my daily experience is a constant need to manually prepend IPv4 addresses for ssh as direct attempt to use ssh with IPv4 literal address fails:

ssh: connect to host port 22: Network is unreachable

Instead I have to append my IPv6 NAT64 prefix all the time:

ssh 64:ff9b::
pavel@64:ff9b::103:307's password:

Luckily for us Linux provides exceptionally easy way to intercept some specific library functions using simple dynamically linked library: LD_PRELOAD

LD_PRELOAD allows us to override some functions with our own logic

When app needs to connect to the network it uses Linux system functions such as socket(), connect(), getpeername(), getsockname() and by overriding them with functions which explicitly transform all IPv4 connection attempts to connections to special IPv6 address crafted using NAT64 prefix. Which this approach in hands we can automatically add IPv6 support for such apps without.

That's exactly how tool called tnat64 works. You can find this tool in Debian or Ubuntu official repositories and installation is as easy as follow:

sudo apt install -y tnat64

This tools provides single dynamic library available on following path: /usr/lib/tnat64/libtnat64.so.

To enable it for specific session in Terminal we need to run following commands:

export LD_PRELOAD=/usr/lib/tnat64/libtnat64.so TNAT64_DEBUG=10 TNAT64_DEBUG_FILE=/tmp/tnat64.log

The only mandatory part here is: LD_PRELOAD, TNAT64_DEBUG and TNAT64_DEBUG_FILE just enable debugging to provide more information how this library  works.

After that when you run any app in same Terminal session it will load libtnat64.so first and then all calls to network functions will be intercepted and as consequence any attempt to connect to IPv4 literal will work just fine even on machine without external IPv4 connectivity:

pavel@'s password:

I would recommend using this apporach only for apps with clear IPv6 support issues. Attempts to enable this logic may lead to some issues as some apps may not like such tricks with syscalls.

To get more information about runtime activity of tnat64 you can check content of it's log file /tmp/tnat64.log:

tnat64 log file

I would like to say thank you for this awesome tool to author of it Andrej Shadura.

Just for historical perspective this tool was written around 2011.

Our current success with IPv6 deployment is a result of two decades of colossal amount of work from incredible number of very talented engineers.

Subscribe to Pavel's blog about underlying Internet technologies

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.