背景
家庭网络使用OpenWrt作为主路由。同时,使用DDNS实现外网访问家庭服务。原来的方案中,使用自带防火墙实现流量转发。但是,存在一个问题:局域网中无法访问流量转发的服务。此问题一般情况下影响较小,但是,最近在搭建rustdesk中继模式设置时由于这个问题,导致内网无法实现中继模式。
解决方案
使用socat代替防火墙实现流量转发。但是,官方源中的socat只是一个服务,没有图形化界面配置。因此,还需要基于luci实现图形化socat配置界面。
操作步骤
安装socat
在图形化界面中安装

也可以在命令行中安装
1
|
opkg update && opkg install socat
|
启动socat并设置开机自启
1
|
/etc/init.d/socat enable && /etc/init.d/socat start
|
实现图形化界面
新增/usr/lib/lua/luci/controller/socat.lua
。功能是在服务菜单下注册一个socat的子菜单。
1
2
3
4
5
|
module("luci.controller.socat", package.seeall)
function index()
entry({"admin","services","socat"}, cbi("socat"), "Socat", 100)
end
|
新增/usr/lib/lua/luci/model/cbi/socat.lua
。这个是具体的页面代码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
require("luci.sys")
m = Map("socat", translate("Socat Service"), translate("Configure socat service"))
s = m:section(TypedSection, "socat", "")
s.addremove = true
s.anonymous = false
enable = s:option(Flag, "enable", translate("Enable"))
enable.rmempty = false
run_as = s:option(Value, "user", translate("Run As"))
run_as.default = "root"
run_as.rmempty = false
options = s:option(TextValue, "SocatOptions", translate("Socat Options"))
options.default = "TCP-LISTEN:12345,fork,reuseaddr TCP:10.10.10.10:12345"
options.rmempty = false
options.size = 40
local apply = luci.http.formvalue("cbi.apply")
if apply then
io.popen("/etc/init.d/socat restart")
end
return m
|
最终的效果:

配置示例
TCP
1
|
TCP-LISTEN:21115,fork,reuseaddr TCP:192.168.2.21:21115
|
UDP,注意-T5
参数,表示在5秒内如果没有发生任何事情,则终止进程
1
|
-T5 UDP-LISTEN:21116,fork,reuseaddr UDP:192.168.2.21:21116
|

参考文档
https://dosk.win/2021/11/19/openwrt-tian-jia-yi-ge-socat-de-luci-web-jie-mian/
https://linux.die.net/man/1/socat