Przeglądaj źródła

some changes

ip limit method back to v1.6.0 method
remove event on getDBClientIps
better show ip on log (",\n")
MHSanaei 1 rok temu
rodzic
commit
fdc1124ea4

+ 1 - 0
web/html/xui/client_bulk_modal.html

@@ -57,6 +57,7 @@
             </span>
             <a-input v-model.trim="clientsBulkModal.tgId"></a-input>
         </a-form-item>
+        <br>
         <a-form-item>
             <span slot="label">
                 <span>{{ i18n "pages.inbounds.IPLimit" }}</span>

+ 15 - 14
web/html/xui/client_modal.html

@@ -120,26 +120,27 @@
             },
         },
         methods: {
-            async getDBClientIps(email, event) {
-                const msg = await HttpUtil.post('/panel/inbound/clientIps/' + email);
-                if (!msg.success) {
-                    return;
-                }
+            async getDBClientIps(email) {
                 try {
-                    ips = JSON.parse(msg.obj)
-                    ips = ips.join(",")
-                    event.target.value = ips
+                    const msg = await HttpUtil.post(`/panel/inbound/clientIps/${email}`);
+                    if (!msg.success) {
+                        return;
+                    }
+                    const ips = JSON.parse(msg.obj).join(",\n");
+                    document.getElementById("clientIPs").value = ips;
                 } catch (error) {
-                    // text
-                    event.target.value = msg.obj
+                    document.getElementById("clientIPs").value = msg.obj;
                 }
             },
             async clearDBClientIps(email) {
-                const msg = await HttpUtil.post('/panel/inbound/clearClientIps/' + email);
-                if (!msg.success) {
-                    return;
+                try {
+                    const msg = await HttpUtil.post(`/panel/inbound/clearClientIps/${email}`);
+                    if (!msg.success) {
+                        return;
+                    }
+                    document.getElementById("clientIPs").value = "";
+                } catch (error) {
                 }
-                document.getElementById("clientIPs").value = ""
             },
             resetClientTraffic(email, dbInboundId, iconElement) {
                 this.$confirm({

+ 26 - 25
web/html/xui/form/client.html

@@ -72,31 +72,32 @@
 		<a-input-number v-model="client.limitIp" min="0"></a-input-number>
 	</a-form-item>
 	<a-form-item v-if="client.email && client.limitIp > 0 && isEdit">
-		<span slot="label">
-			<span>{{ i18n "pages.inbounds.IPLimitlog" }}</span>
-			<a-tooltip>
-				<template slot="title">
-				<span>{{ i18n "pages.inbounds.IPLimitlogDesc" }}</span>
-				</template>
-				<a-icon type="question-circle" theme="filled"></a-icon>
-			</a-tooltip>
-			<a-tooltip>
-				<template slot="title">
-				<span>{{ i18n "pages.inbounds.IPLimitlogclear" }}</span>
-				</template>
-				<span style="color: #FF4D4F">
-				<a-icon type="delete" @click="clearDBClientIps(client.email)"></a-icon>
-				</span>
-			</a-tooltip>
-		</span>
-		<a-form layout="block">
-			<a-textarea id="clientIPs" readonly 
-                        @click="getDBClientIps(client.email,$event)"
-                        placeholder="Click To Get IPs"
-                        :auto-size="{ minRows: 2, maxRows: 10 }">
-			</a-textarea>
-		</a-form>
-	</a-form-item>
+        <span slot="label">
+          <span>{{ i18n "pages.inbounds.IPLimitlog" }}</span>
+          <a-tooltip>
+            <template slot="title">
+              <span>{{ i18n "pages.inbounds.IPLimitlogDesc" }}</span>
+            </template>
+            <a-icon type="question-circle" theme="filled"></a-icon>
+          </a-tooltip>
+          <a-tooltip>
+            <template slot="title">
+              <span>{{ i18n "pages.inbounds.IPLimitlogclear" }}</span>
+            </template>
+            <span style="color: #FF4D4F">
+              <a-icon type="delete" @click="clearDBClientIps(client.email)"></a-icon>
+            </span>
+          </a-tooltip>
+        </span>
+        <a-form layout="block">
+          <a-textarea id="clientIPs" readonly 
+            @click="getDBClientIps(client.email)"
+            placeholder="Click To Get IPs"
+            :auto-size="{ minRows: 5, maxRows: 10 }"
+          >
+          </a-textarea>
+        </a-form>
+    </a-form-item>
     <br>
     <a-form-item v-if="inbound.xtls" label="Flow">
         <a-select v-model="client.flow" style="width: 200px" :dropdown-class-name="themeSwitcher.darkCardClass">

+ 4 - 3
web/html/xui/form/inbound.html

@@ -1,12 +1,13 @@
 {{define "form/inbound"}}
 <!-- base -->
 <a-form layout="inline">
-    <a-form-item label='{{ i18n "remark" }}'>
-        <a-input v-model.trim="dbInbound.remark"></a-input>
-    </a-form-item>
     <a-form-item label='{{ i18n "enable" }}'>
         <a-switch v-model="dbInbound.enable"></a-switch>
     </a-form-item>
+    <br>
+    <a-form-item label='{{ i18n "remark" }}'>
+        <a-input v-model.trim="dbInbound.remark"></a-input>
+    </a-form-item>
     <a-form-item label='{{ i18n "protocol" }}'>
         <a-select v-model="inbound.protocol" style="width: 160px;" :disabled="isEdit" :dropdown-class-name="themeSwitcher.darkCardClass">
             <a-select-option v-for="p in Protocols" :key="p" :value="p">[[ p ]]</a-select-option>

+ 37 - 57
web/job/check_client_ip_job.go

@@ -4,7 +4,6 @@ import (
 	"encoding/json"
 	"os"
 	"regexp"
-	"sync"
 	"x-ui/database"
 	"x-ui/database/model"
 	"x-ui/logger"
@@ -21,38 +20,33 @@ import (
 
 type CheckClientIpJob struct {
 	xrayService service.XrayService
-	AllowedIps  []string
-	mutex       sync.Mutex
 }
 
 var job *CheckClientIpJob
-var AllowedIps []string
-var ipRegx *regexp.Regexp = regexp.MustCompile(`[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+`)
-var emailRegx *regexp.Regexp = regexp.MustCompile(`email:.+`)
+var disAllowedIps []string
 
 func NewCheckClientIpJob() *CheckClientIpJob {
-	job := &CheckClientIpJob{}
+	job = new(CheckClientIpJob)
 	return job
 }
 
 func (j *CheckClientIpJob) Run() {
 	logger.Debug("Check Client IP Job...")
-	j.processLogFile()
+	processLogFile()
 
-	// AllowedIps = []string{"192.168.1.183","192.168.1.197"}
-	allowedIps := []byte(strings.Join(j.getAllowedIps(), ","))
+	blockedIps := []byte(strings.Join(disAllowedIps, ","))
 
 	// check if file exists, if not create one
-	_, err := os.Stat(xray.GetAllowedIPsPath())
+	_, err := os.Stat(xray.GetBlockedIPsPath())
 	if os.IsNotExist(err) {
-		_, err = os.OpenFile(xray.GetAllowedIPsPath(), os.O_RDWR|os.O_CREATE, 0755)
+		_, err = os.OpenFile(xray.GetBlockedIPsPath(), os.O_RDWR|os.O_CREATE, 0755)
 		checkError(err)
 	}
-	err = os.WriteFile(xray.GetAllowedIPsPath(), allowedIps, 0755)
+	err = os.WriteFile(xray.GetBlockedIPsPath(), blockedIps, 0755)
 	checkError(err)
 }
 
-func (j *CheckClientIpJob) processLogFile() {
+func processLogFile() {
 	accessLogPath := GetAccessLogPath()
 	if accessLogPath == "" {
 		logger.Warning("access.log doesn't exist in your config.json")
@@ -70,6 +64,8 @@ func (j *CheckClientIpJob) processLogFile() {
 
 	lines := strings.Split(string(data), "\n")
 	for _, line := range lines {
+		ipRegx, _ := regexp.Compile(`[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+`)
+		emailRegx, _ := regexp.Compile(`email:.+`)
 
 		matchesIp := ipRegx.FindString(line)
 		if len(matchesIp) > 0 {
@@ -84,13 +80,19 @@ func (j *CheckClientIpJob) processLogFile() {
 			}
 			matchesEmail = strings.TrimSpace(strings.Split(matchesEmail, "email: ")[1])
 
-			if !contains(InboundClientIps[matchesEmail], ip) {
+			if InboundClientIps[matchesEmail] != nil {
+				if contains(InboundClientIps[matchesEmail], ip) {
+					continue
+				}
+				InboundClientIps[matchesEmail] = append(InboundClientIps[matchesEmail], ip)
+
+			} else {
 				InboundClientIps[matchesEmail] = append(InboundClientIps[matchesEmail], ip)
 			}
 		}
 
 	}
-	j.setAllowedIps([]string{})
+	disAllowedIps = []string{}
 
 	for clientEmail, ips := range InboundClientIps {
 		inboundClientIps, err := GetInboundClientIps(clientEmail)
@@ -99,7 +101,7 @@ func (j *CheckClientIpJob) processLogFile() {
 			addInboundClientIps(clientEmail, ips)
 
 		} else {
-			j.updateInboundClientIps(inboundClientIps, clientEmail, ips)
+			updateInboundClientIps(inboundClientIps, clientEmail, ips)
 		}
 
 	}
@@ -112,7 +114,6 @@ func (j *CheckClientIpJob) processLogFile() {
 	stop <- true
 
 }
-
 func GetAccessLogPath() string {
 
 	config, err := os.ReadFile(xray.GetConfigPath())
@@ -133,22 +134,20 @@ func GetAccessLogPath() string {
 	return ""
 
 }
-
 func checkError(e error) {
 	if e != nil {
 		logger.Warning("client ip job err:", e)
 	}
 }
-
 func contains(s []string, str string) bool {
 	for _, v := range s {
 		if v == str {
 			return true
 		}
 	}
+
 	return false
 }
-
 func GetInboundClientIps(clientEmail string) (*model.InboundClientIps, error) {
 	db := database.GetDB()
 	InboundClientIps := &model.InboundClientIps{}
@@ -158,7 +157,6 @@ func GetInboundClientIps(clientEmail string) (*model.InboundClientIps, error) {
 	}
 	return InboundClientIps, nil
 }
-
 func addInboundClientIps(clientEmail string, ips []string) error {
 	inboundClientIps := &model.InboundClientIps{}
 	jsonIps, err := json.Marshal(ips)
@@ -171,10 +169,10 @@ func addInboundClientIps(clientEmail string, ips []string) error {
 	tx := db.Begin()
 
 	defer func() {
-		if r := recover(); r != nil {
-			tx.Rollback()
-		} else {
+		if err == nil {
 			tx.Commit()
+		} else {
+			tx.Rollback()
 		}
 	}()
 
@@ -184,7 +182,13 @@ func addInboundClientIps(clientEmail string, ips []string) error {
 	}
 	return nil
 }
-func (j *CheckClientIpJob) updateInboundClientIps(inboundClientIps *model.InboundClientIps, clientEmail string, ips []string) error {
+func updateInboundClientIps(inboundClientIps *model.InboundClientIps, clientEmail string, ips []string) error {
+
+	jsonIps, err := json.Marshal(ips)
+	checkError(err)
+
+	inboundClientIps.ClientEmail = clientEmail
+	inboundClientIps.Ips = string(jsonIps)
 
 	// check inbound limitation
 	inbound, err := GetInboundByEmail(clientEmail)
@@ -201,22 +205,17 @@ func (j *CheckClientIpJob) updateInboundClientIps(inboundClientIps *model.Inboun
 
 	for _, client := range clients {
 		if client.Email == clientEmail {
+
 			limitIp := client.LimitIP
+
 			if limitIp < len(ips) && limitIp != 0 && inbound.Enable {
-				for _, ip := range ips[:limitIp] {
-					j.addAllowedIp(ip)
-				}
+
+				disAllowedIps = append(disAllowedIps, ips[limitIp:]...)
 			}
 		}
 	}
-
-	jsonIps, err := json.Marshal(ips) // marshal the possibly truncated list of IPs
-	checkError(err)
-
-	inboundClientIps.ClientEmail = clientEmail
-	inboundClientIps.Ips = string(jsonIps)
-
-	logger.Debug("Allowed IPs: ", ips)
+	logger.Debug("disAllowedIps ", disAllowedIps)
+	sort.Strings(disAllowedIps)
 
 	db := database.GetDB()
 	err = db.Save(inboundClientIps).Error
@@ -225,25 +224,6 @@ func (j *CheckClientIpJob) updateInboundClientIps(inboundClientIps *model.Inboun
 	}
 	return nil
 }
-
-func (j *CheckClientIpJob) setAllowedIps(ips []string) {
-	j.mutex.Lock()
-	defer j.mutex.Unlock()
-	j.AllowedIps = ips
-}
-
-func (j *CheckClientIpJob) addAllowedIp(ip string) {
-	j.mutex.Lock()
-	defer j.mutex.Unlock()
-	j.AllowedIps = append(j.AllowedIps, ip)
-}
-
-func (j *CheckClientIpJob) getAllowedIps() []string {
-	j.mutex.Lock()
-	defer j.mutex.Unlock()
-	return j.AllowedIps
-}
-
 func DisableInbound(id int) error {
 	db := database.GetDB()
 	result := db.Model(model.Inbound{}).
@@ -297,7 +277,7 @@ func LimitDevice() {
 			srcPort = portRegx.FindString(data[1])
 			srcPort = strings.Replace(srcPort, ":", "", -1)
 
-			if contains(AllowedIps, srcIp) {
+			if contains(disAllowedIps, srcIp) {
 				dropCmd := cmd.NewCmd("bash", "-c", "ss -K dport = "+srcPort)
 				dropCmd.Start()
 

+ 3 - 3
xray/process.go

@@ -51,8 +51,8 @@ func GetIranPath() string {
 	return config.GetBinFolderPath() + "/iran.dat"
 }
 
-func GetAllowedIPsPath() string {
-	return config.GetBinFolderPath() + "/AllowedIPs"
+func GetBlockedIPsPath() string {
+	return config.GetBinFolderPath() + "/BlockedIps"
 }
 
 func stopProcess(p *Process) {
@@ -173,7 +173,7 @@ func (p *process) Start() (err error) {
 		return common.NewErrorf("Failed to write configuration file: %v", err)
 	}
 
-	cmd := exec.Command(GetBinaryPath(), "-c", configPath, "-restrictedIPsPath", GetAllowedIPsPath())
+	cmd := exec.Command(GetBinaryPath(), "-c", configPath, "-restrictedIPsPath", GetBlockedIPsPath())
 	p.cmd = cmd
 
 	stdReader, err := cmd.StdoutPipe()