diff --git a/satellite/contact/endpoint.go b/satellite/contact/endpoint.go index d949cfbc2..f780e32f8 100644 --- a/satellite/contact/endpoint.go +++ b/satellite/contact/endpoint.go @@ -74,7 +74,7 @@ func (endpoint *Endpoint) CheckIn(ctx context.Context, req *pb.CheckInRequest) ( endpoint.log.Info("failed to resolve IP from address", zap.String("node address", req.Address), zap.Stringer("Node ID", nodeID), zap.Error(err)) return nil, rpcstatus.Error(rpcstatus.InvalidArgument, errCheckInNetwork.New("failed to resolve IP from address: %s, err: %v", req.Address, err).Error()) } - if !endpoint.service.allowPrivateIP && (!resolvedIP.IsGlobalUnicast() || resolvedIP.IsPrivate()) { + if !endpoint.service.allowPrivateIP && (!resolvedIP.IsGlobalUnicast() || isPrivateIP(resolvedIP)) { endpoint.log.Info("IP address not allowed", zap.String("node address", req.Address), zap.Stringer("Node ID", nodeID)) return nil, rpcstatus.Error(rpcstatus.InvalidArgument, errCheckInNetwork.New("IP address not allowed: %s", req.Address).Error()) } @@ -167,7 +167,7 @@ func (endpoint *Endpoint) PingMe(ctx context.Context, req *pb.PingMeRequest) (_ endpoint.log.Info("failed to resolve IP from address", zap.String("node address", req.Address), zap.Stringer("Node ID", nodeID), zap.Error(err)) return nil, rpcstatus.Error(rpcstatus.InvalidArgument, errCheckInNetwork.New("failed to resolve IP from address: %s, err: %v", req.Address, err).Error()) } - if !endpoint.service.allowPrivateIP && (!resolvedIP.IsGlobalUnicast() || resolvedIP.IsPrivate()) { + if !endpoint.service.allowPrivateIP && (!resolvedIP.IsGlobalUnicast() || isPrivateIP(resolvedIP)) { endpoint.log.Info("IP address not allowed", zap.String("node address", req.Address), zap.Stringer("Node ID", nodeID)) return nil, rpcstatus.Error(rpcstatus.InvalidArgument, errCheckInNetwork.New("IP address not allowed: %s", req.Address).Error()) } @@ -214,3 +214,25 @@ func (endpoint *Endpoint) checkPingRPCErr(err error, nodeURL storj.NodeURL) erro err = errCheckInNetwork.New("failed to ping node (ID: %s) at address: %s, err: %v", nodeURL.ID, nodeURL.Address, err) return rpcstatus.Error(rpcstatus.NotFound, err.Error()) } + +// isPrivateIP is copied Go 1.17's net.IP.IsPrivate. We copied it to ensure we +// can compile for the Go version earlier than 1.17. +// +// TODO(artur): Swap isPrivateIP usages with net.IP.IsPrivate when we no longer +// need to build for earlier than Go 1.17. Keep this in sync with stdlib until. +func isPrivateIP(ip net.IP) bool { + if ip4 := ip.To4(); ip4 != nil { + // Following RFC 1918, Section 3. Private Address Space which says: + // The Internet Assigned Numbers Authority (IANA) has reserved the + // following three blocks of the IP address space for private internets: + // 10.0.0.0 - 10.255.255.255 (10/8 prefix) + // 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) + // 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) + return ip4[0] == 10 || + (ip4[0] == 172 && ip4[1]&0xf0 == 16) || + (ip4[0] == 192 && ip4[1] == 168) + } + // Following RFC 4193, Section 8. IANA Considerations which says: + // The IANA has assigned the FC00::/7 prefix to "Unique Local Unicast". + return len(ip) == net.IPv6len && ip[0]&0xfe == 0xfc +}