mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-02-04 04:30:05 +00:00
Merge branch 'dev' of github.com:naiba/nezha-v1 into dev
This commit is contained in:
@@ -4,11 +4,12 @@ import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
petname "github.com/dustinkirkland/golang-petname"
|
||||
"github.com/hashicorp/go-uuid"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"github.com/hashicorp/go-uuid"
|
||||
"github.com/naiba/nezha/model"
|
||||
"github.com/naiba/nezha/service/singleton"
|
||||
)
|
||||
@@ -30,7 +31,7 @@ func (a *authHandler) Check(ctx context.Context) (uint64, error) {
|
||||
}
|
||||
|
||||
if clientSecret != singleton.Conf.AgentSecretKey {
|
||||
return 0, status.Errorf(codes.Unauthenticated, "客户端认证失败")
|
||||
return 0, status.Error(codes.Unauthenticated, "客户端认证失败")
|
||||
}
|
||||
|
||||
var clientUUID string
|
||||
@@ -39,22 +40,25 @@ func (a *authHandler) Check(ctx context.Context) (uint64, error) {
|
||||
}
|
||||
|
||||
if _, err := uuid.ParseUUID(clientUUID); err != nil {
|
||||
return 0, status.Errorf(codes.Unauthenticated, "客户端 UUID 不合法")
|
||||
return 0, status.Error(codes.Unauthenticated, "客户端 UUID 不合法")
|
||||
}
|
||||
|
||||
singleton.ServerLock.RLock()
|
||||
defer singleton.ServerLock.RUnlock()
|
||||
|
||||
clientID, hasID := singleton.ServerUUIDToID[clientUUID]
|
||||
if !hasID {
|
||||
s := model.Server{UUID: clientUUID}
|
||||
s := model.Server{UUID: clientUUID, Name: petname.Generate(2, "-")}
|
||||
if err := singleton.DB.Create(&s).Error; err != nil {
|
||||
return 0, status.Errorf(codes.Unauthenticated, err.Error())
|
||||
return 0, status.Error(codes.Unauthenticated, err.Error())
|
||||
}
|
||||
s.Host = &model.Host{}
|
||||
s.State = &model.HostState{}
|
||||
s.TaskCloseLock = new(sync.Mutex)
|
||||
// generate a random silly server name
|
||||
singleton.ServerList[s.ID] = &s
|
||||
singleton.ServerUUIDToID[clientUUID] = s.ID
|
||||
singleton.ReSortServer()
|
||||
clientID = s.ID
|
||||
}
|
||||
|
||||
|
||||
@@ -9,9 +9,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/naiba/nezha/pkg/ddns"
|
||||
"github.com/naiba/nezha/pkg/geoip"
|
||||
geoipx "github.com/naiba/nezha/pkg/geoip"
|
||||
"github.com/naiba/nezha/pkg/grpcx"
|
||||
"github.com/naiba/nezha/pkg/utils"
|
||||
|
||||
"github.com/jinzhu/copier"
|
||||
|
||||
@@ -126,40 +125,6 @@ func (s *NezhaHandler) ReportSystemInfo(c context.Context, r *pb.Host) (*pb.Rece
|
||||
singleton.ServerLock.RLock()
|
||||
defer singleton.ServerLock.RUnlock()
|
||||
|
||||
// 检查并更新DDNS
|
||||
if singleton.ServerList[clientID].EnableDDNS && host.IP != "" &&
|
||||
(singleton.ServerList[clientID].Host == nil || singleton.ServerList[clientID].Host.IP != host.IP) {
|
||||
ipv4, ipv6, _ := utils.SplitIPAddr(host.IP)
|
||||
providers, err := singleton.GetDDNSProvidersFromProfiles(singleton.ServerList[clientID].DDNSProfiles, &ddns.IP{Ipv4Addr: ipv4, Ipv6Addr: ipv6})
|
||||
if err == nil {
|
||||
for _, provider := range providers {
|
||||
go func(provider *ddns.Provider) {
|
||||
provider.UpdateDomain(context.Background())
|
||||
}(provider)
|
||||
}
|
||||
} else {
|
||||
log.Printf("NEZHA>> 获取DDNS配置时发生错误: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// 发送IP变动通知
|
||||
if singleton.ServerList[clientID].Host != nil && singleton.Conf.EnableIPChangeNotification &&
|
||||
((singleton.Conf.Cover == model.ConfigCoverAll && !singleton.Conf.IgnoredIPNotificationServerIDs[clientID]) ||
|
||||
(singleton.Conf.Cover == model.ConfigCoverIgnoreAll && singleton.Conf.IgnoredIPNotificationServerIDs[clientID])) &&
|
||||
singleton.ServerList[clientID].Host.IP != "" &&
|
||||
host.IP != "" &&
|
||||
singleton.ServerList[clientID].Host.IP != host.IP {
|
||||
|
||||
singleton.SendNotification(singleton.Conf.IPChangeNotificationGroupID,
|
||||
fmt.Sprintf(
|
||||
"[%s] %s, %s => %s",
|
||||
singleton.Localizer.T("IP Changed"),
|
||||
singleton.ServerList[clientID].Name, singleton.IPDesensitize(singleton.ServerList[clientID].Host.IP),
|
||||
singleton.IPDesensitize(host.IP),
|
||||
),
|
||||
nil)
|
||||
}
|
||||
|
||||
/**
|
||||
* 这里的 singleton 中的数据都是关机前的旧数据
|
||||
* 当 agent 重启时,bootTime 变大,agent 端会先上报 host 信息,然后上报 state 信息
|
||||
@@ -170,11 +135,6 @@ func (s *NezhaHandler) ReportSystemInfo(c context.Context, r *pb.Host) (*pb.Rece
|
||||
singleton.ServerList[clientID].PrevTransferOutSnapshot = singleton.ServerList[clientID].PrevTransferOutSnapshot - int64(singleton.ServerList[clientID].State.NetOutTransfer)
|
||||
}
|
||||
|
||||
// 不要冲掉国家码
|
||||
if singleton.ServerList[clientID].Host != nil {
|
||||
host.CountryCode = singleton.ServerList[clientID].Host.CountryCode
|
||||
}
|
||||
|
||||
singleton.ServerList[clientID].Host = &host
|
||||
return &pb.Receipt{Proced: true}, nil
|
||||
}
|
||||
@@ -204,28 +164,73 @@ func (s *NezhaHandler) IOStream(stream pb.NezhaService_IOStreamServer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *NezhaHandler) LookupGeoIP(c context.Context, r *pb.GeoIP) (*pb.GeoIP, error) {
|
||||
func (s *NezhaHandler) ReportGeoIP(c context.Context, r *pb.GeoIP) (*pb.GeoIP, error) {
|
||||
var clientID uint64
|
||||
var err error
|
||||
if clientID, err = s.Auth.Check(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 根据内置数据库查询 IP 地理位置
|
||||
ip := r.GetIp()
|
||||
netIP := net.ParseIP(ip)
|
||||
location, err := geoip.Lookup(netIP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
geoip := model.PB2GeoIP(r)
|
||||
joinedIP := geoip.IP.Join()
|
||||
use6 := r.GetUse6()
|
||||
|
||||
singleton.ServerLock.RLock()
|
||||
// 检查并更新DDNS
|
||||
if singleton.ServerList[clientID].EnableDDNS && joinedIP != "" &&
|
||||
(singleton.ServerList[clientID].GeoIP == nil || singleton.ServerList[clientID].GeoIP.IP != geoip.IP) {
|
||||
ipv4 := geoip.IP.IPv4Addr
|
||||
ipv6 := geoip.IP.IPv6Addr
|
||||
providers, err := singleton.GetDDNSProvidersFromProfiles(singleton.ServerList[clientID].DDNSProfiles, &ddns.IP{Ipv4Addr: ipv4, Ipv6Addr: ipv6})
|
||||
if err == nil {
|
||||
for _, provider := range providers {
|
||||
go func(provider *ddns.Provider) {
|
||||
provider.UpdateDomain(context.Background())
|
||||
}(provider)
|
||||
}
|
||||
} else {
|
||||
log.Printf("NEZHA>> 获取DDNS配置时发生错误: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// 发送IP变动通知
|
||||
if singleton.ServerList[clientID].GeoIP != nil && singleton.Conf.EnableIPChangeNotification &&
|
||||
((singleton.Conf.Cover == model.ConfigCoverAll && !singleton.Conf.IgnoredIPNotificationServerIDs[clientID]) ||
|
||||
(singleton.Conf.Cover == model.ConfigCoverIgnoreAll && singleton.Conf.IgnoredIPNotificationServerIDs[clientID])) &&
|
||||
singleton.ServerList[clientID].GeoIP.IP.Join() != "" &&
|
||||
joinedIP != "" &&
|
||||
singleton.ServerList[clientID].GeoIP.IP != geoip.IP {
|
||||
|
||||
singleton.SendNotification(singleton.Conf.IPChangeNotificationGroupID,
|
||||
fmt.Sprintf(
|
||||
"[%s] %s, %s => %s",
|
||||
singleton.Localizer.T("IP Changed"),
|
||||
singleton.ServerList[clientID].Name, singleton.IPDesensitize(singleton.ServerList[clientID].GeoIP.IP.Join()),
|
||||
singleton.IPDesensitize(joinedIP),
|
||||
),
|
||||
nil)
|
||||
}
|
||||
singleton.ServerLock.RUnlock()
|
||||
|
||||
// 根据内置数据库查询 IP 地理位置
|
||||
var ip string
|
||||
if geoip.IP.IPv6Addr != "" && (use6 || geoip.IP.IPv4Addr == "") {
|
||||
ip = geoip.IP.IPv6Addr
|
||||
} else {
|
||||
ip = geoip.IP.IPv4Addr
|
||||
}
|
||||
|
||||
netIP := net.ParseIP(ip)
|
||||
location, err := geoipx.Lookup(netIP)
|
||||
if err != nil {
|
||||
log.Printf("NEZHA>> geoip.Lookup: %v", err)
|
||||
}
|
||||
geoip.CountryCode = location
|
||||
|
||||
// 将地区码写入到 Host
|
||||
singleton.ServerLock.RLock()
|
||||
defer singleton.ServerLock.RUnlock()
|
||||
if singleton.ServerList[clientID].Host == nil {
|
||||
return nil, fmt.Errorf("host not found")
|
||||
}
|
||||
singleton.ServerList[clientID].Host.CountryCode = location
|
||||
singleton.ServerLock.Lock()
|
||||
defer singleton.ServerLock.Unlock()
|
||||
singleton.ServerList[clientID].GeoIP = &geoip
|
||||
|
||||
return &pb.GeoIP{Ip: ip, CountryCode: location}, nil
|
||||
return &pb.GeoIP{Ip: nil, CountryCode: location}, err
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ func checkStatus() {
|
||||
if alert.TriggerMode == model.ModeAlwaysTrigger || alertsPrevState[alert.ID][server.ID] != _RuleCheckFail {
|
||||
alertsPrevState[alert.ID][server.ID] = _RuleCheckFail
|
||||
message := fmt.Sprintf("[%s] %s(%s) %s", Localizer.T("Incident"),
|
||||
server.Name, IPDesensitize(server.Host.IP), alert.Name)
|
||||
server.Name, IPDesensitize(server.GeoIP.IP.Join()), alert.Name)
|
||||
go SendTriggerTasks(alert.FailTriggerTasks, curServer.ID)
|
||||
go SendNotification(alert.NotificationGroupID, message, NotificationMuteLabel.ServerIncident(server.ID, alert.ID), &curServer)
|
||||
// 清除恢复通知的静音缓存
|
||||
@@ -167,7 +167,7 @@ func checkStatus() {
|
||||
// 本次通过检查但上一次的状态为失败,则发送恢复通知
|
||||
if alertsPrevState[alert.ID][server.ID] == _RuleCheckFail {
|
||||
message := fmt.Sprintf("[%s] %s(%s) %s", Localizer.T("Resolved"),
|
||||
server.Name, IPDesensitize(server.Host.IP), alert.Name)
|
||||
server.Name, IPDesensitize(server.GeoIP.IP.Join()), alert.Name)
|
||||
go SendTriggerTasks(alert.RecoverTriggerTasks, curServer.ID)
|
||||
go SendNotification(alert.NotificationGroupID, message, NotificationMuteLabel.ServerIncidentResolved(server.ID, alert.ID), &curServer)
|
||||
// 清除失败通知的静音缓存
|
||||
|
||||
@@ -68,3 +68,13 @@ func ReSortServer() {
|
||||
return SortedServerListForGuest[i].DisplayIndex > SortedServerListForGuest[j].DisplayIndex
|
||||
})
|
||||
}
|
||||
|
||||
func OnServerDelete(sid []uint64) {
|
||||
ServerLock.Lock()
|
||||
defer ServerLock.Unlock()
|
||||
for _, id := range sid {
|
||||
serverUUID := ServerList[id].UUID
|
||||
delete(ServerUUIDToID, serverUUID)
|
||||
delete(ServerList, id)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user