mirror of
https://github.com/alireza0/x-ui.git
synced 2026-08-28 12:22:21 +00:00
block user IPs on remove
This commit is contained in:
parent
2b3600876e
commit
a770cebb20
3 changed files with 55 additions and 1 deletions
|
|
@ -613,9 +613,11 @@ func (s *InboundService) DelInboundClient(inboundId int, clientId string) (bool,
|
|||
}
|
||||
if needApiDel && notDepleted {
|
||||
s.xrayApi.Init(p.GetAPIAddr())
|
||||
onlineIPs := s.collectClientOnlineIPs(email)
|
||||
err1 := s.xrayApi.RemoveUser(oldInbound.Tag, email)
|
||||
if err1 == nil {
|
||||
logger.Debug("Client deleted by api:", email)
|
||||
blockIPsForPort(onlineIPs, uint16(oldInbound.Port))
|
||||
needRestart = false
|
||||
} else {
|
||||
if strings.Contains(err1.Error(), fmt.Sprintf("User %s not found.", email)) {
|
||||
|
|
@ -745,9 +747,14 @@ func (s *InboundService) UpdateInboundClient(data *model.Inbound, clientId strin
|
|||
if len(oldEmail) > 0 {
|
||||
s.xrayApi.Init(p.GetAPIAddr())
|
||||
if oldClients[clientIndex].Enable {
|
||||
var onlineIPs []string
|
||||
if !clients[0].Enable {
|
||||
onlineIPs = s.collectClientOnlineIPs(oldEmail)
|
||||
}
|
||||
err1 := s.xrayApi.RemoveUser(oldInbound.Tag, oldEmail)
|
||||
if err1 == nil {
|
||||
logger.Debug("Old client deleted by api:", oldEmail)
|
||||
blockIPsForPort(onlineIPs, uint16(oldInbound.Port))
|
||||
} else {
|
||||
if strings.Contains(err1.Error(), fmt.Sprintf("User %s not found.", oldEmail)) {
|
||||
logger.Debug("User is already deleted. Nothing to do more...")
|
||||
|
|
@ -1137,6 +1144,22 @@ func (s *InboundService) disableInvalidInbounds(tx *gorm.DB) (bool, int64, error
|
|||
return needRestart, count, err
|
||||
}
|
||||
|
||||
func (s *InboundService) collectClientOnlineIPs(email string) []string {
|
||||
if ipLimitFw == nil || !ipLimitFw.Supported() {
|
||||
return nil
|
||||
}
|
||||
ipMap, err := s.xrayApi.GetUserOnlineIpList(email)
|
||||
if err != nil {
|
||||
logger.Debug("get online ip list failed for ", email, ": ", err)
|
||||
return nil
|
||||
}
|
||||
ips := make([]string, 0, len(ipMap))
|
||||
for ip := range ipMap {
|
||||
ips = append(ips, ip)
|
||||
}
|
||||
return ips
|
||||
}
|
||||
|
||||
func (s *InboundService) disableInvalidClients(tx *gorm.DB) (bool, int64, error) {
|
||||
now := time.Now().Unix() * 1000
|
||||
needRestart := false
|
||||
|
|
@ -1144,11 +1167,12 @@ func (s *InboundService) disableInvalidClients(tx *gorm.DB) (bool, int64, error)
|
|||
if p != nil {
|
||||
var results []struct {
|
||||
Tag string
|
||||
Port int
|
||||
Email string
|
||||
}
|
||||
|
||||
err := tx.Table("inbounds").
|
||||
Select("inbounds.tag, client_traffics.email").
|
||||
Select("inbounds.tag, inbounds.port, client_traffics.email").
|
||||
Joins("JOIN client_traffics ON inbounds.id = client_traffics.inbound_id").
|
||||
Where("((client_traffics.total > 0 AND client_traffics.up + client_traffics.down >= client_traffics.total) OR (client_traffics.expiry_time > 0 AND client_traffics.expiry_time <= ?)) AND client_traffics.enable = ?", now, true).
|
||||
Scan(&results).Error
|
||||
|
|
@ -1157,9 +1181,11 @@ func (s *InboundService) disableInvalidClients(tx *gorm.DB) (bool, int64, error)
|
|||
}
|
||||
s.xrayApi.Init(p.GetAPIAddr())
|
||||
for _, result := range results {
|
||||
onlineIPs := s.collectClientOnlineIPs(result.Email)
|
||||
err1 := s.xrayApi.RemoveUser(result.Tag, result.Email)
|
||||
if err1 == nil {
|
||||
logger.Debug("Client disabled by api:", result.Email)
|
||||
blockIPsForPort(onlineIPs, uint16(result.Port))
|
||||
} else {
|
||||
if strings.Contains(err1.Error(), fmt.Sprintf("User %s not found.", result.Email)) {
|
||||
logger.Debug("User is already disabled. Nothing to do more...")
|
||||
|
|
|
|||
|
|
@ -200,6 +200,17 @@ func (s *InboundService) syncIpLimitStore(updates []IpLimitClientUpdate, removeE
|
|||
applyIpLimitMemoryChanges(updates, removeEmails)
|
||||
}
|
||||
|
||||
func blockIPsForPort(ips []string, port uint16) {
|
||||
if len(ips) == 0 || ipLimitFw == nil || !ipLimitFw.Supported() {
|
||||
return
|
||||
}
|
||||
for _, ip := range ips {
|
||||
if err := ipLimitFw.Block(iplimit.BlockKey{IP: ip, Port: port}); err != nil {
|
||||
logger.Debug("block ip failed:", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func isClientStatEnabled(inbound *model.Inbound, email string) bool {
|
||||
for _, stat := range inbound.ClientStats {
|
||||
if stat.Email == email {
|
||||
|
|
|
|||
17
xray/api.go
17
xray/api.go
|
|
@ -283,6 +283,23 @@ func (x *XrayAPI) RemoveUser(inboundTag string, email string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (x *XrayAPI) GetUserOnlineIpList(email string) (map[string]int64, error) {
|
||||
if x.StatsServiceClient == nil {
|
||||
return nil, common.NewError("xray api is not initialized")
|
||||
}
|
||||
client := *x.StatsServiceClient
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||
defer cancel()
|
||||
|
||||
resp, err := client.GetStatsOnlineIpList(ctx, &statsService.GetStatsRequest{
|
||||
Name: "user>>>" + email + ">>>online",
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.GetIps(), nil
|
||||
}
|
||||
|
||||
type OnlineUserInfo struct {
|
||||
Email string `json:"email"`
|
||||
IPs map[string]int64 `json:"ips"`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue