Port forwarding (or proxying) on OpenWRT with socat

在校园网环境中可能会有这种需求:我可以获取到公网IPv6而不能获取到公网IPv4,但是我的应用程序只支持IPv4(比如某些游戏),能否把到达我的公网IPv6的数据转发到内网IPv4(forward IPv6 to IPv4)?

在OpenWRT上,这个事情如果单纯用iptables或者ip6tables做可能有点复杂。还好,我们有socat这个用户空间(userspace)工具可以达到目的。

完成这个转发的工作原理示意图如下所示:
User <—-> Internet <—-> socat(on your router) <—-> server in your network

Step by step tutorial

在你的OpenWRT上安装socat:

opkg update
opkg install socat

在防火墙设置中打开你想要允许的入站(inbound)端口。为了简单起见,你可以在LUCI中设置。找到Network > Firewall > Traffic Rules,在页面中的Open ports on router中填写相关数据。例如,允许外网访问路由器的10080端口,如下图。

如果你在内网的192.168.1.101有个http服务器,监听端口80。现在你可以用socat将访问你路由器10080端口的流量转发到那上面:

socat TCP6-LISTEN:10080,fork TCP:192.168.1.101:80

这里用TCP6-LISTEN表示只监听路由器IPv6栈上的端口10080。换句话说,远程用户访问你的服务器时必须使用IPv6流量——一个简单的方法就是让他们访问http://[你的公网IPv6]:10080这样的URL(注意方括号不能少)。

本文开头曾经提到某些游戏只支持IPv4。为了让这些游戏的流量走IPv6,用户也可以利用socat(在Windows上可以用Cygwin的socat)进行简单的转换:

socat TCP-LISTEN:23456,bind=127.0.0.1,fork TCP6:[你的公网IPv6]:10080

同时,请他们在游戏中把要连接的服务器地址改成127.0.0.1:23456即可。

下面的示意图解释了socat在转发和转换方面的作用:
User <—-> socat(on his machine) <—-> Internet <—-> socat(on your router) <—-> server in your network

Further reading

SOCAT 简介
Use iptables to forward ipv6 to ipv4?
socat manual

发表评论

电子邮件地址不会被公开。