Files
nezha_domains/service/rpc/geoip_rpc.go
T
2026-07-20 04:26:19 +00:00

58 lines
2.1 KiB
Go

package rpc
import (
"context"
"fmt"
"log"
"net"
"github.com/nezhahq/nezha/model"
geoipx "github.com/nezhahq/nezha/pkg/geoip"
pb "github.com/nezhahq/nezha/proto"
"github.com/nezhahq/nezha/service/singleton"
)
func (s *NezhaHandler) ReportGeoIP(ctx context.Context, report *pb.GeoIP) (*pb.GeoIP, error) {
clientID, err := s.Auth.Check(ctx)
if err != nil {
return nil, err
}
geoIP := model.PB2GeoIP(report)
if geoIP.IP.IPv4Addr == "" && geoIP.IP.IPv6Addr == "" {
ip, _ := ctx.Value(model.CtxKeyRealIP{}).(string)
if ip == "" {
ip, _ = ctx.Value(model.CtxKeyConnectingIP{}).(string)
}
geoIP.IP.IPv4Addr = ip
}
joinedIP := geoIP.IP.Join()
server, ok := singleton.ServerShared.Get(clientID)
if !ok || server == nil {
return nil, fmt.Errorf("server not found")
}
if server.EnableDDNS && joinedIP != "" && (server.GeoIP == nil || server.GeoIP.IP != geoIP.IP) {
if err := singleton.ServerShared.UpdateDDNS(server, &model.IP{IPv4Addr: geoIP.IP.IPv4Addr, IPv6Addr: geoIP.IP.IPv6Addr}); err != nil {
log.Printf("NEZHA>> Failed to update DDNS for server %d: %v", server.ID, err)
}
}
if server.GeoIP != nil && singleton.Conf.EnableIPChangeNotification &&
((singleton.Conf.Cover == model.ConfigCoverAll && !singleton.Conf.IgnoredIPNotificationServerIDs[clientID]) ||
(singleton.Conf.Cover == model.ConfigCoverIgnoreAll && singleton.Conf.IgnoredIPNotificationServerIDs[clientID])) &&
server.GeoIP.IP.Join() != "" && joinedIP != "" && server.GeoIP.IP != geoIP.IP {
singleton.NotificationShared.SendNotification(singleton.Conf.IPChangeNotificationGroupID,
fmt.Sprintf("[%s] %s, %s => %s", singleton.Localizer.T("IP Changed"), server.Name,
singleton.IPDesensitize(server.GeoIP.IP.Join()), singleton.IPDesensitize(joinedIP)), "")
}
ip := geoIP.IP.IPv4Addr
if geoIP.IP.IPv6Addr != "" && (report.GetUse6() || ip == "") {
ip = geoIP.IP.IPv6Addr
}
location, err := geoipx.Lookup(net.ParseIP(ip))
if err != nil {
log.Printf("NEZHA>> geoip.Lookup: %v", err)
}
geoIP.CountryCode = location
server.GeoIP = &geoIP
return &pb.GeoIP{Ip: nil, CountryCode: location, DashboardBootTime: singleton.DashboardBootTime}, nil
}