github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/pkg/util/net/firewall_dialer_test.go (about)

     1  package net
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net"
     7  	"strings"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/grafana/dskit/flagext"
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  func TestFirewallDialer(t *testing.T) {
    17  	blockedCIDR := flagext.CIDR{}
    18  	require.NoError(t, blockedCIDR.Set("172.217.168.64/28"))
    19  
    20  	type testCase struct {
    21  		address       string
    22  		expectBlocked bool
    23  	}
    24  
    25  	tests := map[string]struct {
    26  		cfg   FirewallDialerConfigProvider
    27  		cases []testCase
    28  	}{
    29  		"should not block traffic with no block config": {
    30  			cfg: firewallCfgProvider{},
    31  			cases: []testCase{
    32  				{"localhost", false},
    33  				{"127.0.0.1", false},
    34  				{"google.com", false},
    35  				{"172.217.168.78", false},
    36  			},
    37  		},
    38  		"should support blocking private addresses": {
    39  			cfg: firewallCfgProvider{
    40  				blockPrivateAddresses: true,
    41  			},
    42  			cases: []testCase{
    43  				{"localhost", true},
    44  				{"127.0.0.1", true},
    45  				{"192.168.0.1", true},
    46  				{"10.0.0.1", true},
    47  				{"google.com", false},
    48  				{"172.217.168.78", false},
    49  				{"fdf8:f53b:82e4::53", true},       // Local
    50  				{"fe80::200:5aee:feaa:20a2", true}, // Link-local
    51  				{"2001:4860:4860::8844", false},    // Google DNS
    52  				{"::ffff:172.217.168.78", false},   // IPv6 mapped v4 non-private
    53  				{"::ffff:192.168.0.1", true},       // IPv6 mapped v4 private
    54  			},
    55  		},
    56  		"should support blocking custom CIDRs": {
    57  			cfg: firewallCfgProvider{
    58  				blockCIDRNetworks: []flagext.CIDR{blockedCIDR},
    59  			},
    60  			cases: []testCase{
    61  				{"localhost", false},
    62  				{"127.0.0.1", false},
    63  				{"192.168.0.1", false},
    64  				{"10.0.0.1", false},
    65  				{"172.217.168.78", true},
    66  				{"fdf8:f53b:82e4::53", false},       // Local
    67  				{"fe80::200:5aee:feaa:20a2", false}, // Link-local
    68  				{"2001:4860:4860::8844", false},     // Google DNS
    69  				{"::ffff:10.0.0.1", false},          // IPv6 mapped v4 non-blocked
    70  				{"::ffff:172.217.168.78", true},     // IPv6 mapped v4 blocked
    71  			},
    72  		},
    73  	}
    74  
    75  	for testName, testData := range tests {
    76  		t.Run(testName, func(t *testing.T) {
    77  			d := NewFirewallDialer(testData.cfg)
    78  
    79  			for _, tc := range testData.cases {
    80  				t.Run(fmt.Sprintf("address: %s", tc.address), func(t *testing.T) {
    81  					ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
    82  					defer cancel()
    83  
    84  					conn, err := d.DialContext(ctx, "tcp", fmt.Sprintf("[%s]:80", tc.address))
    85  					if conn != nil {
    86  						require.NoError(t, conn.Close())
    87  					}
    88  
    89  					if tc.expectBlocked {
    90  						assert.Error(t, err, errBlockedAddress.Error())
    91  						assert.Contains(t, err.Error(), errBlockedAddress.Error())
    92  					} else {
    93  						// We're fine either if succeeded or triggered a different error (eg. connection refused).
    94  						assert.True(t, err == nil || !strings.Contains(err.Error(), errBlockedAddress.Error()))
    95  					}
    96  				})
    97  			}
    98  		})
    99  	}
   100  }
   101  
   102  func TestIsPrivate(t *testing.T) {
   103  	tests := []struct {
   104  		ip       net.IP
   105  		expected bool
   106  	}{
   107  		{nil, false},
   108  		{net.IPv4(1, 1, 1, 1), false},
   109  		{net.IPv4(9, 255, 255, 255), false},
   110  		{net.IPv4(10, 0, 0, 0), true},
   111  		{net.IPv4(10, 255, 255, 255), true},
   112  		{net.IPv4(11, 0, 0, 0), false},
   113  		{net.IPv4(172, 15, 255, 255), false},
   114  		{net.IPv4(172, 16, 0, 0), true},
   115  		{net.IPv4(172, 16, 255, 255), true},
   116  		{net.IPv4(172, 23, 18, 255), true},
   117  		{net.IPv4(172, 31, 255, 255), true},
   118  		{net.IPv4(172, 31, 0, 0), true},
   119  		{net.IPv4(172, 32, 0, 0), false},
   120  		{net.IPv4(192, 167, 255, 255), false},
   121  		{net.IPv4(192, 168, 0, 0), true},
   122  		{net.IPv4(192, 168, 255, 255), true},
   123  		{net.IPv4(192, 169, 0, 0), false},
   124  		{net.IP{0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, true},
   125  		{net.IP{0xfc, 0xff, 0x12, 0, 0, 0, 0, 0x44, 0, 0, 0, 0, 0, 0, 0, 0}, true},
   126  		{net.IP{0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, false},
   127  		{net.IP{0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, true},
   128  		{net.IP{0xfe, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
   129  	}
   130  
   131  	for _, test := range tests {
   132  		assert.Equalf(t, test.expected, isPrivate(test.ip), "ip: %s", test.ip.String())
   133  	}
   134  }
   135  
   136  type firewallCfgProvider struct {
   137  	blockCIDRNetworks     []flagext.CIDR
   138  	blockPrivateAddresses bool
   139  }
   140  
   141  func (p firewallCfgProvider) BlockCIDRNetworks() []flagext.CIDR {
   142  	return p.blockCIDRNetworks
   143  }
   144  
   145  func (p firewallCfgProvider) BlockPrivateAddresses() bool {
   146  	return p.blockPrivateAddresses
   147  }