fea: support disable snat.
Some checks failed
Coverage CI / build (push) Has been cancelled
CodeQL / Analyze (go) (push) Has been cancelled
Ubuntu CI / build (push) Has been cancelled

This commit is contained in:
Daniel Ding
2024-10-20 22:40:26 +08:00
parent 0255bc9c6b
commit 49ecf383f4
7 changed files with 60 additions and 36 deletions

View File

@@ -24,7 +24,6 @@ func (r Route) Add(c *cli.Context) error {
NextHop: c.String("nexthop"), NextHop: c.String("nexthop"),
FindHop: c.String("findhop"), FindHop: c.String("findhop"),
Metric: c.Int("metric"), Metric: c.Int("metric"),
Mode: c.String("mode"),
} }
url := r.Url(c.String("url"), network) url := r.Url(c.String("url"), network)
clt := r.NewHttp(c.String("token")) clt := r.NewHttp(c.String("token"))

View File

@@ -4,11 +4,6 @@
"bridge": { "bridge": {
"address": "172.32.99.40/24" "address": "172.32.99.40/24"
}, },
"routes": [
{
"prefix": "172.32.10.0/24"
}
],
"openvpn": { "openvpn": {
"listen": "0.0.0.0:3294", "listen": "0.0.0.0:3294",
"subnet": "172.32.194.0/24" "subnet": "172.32.194.0/24"

View File

@@ -5,19 +5,6 @@
"address": "172.32.100.40/24", "address": "172.32.100.40/24",
"tcpMss": 1360 "tcpMss": 1360
}, },
"routes": [
{
"prefix": "172.32.10.0/24"
}
],
"links": [
{
"protocol": "tls",
"connection": "hi.openlan.net",
"username": "hi",
"password": "1f4ee82b5eb6"
}
],
"openvpn": { "openvpn": {
"protocol": "tcp", "protocol": "tcp",
"listen": "0.0.0.0:3295", "listen": "0.0.0.0:3295",
@@ -35,5 +22,6 @@
}, },
"acl": "acl-100", "acl": "acl-100",
"dhcp": "enable", "dhcp": "enable",
"snat": "disable",
"namespace": "example" "namespace": "example"
} }

View File

@@ -114,6 +114,8 @@ type Networker interface {
FindHoper() FindHoper FindHoper() FindHoper
DoZTrust() DoZTrust()
UndoZTrust() UndoZTrust()
DoSnat()
UndoSnat()
} }
type IPSecer interface { type IPSecer interface {

View File

@@ -25,6 +25,7 @@ type Network struct {
Outputs []*Output `json:"outputs,omitempty"` Outputs []*Output `json:"outputs,omitempty"`
ZTrust string `json:"ztrust,omitempty"` ZTrust string `json:"ztrust,omitempty"`
Qos string `json:"qos,omitempty"` Qos string `json:"qos,omitempty"`
Snat string `json:"snat,omitempty"`
Namespace string `json:"namespace,omitempty"` Namespace string `json:"namespace,omitempty"`
FindHop map[string]*FindHop `json:"findhop,omitempty"` FindHop map[string]*FindHop `json:"findhop,omitempty"`
} }

View File

@@ -13,7 +13,6 @@ type PrefixRoute struct {
NextHop string `json:"nexthop"` NextHop string `json:"nexthop"`
FindHop string `json:"findhop"` FindHop string `json:"findhop"`
Metric int `json:"metric"` Metric int `json:"metric"`
Mode string `json:"mode"`
MultiPath []MultiPath `json:"multipath,omitempty"` MultiPath []MultiPath `json:"multipath,omitempty"`
} }

View File

