From 8df34428dd015893df9466ba6b9101f47fe695bb Mon Sep 17 00:00:00 2001 From: huweishan Date: Mon, 8 Apr 2024 14:54:09 +0800 Subject: [PATCH 1/8] =?UTF-8?q?acl=E6=94=AF=E6=8C=81=E9=80=97=E5=8F=B7?= =?UTF-8?q?=E5=88=86=E9=9A=94=E5=A4=9A=E7=AB=AF=E5=8F=A3=E5=8F=B7=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/dbdata/group.go | 39 +++++++++++-- server/handler/payload.go | 2 +- web/src/pages/group/List.vue | 110 +++++++++++++++++------------------ 3 files changed, 89 insertions(+), 62 deletions(-) diff --git a/server/dbdata/group.go b/server/dbdata/group.go index 8e561b6..d8f8f1f 100644 --- a/server/dbdata/group.go +++ b/server/dbdata/group.go @@ -6,6 +6,7 @@ import ( "net" "regexp" "strings" + "strconv" "time" "github.com/bjdgyc/anylink/base" @@ -24,11 +25,12 @@ const DsMaxLen = 20000 type GroupLinkAcl struct { // 自上而下匹配 默认 allow * * - Action string `json:"action"` // allow、deny - Val string `json:"val"` - Port uint16 `json:"port"` - IpNet *net.IPNet `json:"ip_net"` - Note string `json:"note"` + Action string `json:"action"` // allow、deny + Val string `json:"val"` + PortStr string `json:"port_str"` + Ports []uint16 `json:"ports"` + IpNet *net.IPNet `json:"ip_net"` + Note string `json:"note"` } type ValData struct { @@ -161,9 +163,25 @@ func SetGroup(g *Group) error { return errors.New("GroupLinkAcl 错误" + err.Error()) } v.IpNet = ipNet - linkAcl = append(linkAcl, v) + if regexp.MustCompile(`^\d{1,5}(,\d{1,5})*$`).MatchString(v.PortStr) { + for _, port := range strings.Split(v.PortStr, ",") { + if port == "" { + continue + } + portInt, err := strconv.Atoi(port) + if err != nil { + return errors.New("端口:"+port+" 格式错误, " + err.Error()) + } + v.Ports = append(v.Ports, uint16(portInt)) + } + linkAcl = append(linkAcl, v) + } else { + return errors.New("端口: "+v.PortStr+" 格式错误,请用逗号分隔的端口列表,比如: 22,80,443") + } + } } + g.LinkAcl = linkAcl // DNS 判断 @@ -238,6 +256,15 @@ func SetGroup(g *Group) error { return err } +func ContainsInPorts(ports []uint16, port uint16) bool { + for _, p := range ports { + if p == port { + return true + } + } + return false +} + func GroupAuthLogin(name, pwd string, authData map[string]interface{}) error { g := &Group{Auth: authData} authType := g.Auth["type"].(string) diff --git a/server/handler/payload.go b/server/handler/payload.go index e5ed545..2bca3f6 100644 --- a/server/handler/payload.go +++ b/server/handler/payload.go @@ -89,7 +89,7 @@ func checkLinkAcl(group *dbdata.Group, pl *sessdata.Payload) bool { // 循环判断ip和端口 if v.IpNet.Contains(ipDst) { // 放行允许ip的ping - if v.Port == ipPort || v.Port == 0 || ipProto == waterutil.ICMP { + if dbdata.ContainsInPorts( v.Ports , ipPort) || v.Ports[0] == 0 || ipProto == waterutil.ICMP { if v.Action == dbdata.Allow { return true } else { diff --git a/web/src/pages/group/List.vue b/web/src/pages/group/List.vue index cb28dce..085b22a 100644 --- a/web/src/pages/group/List.vue +++ b/web/src/pages/group/List.vue @@ -52,7 +52,7 @@ + {{ item.val }}
- {{ item.val }} + {{ item.val }}
- {{ readMore[`ri_${ scope.row.id }`] ? "▲ 收起" : "▼ 更多" }} -
+ {{ readMore[`ri_${ scope.row.id }`] ? "▲ 收起" : "▼ 更多" }} +
@@ -87,9 +87,9 @@ {{ item.val }}
- {{ item.val }} + {{ item.val }}
- {{ readMore[`re_${ scope.row.id }`] ? "▲ 收起" : "▼ 更多" }} + {{ readMore[`re_${ scope.row.id }`] ? "▲ 收起" : "▼ 更多" }}
@@ -100,15 +100,15 @@ min-width="180"> @@ -178,7 +178,7 @@ - + @@ -234,7 +234,7 @@ 启用 停用 - + @@ -244,43 +244,43 @@ Radius LDAP - + - + + + @@ -293,7 +293,7 @@ - + - + - 输入CIDR格式如: 192.168.3.0/24 端口0表示所有端口 + 输入CIDR格式如: 192.168.3.0/24 端口0表示所有端口,多个端口用,号分隔 - + - + :key="index" style="margin-bottom: 5px" :gutter="1"> + @@ -361,10 +361,10 @@ - - + + - + @@ -378,7 +378,7 @@ - +
注:域名拆分隧道,仅支持AnyConnect的windows和MacOS桌面客户端,不支持移动端.
@@ -392,7 +392,7 @@ 取消
-
+ 取 消 - + { resp.data.data.bandwidth_format = this.convertBandwidth(resp.data.data.bandwidth, 'BYTE', 'Mbps').toString(); - this.ruleForm = resp.data.data; + this.ruleForm = resp.data.data; this.setAuthData(resp.data.data); }).catch(error => { this.$message.error('哦,请求出错'); @@ -654,7 +654,7 @@ export default { if (!valid) { console.log('error submit!!'); return false; - } + } this.authLoginLoading = true; axios.post('/group/auth_login', {name:this.authLoginForm.name, pwd:this.authLoginForm.pwd, @@ -663,7 +663,7 @@ export default { if (rdata.code === 0) { this.$message.success("登录成功"); } else { - this.$message.error(rdata.msg); + this.$message.error(rdata.msg); } this.authLoginLoading = false; console.log(rdata); @@ -679,7 +679,7 @@ export default { if (!valid) { console.log('error submit!!'); return false; - } + } this.authLoginDialog = true; // set authLoginFormName focus this.$nextTick(() => { @@ -690,14 +690,14 @@ export default { openIpListDialog(type) { this.ipListDialog = true; this.ipEditForm.type = type; - this.ipEditForm.ip_list = this.ruleForm[type].map(item => item.val + (item.note ? "," + item.note : "")).join("\n"); + this.ipEditForm.ip_list = this.ruleForm[type].map(item => item.val + (item.note ? "," + item.note : "")).join("\n"); }, ipEdit() { this.ipEditLoading = true; let ipList = []; if (this.ipEditForm.ip_list.trim() !== "") { ipList = this.ipEditForm.ip_list.trim().split("\n"); - } + } let arr = []; for (let i = 0; i < ipList.length; i++) { let item = ipList[i]; @@ -714,7 +714,7 @@ export default { }; if (this.ipEditForm.type == "route_include" && ip[0] == "all") { pushToArr(); - continue; + continue; } let valid = this.isValidCIDR(ip[0]); if (!valid.valid) { @@ -768,14 +768,14 @@ export default { var isSwitch = true if (! this.user_edit_dialog) { return isSwitch; - } + } this.$refs['ruleForm'].validate((valid) => { if (!valid) { this.$message.error("错误:您有必填项没有填写。") isSwitch = false; return false; } - }); + }); return isSwitch; }, closeDialog() { From 38b8f0b2aa49c39dcc711d50593a8a767f5c8bb2 Mon Sep 17 00:00:00 2001 From: huweishan Date: Mon, 8 Apr 2024 15:12:47 +0800 Subject: [PATCH 2/8] =?UTF-8?q?ports=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/dbdata/group.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/dbdata/group.go b/server/dbdata/group.go index d8f8f1f..12814f3 100644 --- a/server/dbdata/group.go +++ b/server/dbdata/group.go @@ -164,6 +164,7 @@ func SetGroup(g *Group) error { } v.IpNet = ipNet if regexp.MustCompile(`^\d{1,5}(,\d{1,5})*$`).MatchString(v.PortStr) { + ports := []uint16{} for _, port := range strings.Split(v.PortStr, ",") { if port == "" { continue @@ -172,8 +173,9 @@ func SetGroup(g *Group) error { if err != nil { return errors.New("端口:"+port+" 格式错误, " + err.Error()) } - v.Ports = append(v.Ports, uint16(portInt)) + ports = append(ports, uint16(portInt)) } + v.Ports = ports linkAcl = append(linkAcl, v) } else { return errors.New("端口: "+v.PortStr+" 格式错误,请用逗号分隔的端口列表,比如: 22,80,443") From 15573a6ef3e8d7e033617a331d73e417dff1a155 Mon Sep 17 00:00:00 2001 From: huweishan Date: Mon, 8 Apr 2024 16:13:52 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=BF=9E=E7=BB=AD?= =?UTF-8?q?=E7=AB=AF=E5=8F=A3,=E6=AF=94=E5=A6=821234-5678?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/dbdata/group.go | 47 +++++++++++++++++++++++++++--------- server/handler/payload.go | 2 +- web/src/pages/group/List.vue | 2 +- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/server/dbdata/group.go b/server/dbdata/group.go index 12814f3..d15b5aa 100644 --- a/server/dbdata/group.go +++ b/server/dbdata/group.go @@ -28,7 +28,7 @@ type GroupLinkAcl struct { Action string `json:"action"` // allow、deny Val string `json:"val"` PortStr string `json:"port_str"` - Ports []uint16 `json:"ports"` + Ports []PortData `json:"ports"` IpNet *net.IPNet `json:"ip_net"` Note string `json:"note"` } @@ -44,6 +44,13 @@ type GroupNameId struct { Name string `json:"name"` } + +type PortData struct { + PortFrom uint16 `json:"port_from"` + PortTo uint16 `json:"port_to"` +} + + // type Group struct { // Id int `json:"id" xorm:"pk autoincr not null"` // Name string `json:"name" xorm:"varchar(60) not null unique"` @@ -163,17 +170,35 @@ func SetGroup(g *Group) error { return errors.New("GroupLinkAcl 错误" + err.Error()) } v.IpNet = ipNet - if regexp.MustCompile(`^\d{1,5}(,\d{1,5})*$`).MatchString(v.PortStr) { - ports := []uint16{} - for _, port := range strings.Split(v.PortStr, ",") { - if port == "" { + if regexp.MustCompile(`^\d{1,5}(-\d{1,5})?(,\d{1,5}(-\d{1,5})?)*$`).MatchString(v.PortStr) { + ports := []PortData{} + for _, p := range strings.Split(v.PortStr, ",") { + if p == "" { continue } - portInt, err := strconv.Atoi(port) - if err != nil { - return errors.New("端口:"+port+" 格式错误, " + err.Error()) + portData :=PortData{PortFrom: 0, PortTo: 0} + if regexp.MustCompile(`^\d{1,5}-\d{1,5}$`).MatchString(p) { + rp := strings.Split(p, "-"); + portfrom, err := strconv.Atoi(rp[0]) + if err != nil { + return errors.New("端口:"+rp[0]+" 格式错误, " + err.Error()) + } + portto, err := strconv.Atoi(rp[1]) + if err != nil { + return errors.New("端口:"+rp[1]+" 格式错误, " + err.Error()) + } + portData.PortFrom=uint16(portfrom) + portData.PortTo=uint16(portto) + } else { + port, err := strconv.Atoi(p) + if err != nil { + return errors.New("端口:"+p+" 格式错误, " + err.Error()) + } + portData.PortFrom=uint16(port) + portData.PortTo=uint16(port) } - ports = append(ports, uint16(portInt)) + + ports = append(ports, portData) } v.Ports = ports linkAcl = append(linkAcl, v) @@ -258,9 +283,9 @@ func SetGroup(g *Group) error { return err } -func ContainsInPorts(ports []uint16, port uint16) bool { +func ContainsInPorts(ports []PortData, port uint16) bool { for _, p := range ports { - if p == port { + if p.PortFrom<=port && p.PortTo >= port { return true } } diff --git a/server/handler/payload.go b/server/handler/payload.go index 2bca3f6..590f272 100644 --- a/server/handler/payload.go +++ b/server/handler/payload.go @@ -89,7 +89,7 @@ func checkLinkAcl(group *dbdata.Group, pl *sessdata.Payload) bool { // 循环判断ip和端口 if v.IpNet.Contains(ipDst) { // 放行允许ip的ping - if dbdata.ContainsInPorts( v.Ports , ipPort) || v.Ports[0] == 0 || ipProto == waterutil.ICMP { + if dbdata.ContainsInPorts( v.Ports , ipPort) || v.Ports[0].PortFrom == 0 || ipProto == waterutil.ICMP { if v.Action == dbdata.Allow { return true } else { diff --git a/web/src/pages/group/List.vue b/web/src/pages/group/List.vue index 085b22a..780c9de 100644 --- a/web/src/pages/group/List.vue +++ b/web/src/pages/group/List.vue @@ -362,7 +362,7 @@ - + From e55b2b6f0ae0abbaafbe939bbb8ef85725643393 Mon Sep 17 00:00:00 2001 From: huweishan Date: Mon, 8 Apr 2024 16:16:45 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=BF=9E=E7=BB=AD?= =?UTF-8?q?=E7=AB=AF=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/dbdata/group.go | 2 +- web/src/pages/group/List.vue | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server/dbdata/group.go b/server/dbdata/group.go index d15b5aa..40941b4 100644 --- a/server/dbdata/group.go +++ b/server/dbdata/group.go @@ -203,7 +203,7 @@ func SetGroup(g *Group) error { v.Ports = ports linkAcl = append(linkAcl, v) } else { - return errors.New("端口: "+v.PortStr+" 格式错误,请用逗号分隔的端口列表,比如: 22,80,443") + return errors.New("端口: "+v.PortStr+" 格式错误,请用逗号分隔的端口,比如: 22,80,443 连续端口用-,比如:1234-5678") } } diff --git a/web/src/pages/group/List.vue b/web/src/pages/group/List.vue index 780c9de..0f20d5b 100644 --- a/web/src/pages/group/List.vue +++ b/web/src/pages/group/List.vue @@ -344,8 +344,8 @@ - 输入CIDR格式如: 192.168.3.0/24 端口0表示所有端口,多个端口用,号分隔 - + 输入CIDR格式如: 192.168.3.0/24 端口0表示所有端口,多个端口用,号分隔,连续端口:1234-5678 + From 4f56ea49c3eafeac1e20ca21bf1760c7572674ca Mon Sep 17 00:00:00 2001 From: huweishan Date: Mon, 8 Apr 2024 19:34:11 +0800 Subject: [PATCH 5/8] =?UTF-8?q?ports=E4=BF=9D=E5=AD=98=E4=B8=BAmap=20?= =?UTF-8?q?=E5=85=BC=E5=AE=B9=E8=80=81=E7=9A=84=E9=85=8D=E7=BD=AE=E6=95=B0?= =?UTF-8?q?=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/dbdata/group.go | 54 +++++++++++++++++++++--------------- server/handler/payload.go | 20 +++++++++---- web/src/pages/group/List.vue | 6 ++-- 3 files changed, 49 insertions(+), 31 deletions(-) diff --git a/server/dbdata/group.go b/server/dbdata/group.go index 40941b4..efedd43 100644 --- a/server/dbdata/group.go +++ b/server/dbdata/group.go @@ -8,6 +8,7 @@ import ( "strings" "strconv" "time" + "reflect" "github.com/bjdgyc/anylink/base" "golang.org/x/text/language" @@ -25,12 +26,12 @@ const DsMaxLen = 20000 type GroupLinkAcl struct { // 自上而下匹配 默认 allow * * - Action string `json:"action"` // allow、deny - Val string `json:"val"` - PortStr string `json:"port_str"` - Ports []PortData `json:"ports"` - IpNet *net.IPNet `json:"ip_net"` - Note string `json:"note"` + Action string `json:"action"` // allow、deny + Val string `json:"val"` + Port interface{} `json:"port"` + Ports map[uint16]int8 `json:"ports"` + IpNet *net.IPNet `json:"ip_net"` + Note string `json:"note"` } type ValData struct { @@ -170,13 +171,21 @@ func SetGroup(g *Group) error { return errors.New("GroupLinkAcl 错误" + err.Error()) } v.IpNet = ipNet - if regexp.MustCompile(`^\d{1,5}(-\d{1,5})?(,\d{1,5}(-\d{1,5})?)*$`).MatchString(v.PortStr) { - ports := []PortData{} - for _, p := range strings.Split(v.PortStr, ",") { + + port:=""; + //base.Debug("v.port:",v.Port,v.Ports,reflect.TypeOf(v.Port).Name()) + switch v := v.Port.(type) { + case float64: + port = strconv.Itoa(int(v)) + case string: + port = v + } + if regexp.MustCompile(`^\d{1,5}(-\d{1,5})?(,\d{1,5}(-\d{1,5})?)*$`).MatchString(port) { + ports := map[uint16]int8{} + for _, p := range strings.Split(port, ",") { if p == "" { continue } - portData :=PortData{PortFrom: 0, PortTo: 0} if regexp.MustCompile(`^\d{1,5}-\d{1,5}$`).MatchString(p) { rp := strings.Split(p, "-"); portfrom, err := strconv.Atoi(rp[0]) @@ -187,23 +196,22 @@ func SetGroup(g *Group) error { if err != nil { return errors.New("端口:"+rp[1]+" 格式错误, " + err.Error()) } - portData.PortFrom=uint16(portfrom) - portData.PortTo=uint16(portto) + for i := portfrom; i <= portto; i++ { + ports[uint16(i)] = 1 + } + } else { port, err := strconv.Atoi(p) if err != nil { return errors.New("端口:"+p+" 格式错误, " + err.Error()) } - portData.PortFrom=uint16(port) - portData.PortTo=uint16(port) + ports[uint16(port)] = 1 } - - ports = append(ports, portData) } v.Ports = ports linkAcl = append(linkAcl, v) } else { - return errors.New("端口: "+v.PortStr+" 格式错误,请用逗号分隔的端口,比如: 22,80,443 连续端口用-,比如:1234-5678") + return errors.New("端口: "+port+" 格式错误,请用逗号分隔的端口,比如: 22,80,443 连续端口用-,比如:1234-5678") } } @@ -283,13 +291,13 @@ func SetGroup(g *Group) error { return err } -func ContainsInPorts(ports []PortData, port uint16) bool { - for _, p := range ports { - if p.PortFrom<=port && p.PortTo >= port { - return true - } +func ContainsInPorts(ports map[uint16]int8, port uint16) bool { + _, ok := ports[port] + if ok { + return true + } else { + return false } - return false } func GroupAuthLogin(name, pwd string, authData map[string]interface{}) error { diff --git a/server/handler/payload.go b/server/handler/payload.go index 590f272..f4613be 100644 --- a/server/handler/payload.go +++ b/server/handler/payload.go @@ -89,11 +89,21 @@ func checkLinkAcl(group *dbdata.Group, pl *sessdata.Payload) bool { // 循环判断ip和端口 if v.IpNet.Contains(ipDst) { // 放行允许ip的ping - if dbdata.ContainsInPorts( v.Ports , ipPort) || v.Ports[0].PortFrom == 0 || ipProto == waterutil.ICMP { - if v.Action == dbdata.Allow { - return true - } else { - return false + if(v.Ports==nil || len(v.Ports)==0){ + if v.Port==ipPort || v.Port==0 || ipProto == waterutil.ICMP { + if v.Action == dbdata.Allow { + return true + } else { + return false + } + } + } else { + if dbdata.ContainsInPorts( v.Ports , ipPort) || dbdata.ContainsInPorts( v.Ports , 0) || ipProto == waterutil.ICMP { + if v.Action == dbdata.Allow { + return true + } else { + return false + } } } } diff --git a/web/src/pages/group/List.vue b/web/src/pages/group/List.vue index 0f20d5b..df4f2ce 100644 --- a/web/src/pages/group/List.vue +++ b/web/src/pages/group/List.vue @@ -100,12 +100,12 @@ min-width="180">