Skip to content

Commit 6c8d48c

Browse files
authored
feat: API interface IP whitelist supports IPv6 (#7981)
Refs #7836
1 parent b61dae6 commit 6c8d48c

File tree

3 files changed

+31
-14
lines changed

3 files changed

+31
-14
lines changed

backend/middleware/session.go

+20-9
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import (
77
"github.com/1Panel-dev/1Panel/backend/app/repo"
88
"github.com/1Panel-dev/1Panel/backend/constant"
99
"github.com/1Panel-dev/1Panel/backend/global"
10+
"github.com/1Panel-dev/1Panel/backend/utils/common"
1011
"github.com/gin-gonic/gin"
1112
"net"
1213
"strconv"
13-
"strings"
1414
"time"
1515
)
1616

@@ -102,27 +102,38 @@ func isValid1PanelToken(panelToken string, panelTimestamp string) bool {
102102

103103
func isIPInWhiteList(clientIP string) bool {
104104
ipWhiteString := global.CONF.System.IpWhiteList
105-
ipWhiteList := strings.Split(ipWhiteString, "\n")
105+
if len(ipWhiteString) == 0 {
106+
global.LOG.Error("IP whitelist is empty")
107+
return false
108+
}
109+
ipWhiteList, ipErr := common.HandleIPList(ipWhiteString)
110+
if ipErr != nil {
111+
global.LOG.Errorf("Failed to handle IP list: %v", ipErr)
112+
return false
113+
}
114+
clientParsedIP := net.ParseIP(clientIP)
115+
if clientParsedIP == nil {
116+
return false
117+
}
118+
iPv4 := clientParsedIP.To4()
119+
iPv6 := clientParsedIP.To16()
106120
for _, cidr := range ipWhiteList {
107-
if cidr == "0.0.0.0" {
121+
if (iPv4 != nil && (cidr == "0.0.0.0" || cidr == "0.0.0.0/0" || iPv4.String() == cidr)) || (iPv6 != nil && (cidr == "::/0" || iPv6.String() == cidr)) {
108122
return true
109123
}
110124
_, ipNet, err := net.ParseCIDR(cidr)
111125
if err != nil {
112-
if cidr == clientIP {
113-
return true
114-
}
115126
continue
116127
}
117-
if ipNet.Contains(net.ParseIP(clientIP)) {
128+
if (iPv4 != nil && ipNet.Contains(iPv4)) || (iPv6 != nil && ipNet.Contains(iPv6)) {
118129
return true
119130
}
120131
}
121132
return false
122133
}
123134

124-
func GenerateMD5(input string) string {
135+
func GenerateMD5(param string) string {
125136
hash := md5.New()
126-
hash.Write([]byte(input))
137+
hash.Write([]byte(param))
127138
return hex.EncodeToString(hash.Sum(nil))
128139
}

frontend/src/utils/util.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ export function checkCidrV6(value: string): boolean {
358358
if (checkIpV6(value.split('/')[0])) {
359359
return true;
360360
}
361-
const reg = /^(?:[1-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$/;
361+
const reg = /^(?:[0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$/;
362362
if (!reg.test(value.split('/')[1])) {
363363
return true;
364364
}

frontend/src/views/setting/panel/api-interface/index.vue

+10-4
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ import i18n from '@/lang';
9898
import { MsgSuccess } from '@/utils/message';
9999
import { ElMessageBox, FormInstance } from 'element-plus';
100100
import DrawerHeader from '@/components/drawer-header/index.vue';
101-
import { checkCidr, checkIp } from '@/utils/util';
101+
import { checkCidr, checkCidrV6, checkIpV4V6 } from '@/utils/util';
102102
import { GlobalStore } from '@/store';
103103
104104
const globalStore = GlobalStore();
@@ -138,10 +138,16 @@ function checkIPs(rule: any, value: any, callback: any) {
138138
continue;
139139
}
140140
if (item.indexOf('/') !== -1) {
141-
if (checkCidr(item)) {
142-
return callback(new Error(i18n.global.t('firewall.addressFormatError')));
141+
if (item.indexOf(':') !== -1) {
142+
if (checkCidrV6(item)) {
143+
return callback(new Error(i18n.global.t('firewall.addressFormatError')));
144+
}
145+
} else {
146+
if (checkCidr(item)) {
147+
return callback(new Error(i18n.global.t('firewall.addressFormatError')));
148+
}
143149
}
144-
} else if (checkIp(item)) {
150+
} else if (checkIpV4V6(item)) {
145151
return callback(new Error(i18n.global.t('firewall.addressFormatError')));
146152
}
147153
}

0 commit comments

Comments
 (0)