@@ -56,6 +56,7 @@ type WorkerImpl struct {
br cn.Bridger br cn.Bridger
acl *ACL acl *ACL
findhop *FindHop findhop *FindHop
snat *cn.FireWallChain
} }
func NewWorkerApi(c *co.Network) *WorkerImpl { func NewWorkerApi(c *co.Network) *WorkerImpl {
@@ -115,6 +116,7 @@ func (w *WorkerImpl) Initialize() {
w.createVPN() w.createVPN()
w.fire = cn.NewFireWallTable(cfg.Name) w.fire = cn.NewFireWallTable(cfg.Name)
w.snat = cn.NewFireWallChain("XTT_"+cfg.Name+"_SNAT", cn.TNat, "")
if out, err := w.setV.Clear(); err != nil { if out, err := w.setV.Clear(); err != nil {
w.out.Error("WorkerImpl.Initialize: create ipset: %s %s", out, err) w.out.Error("WorkerImpl.Initialize: create ipset: %s %s", out, err)
@@ -394,6 +396,36 @@ func (w *WorkerImpl) SetMss(mss int) {
} }
} }
func (w *WorkerImpl) doSnat() {
w.fire.Nat.Post.AddRuleX(cn.IPRule{
Jump: w.snat.Chain().Name,
Comment: "Goto SNAT",
})
}
func (w *WorkerImpl) undoSnat() {
w.fire.Nat.Post.DelRuleX(cn.IPRule{
Jump: w.snat.Chain().Name,
Comment: "Goto SNAT",
})
}
func (w *WorkerImpl) DoSnat() {
cfg, _ := w.GetCfgs()
if cfg.Snat != "disable" {
cfg.Snat = "enable"
w.doSnat()
}
}
func (w *WorkerImpl) UndoSnat() {
cfg, _ := w.GetCfgs()
if cfg.Snat == "disable" {
cfg.Snat = "disable"
w.undoSnat()
}
}
func (w *WorkerImpl) doTrust() { func (w *WorkerImpl) doTrust() {
_, vpn := w.GetCfgs() _, vpn := w.GetCfgs()
w.fire.Mangle.Pre.AddRuleX(cn.IPRule{ w.fire.Mangle.Pre.AddRuleX(cn.IPRule{
@@ -403,6 +435,15 @@ func (w *WorkerImpl) doTrust() {
}) })
} }
func (w *WorkerImpl) undoTrust() {
_, vpn := w.GetCfgs()
w.fire.Mangle.Pre.DelRuleX(cn.IPRule{
Input: vpn.Device,
Jump: w.ztrust.Chain(),
Comment: "Goto Zero Trust",
})
}
func (w *WorkerImpl) DoZTrust() { func (w *WorkerImpl) DoZTrust() {
cfg, _ := w.GetCfgs() cfg, _ := w.GetCfgs()
if cfg.ZTrust != "enable" { if cfg.ZTrust != "enable" {
@@ -411,15 +452,6 @@ func (w *WorkerImpl) DoZTrust() {
} }
} }
func (w *WorkerImpl) undoTrust() {
_, vpn := w.GetCfgs()
w.fire.Mangle.Pre.DelRuleX(cn.IPRule{
Input: vpn.Device,
Jump: w.ztrust.Chain(),
Comment: "Goto Zero Trust",
})
}
func (w *WorkerImpl) UndoZTrust() { func (w *WorkerImpl) UndoZTrust() {
cfg, _ := w.GetCfgs() cfg, _ := w.GetCfgs()
if cfg.ZTrust == "enable" { if cfg.ZTrust == "enable" {
@@ -491,6 +523,10 @@ func (w *WorkerImpl) Start(v api.Switcher) {
} }
w.fire.Start() w.fire.Start()
w.snat.Install()
if cfg.Snat != "disable" {
w.doSnat()
}
if cfg.Bridge.Mss > 0 { if cfg.Bridge.Mss > 0 {
// forward to remote // forward to remote
w.setMss() w.setMss()
@@ -575,6 +611,12 @@ func (w *WorkerImpl) RestartVPN() {
func (w *WorkerImpl) Stop() { func (w *WorkerImpl) Stop() {
w.out.Info("WorkerImpl.Stop") w.out.Info("WorkerImpl.Stop")
cfg, _ := w.GetCfgs()
if cfg.Snat != "disable" {
w.undoSnat()
}
w.snat.Cancel()
w.fire.Stop() w.fire.Stop()
w.findhop.Stop() w.findhop.Stop()
w.acl.Stop() w.acl.Stop()
@@ -593,8 +635,8 @@ func (w *WorkerImpl) Stop() {
w.vrf.Down() w.vrf.Down()
} }
for _, output := range w.cfg.Outputs { for _, output := range cfg.Outputs {
w.delOutput(w.cfg.Bridge.Name, output) w.delOutput(cfg.Bridge.Name, output)
} }
w.setR.Destroy() w.setR.Destroy()
@@ -691,7 +733,7 @@ func (w *WorkerImpl) toForward_s(input, srcSet, prefix, comment string) {
func (w *WorkerImpl) toMasq_r(source, pfxSet, comment string) { func (w *WorkerImpl) toMasq_r(source, pfxSet, comment string) {
// Enable masquerade from source to prefix. // Enable masquerade from source to prefix.
output := "" output := ""
w.fire.Nat.Post.AddRule(cn.IPRule{ w.snat.AddRule(cn.IPRule{
Mark: uint32(w.table), Mark: uint32(w.table),
Source: source, Source: source,
DestSet: pfxSet, DestSet: pfxSet,
@@ -705,7 +747,7 @@ func (w *WorkerImpl) toMasq_r(source, pfxSet, comment string) {
func (w *WorkerImpl) toMasq_s(srcSet, prefix, comment string) { func (w *WorkerImpl) toMasq_s(srcSet, prefix, comment string) {
output := "" output := ""
// Enable masquerade from source to prefix. // Enable masquerade from source to prefix.
w.fire.Nat.Post.AddRule(cn.IPRule{ w.snat.AddRule(cn.IPRule{
Mark: uint32(w.table), Mark: uint32(w.table),
SrcSet: srcSet, SrcSet: srcSet,
Dest: prefix, Dest: prefix,
@@ -837,6 +879,7 @@ func (w *WorkerImpl) forwardVPN() {
for _, rt := range vpn.Routes { for _, rt := range vpn.Routes {
w.addVPNSet(rt) w.addVPNSet(rt)
} }
if w.vrf != nil { if w.vrf != nil {
w.toForward_r(w.vrf.Name(), vpn.Subnet, w.setV.Name, "From VPN") w.toForward_r(w.vrf.Name(), vpn.Subnet, w.setV.Name, "From VPN")
} else { } else {
@@ -904,7 +947,6 @@ func (w *WorkerImpl) forwardSubnet() {
if vpn != nil { if vpn != nil {
w.toMasq_s(w.setR.Name, vpn.Subnet, "To VPN") w.toMasq_s(w.setR.Name, vpn.Subnet, "To VPN")
} }
w.toMasq_r(subnet.String(), w.setR.Name, "To Masq") w.toMasq_r(subnet.String(), w.setR.Name, "To Masq")
} }
@@ -970,7 +1012,6 @@ func (w *WorkerImpl) correctRoute(route *schema.PrefixRoute) co.PrefixRoute {
Prefix: route.Prefix, Prefix: route.Prefix,
NextHop: route.NextHop, NextHop: route.NextHop,
FindHop: route.FindHop, FindHop: route.FindHop,
Mode: route.Mode,
Metric: route.Metric, Metric: route.Metric,
} }
rt.CorrectRoute(w.IfAddr()) rt.CorrectRoute(w.IfAddr())
@@ -983,7 +1024,6 @@ func (w *WorkerImpl) ListRoute(call func(obj schema.PrefixRoute)) {
Prefix: obj.Prefix, Prefix: obj.Prefix,
NextHop: obj.NextHop, NextHop: obj.NextHop,
FindHop: obj.FindHop, FindHop: obj.FindHop,
Mode: obj.Mode,
Metric: obj.Metric, Metric: obj.Metric,
} }
call(data) call(data)