Currently I have a setup where, due to configuration that would take forever to fix, I have a server that can only be accessed by ipv4. I also, however, have a server that can be accessed by ipv6. I was wondering if I could use iptables to forward ipv6 traffic on a certain port from one of the servers to another server using ipv4 traffic.
-
2What you're looking for is called NAT64, which I don't think iptables will do (yet).– Chris SCommented Jun 3, 2011 at 2:06
-
Chris is right on - the NAT64 RFCs just got published, I'd give it a while until anything really supports it. That said, you may be able to accomplish your goal in a different way, but we don't have enough detail to know for sure. For instance, if it's an HTTP server, you could reverse-proxy the requests between protocols.– Shane MaddenCommented Jun 3, 2011 at 4:52
6 Answers
IPtables cannot currently do this, so you need a userspace process to proxy the connections. socat is a suitable tool for this:
socat TCP6-LISTEN:1234,fork TCP4:1.2.3.4:1234
-
6thanks, this was helpful! In case anyone is looking for a UDP solution: socat UDP6-RECVFROM:64444,fork UDP4-SENDTO:localhost:64443 worked for me Commented Feb 20, 2014 at 12:32
As noted in the comments on your question, NAT64 is far from being ready, even 3 years later.
You could, however, try 6tunnel
, as suggested by puzzlement.
Fortunately, it is present in the Debian and Ubuntu repositories, so you can install it very easily using sudo apt-get install 6tunnel
. If you are using another system, you'll have to build it from source.
Building from source really isn't hard, and is just a matter of running some commands (as root):
git clone https://github.com/wojtekka/6tunnel && cd 6tunnel && ./autogen.sh && make && make install
Here's its syntax, simplified:
6tunnel [-4|-6] [-l local-host] original-port destination-host destination-port
- The
[-4|-6]
is optional and lets you specify whether you'll bind (listen) on IPv4 or IPv6 (respectively). -l
is also optional. It lets you choose on which address (IPv4 or IPv6) you want to bind.- The original port is the port on which you'll bind.
- The destination host is where you'll forward the traffic to. It can be anywhere: localhost, or somewhere else on your network or on the Internet.
- The destination port is the port on the destination host which will receive your forwarded traffic.
For example, if you want to allow an IPv4-only server, listening on port 1337, to be accessed over IPv6, use:
6tunnel -6 1337 localhost 1337
The above command will listen on port 1337 on IPv6, and forward the traffic to port 1337 on the same machine via IPv4. It will then run in the background, so you don't have to worry about it.
Actually, you should set up a cron job to make sure that it is still running. 6tunnel
provides an example for your convenience! Running it on boot shouldn't be a bad idea either.
For more documentation, run 6tunnel -h
or man 6tunnel
.
-
1Posting it as new answer because editing the current answer by puzzlement would change way too much, and could get rejected as a suggested edit!– Léo LamCommented Jul 12, 2014 at 15:02
Recent versions of xinetd
can also listen on IPv6 and then forward the connection to an IPv4 address.
A sample configuration which listens for IPv6 connections on port 3389 and forwards them to port 3389 of an internal IPv4 address:
service rdp_port_forward
{
flags = IPv6
disable = no
type = UNLISTED
socket_type = stream
protocol = tcp
user = nobody
wait = no
redirect = 10.187.20.42 3389
port = 3389
}
This may be useful in more restricted environments since xinetd
is likely to be installed with your base system or available in approved vendor repositories.
I wanted to comment on Leo Lams answer and upvote, but I do not have enough reputation. First of all: Thank you very much Leo Lam!
For anyone coming along this thread: My ISP changed my connection from IPv4 to IPv6 with Dual Stack Lite, which means I do not have my own IPv4 address anymore. This was an issue as I want to access my IP Camera from anyhwere which does not support IPv6. To resolve this I tried the following:
- Enabling IPv6 Forward for port 99 in my Router to my Ubuntu machine.
- Ubuntu machine (home network):
sudo 6tunnel -6 99 192.168.178.35 80
- vServer Debian with static IPv4 and IPv6 address:
sudo 6tunnel -4 99 IPV6PREFIXROUTER:IPV6INTERFACEIDUUBUNTUMACHINE 99
- vServer Debian: Allow incoming tcp connections on port 99 in iptables
The ipv6 prefix was denoted in my router and the interface id was mapped in the IPv6 forwarding process.
Now I can access the camera from anywhere using the vServer domain example.com:99 .. Perfect! I plan on either getting an raspberry which will fulfill this job or a banana pi m3 for other tasks aswell.
-
1Now you know what to do when you need another IP camera. It's 2015; buying one that doesn't support IPv6 is a complete waste of money. Commented Dec 19, 2015 at 18:32
-
More for the benefit of people finding this page than the OP necessarily (I came here looking for a solution to IPv6 connectivity for an IPv4 (Twisted) application), one possibility is the application 6tunnel, listens on IPv6 and forwards requests to another interface and port.
you might want to consider Jool https://www.jool.mx/en/download.html
-
1Nice, but a workable example for this question would make this an actual answer.– bonanzaCommented Dec 28, 2020 at 18:01
-
Hi, setting up Jool isn't too bad. You'll need to have installed the basic tools as well as the kernel headers and things. Then download and unpack Jool, run configure, run make, run install. jool.mx/en/install.html I was able to create an IPv6 only vlan and have Jool do the 6-to-4 mapping for me, it worked fine with android and a linux desktop (the latter needed the network configuring so that it didn't care if dhcp-v4 failed).– Paul MCommented Dec 29, 2020 at 21:08