Skip to content

Commit

Permalink
Extend realip parsing of GRPC peer address to handle IPv6 (#692)
Browse files Browse the repository at this point in the history
* Extend realip parsing of GRPC peer address to handle IPv6

* Remove debug fmt
  • Loading branch information
surik authored Feb 2, 2024
1 parent 220740b commit c2940ba
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 4 deletions.
4 changes: 3 additions & 1 deletion interceptors/realip/realip.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,12 @@ func getRemoteIP(ctx context.Context, trustedPeers []netip.Prefix, headers []str
return noIP
}

ip, err := netip.ParseAddr(strings.Split(pr.String(), ":")[0])
addrPort, err := netip.ParseAddrPort(pr.String())
if err != nil {
return noIP
}
ip := addrPort.Addr()

if len(trustedPeers) == 0 || !ipInNets(ip, trustedPeers) {
return ip
}
Expand Down
58 changes: 55 additions & 3 deletions interceptors/realip/realip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,22 @@ import (
var (
localnet []netip.Prefix = []netip.Prefix{
netip.MustParsePrefix("127.0.0.1/8"),
netip.MustParsePrefix("::1/128"),
}

privatenet []netip.Prefix = []netip.Prefix{
netip.MustParsePrefix("10.0.0.0/8"),
netip.MustParsePrefix("172.16.0.0/12"),
netip.MustParsePrefix("192.168.0.0/16"),
netip.MustParsePrefix("2002:c0a8::/32"),
}

privateIP netip.Addr = netip.MustParseAddr("192.168.0.1")
publicIP netip.Addr = netip.MustParseAddr("8.8.8.8")
localhost netip.Addr = netip.MustParseAddr("127.0.0.1")
privateIP netip.Addr = netip.MustParseAddr("192.168.0.1")
privateIP6 netip.Addr = netip.MustParseAddr("::ffff:c0a8:1")
publicIP netip.Addr = netip.MustParseAddr("8.8.8.8")
publicIP6 netip.Addr = netip.MustParseAddr("::ffff:808:808")
localhost netip.Addr = netip.MustParseAddr("127.0.0.1")
localhost6 netip.Addr = netip.MustParseAddr("::1")
)

func localhostPeer() *peer.Peer {
Expand All @@ -40,6 +45,14 @@ func localhostPeer() *peer.Peer {
}
}

func localhost6Peer() *peer.Peer {
return &peer.Peer{
Addr: &net.TCPAddr{
IP: net.ParseIP(localhost6.String()),
},
}
}

func publicPeer() *peer.Peer {
return &peer.Peer{
Addr: &net.TCPAddr{
Expand All @@ -56,6 +69,14 @@ func privatePeer() *peer.Peer {
}
}

func private6Peer() *peer.Peer {
return &peer.Peer{
Addr: &net.TCPAddr{
IP: net.ParseIP(privateIP6.String()),
},
}
}

type testCase struct {
trustedPeers []netip.Prefix
headerKeys []string
Expand Down Expand Up @@ -331,6 +352,37 @@ func TestInterceptor(t *testing.T) {
testStreamServerInterceptor(t, tc)
})
})
t.Run("ipv6 from grpc peer", func(t *testing.T) {
tc := testCase{
trustedPeers: localnet,
headerKeys: []string{},
peer: localhost6Peer(),
expectedIP: localhost6,
}
t.Run("unary", func(t *testing.T) {
testUnaryServerInterceptor(t, tc)
})
t.Run("stream", func(t *testing.T) {
testStreamServerInterceptor(t, tc)
})
})
t.Run("ipv6 from header", func(t *testing.T) {
tc := testCase{
trustedPeers: privatenet,
headerKeys: []string{XForwardedFor},
inputHeaders: map[string]string{
XForwardedFor: publicIP6.String(),
},
peer: private6Peer(),
expectedIP: publicIP6,
}
t.Run("unary", func(t *testing.T) {
testUnaryServerInterceptor(t, tc)
})
t.Run("stream", func(t *testing.T) {
testStreamServerInterceptor(t, tc)
})
})
t.Run("unix", func(t *testing.T) {
tc := testCase{
trustedPeers: localnet,
Expand Down

0 comments on commit c2940ba

Please sign in to comment.