Skip to content

Commit c2940ba

Browse files
authored
Extend realip parsing of GRPC peer address to handle IPv6 (#692)
* Extend realip parsing of GRPC peer address to handle IPv6 * Remove debug fmt
1 parent 220740b commit c2940ba

File tree

2 files changed

+58
-4
lines changed

2 files changed

+58
-4
lines changed

interceptors/realip/realip.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,12 @@ func getRemoteIP(ctx context.Context, trustedPeers []netip.Prefix, headers []str
8383
return noIP
8484
}
8585

86-
ip, err := netip.ParseAddr(strings.Split(pr.String(), ":")[0])
86+
addrPort, err := netip.ParseAddrPort(pr.String())
8787
if err != nil {
8888
return noIP
8989
}
90+
ip := addrPort.Addr()
91+
9092
if len(trustedPeers) == 0 || !ipInNets(ip, trustedPeers) {
9193
return ip
9294
}

interceptors/realip/realip_test.go

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,22 @@ import (
1919
var (
2020
localnet []netip.Prefix = []netip.Prefix{
2121
netip.MustParsePrefix("127.0.0.1/8"),
22+
netip.MustParsePrefix("::1/128"),
2223
}
2324

2425
privatenet []netip.Prefix = []netip.Prefix{
2526
netip.MustParsePrefix("10.0.0.0/8"),
2627
netip.MustParsePrefix("172.16.0.0/12"),
2728
netip.MustParsePrefix("192.168.0.0/16"),
29+
netip.MustParsePrefix("2002:c0a8::/32"),
2830
}
2931

30-
privateIP netip.Addr = netip.MustParseAddr("192.168.0.1")
31-
publicIP netip.Addr = netip.MustParseAddr("8.8.8.8")
32-
localhost netip.Addr = netip.MustParseAddr("127.0.0.1")
32+
privateIP netip.Addr = netip.MustParseAddr("192.168.0.1")
33+
privateIP6 netip.Addr = netip.MustParseAddr("::ffff:c0a8:1")
34+
publicIP netip.Addr = netip.MustParseAddr("8.8.8.8")
35+
publicIP6 netip.Addr = netip.MustParseAddr("::ffff:808:808")
36+
localhost netip.Addr = netip.MustParseAddr("127.0.0.1")
37+
localhost6 netip.Addr = netip.MustParseAddr("::1")
3338
)
3439

3540
func localhostPeer() *peer.Peer {
@@ -40,6 +45,14 @@ func localhostPeer() *peer.Peer {
4045
}
4146
}
4247

48+
func localhost6Peer() *peer.Peer {
49+
return &peer.Peer{
50+
Addr: &net.TCPAddr{
51+
IP: net.ParseIP(localhost6.String()),
52+
},
53+
}
54+
}
55+
4356
func publicPeer() *peer.Peer {
4457
return &peer.Peer{
4558
Addr: &net.TCPAddr{
@@ -56,6 +69,14 @@ func privatePeer() *peer.Peer {
5669
}
5770
}
5871

72+
func private6Peer() *peer.Peer {
73+
return &peer.Peer{
74+
Addr: &net.TCPAddr{
75+
IP: net.ParseIP(privateIP6.String()),
76+
},
77+
}
78+
}
79+
5980
type testCase struct {
6081
trustedPeers []netip.Prefix
6182
headerKeys []string
@@ -331,6 +352,37 @@ func TestInterceptor(t *testing.T) {
331352
testStreamServerInterceptor(t, tc)
332353
})
333354
})
355+
t.Run("ipv6 from grpc peer", func(t *testing.T) {
356+
tc := testCase{
357+
trustedPeers: localnet,
358+
headerKeys: []string{},
359+
peer: localhost6Peer(),
360+
expectedIP: localhost6,
361+
}
362+
t.Run("unary", func(t *testing.T) {
363+
testUnaryServerInterceptor(t, tc)
364+
})
365+
t.Run("stream", func(t *testing.T) {
366+
testStreamServerInterceptor(t, tc)
367+
})
368+
})
369+
t.Run("ipv6 from header", func(t *testing.T) {
370+
tc := testCase{
371+
trustedPeers: privatenet,
372+
headerKeys: []string{XForwardedFor},
373+
inputHeaders: map[string]string{
374+
XForwardedFor: publicIP6.String(),
375+
},
376+
peer: private6Peer(),
377+
expectedIP: publicIP6,
378+
}
379+
t.Run("unary", func(t *testing.T) {
380+
testUnaryServerInterceptor(t, tc)
381+
})
382+
t.Run("stream", func(t *testing.T) {
383+
testStreamServerInterceptor(t, tc)
384+
})
385+
})
334386
t.Run("unix", func(t *testing.T) {
335387
tc := testCase{
336388
trustedPeers: localnet,

0 commit comments

Comments
 (0)