lncfg: allow no auth on private addresses

This commit is contained in:
yyforyongyu 2020-05-07 18:28:52 +08:00 committed by yyforyongyu
parent cfbc365c20
commit 3a3b5413b9
No known key found for this signature in database
GPG Key ID: 9BCD95C4FF296868
2 changed files with 91 additions and 3 deletions

@ -54,10 +54,10 @@ func NormalizeAddresses(addrs []string, defaultPort string,
// interface. // interface.
func EnforceSafeAuthentication(addrs []net.Addr, macaroonsActive bool) error { func EnforceSafeAuthentication(addrs []net.Addr, macaroonsActive bool) error {
// We'll now examine all addresses that this RPC server is listening // We'll now examine all addresses that this RPC server is listening
// on. If it's a localhost address, we'll skip it, otherwise, we'll // on. If it's a localhost address or a private address, we'll skip it,
// return an error if macaroons are inactive. // otherwise, we'll return an error if macaroons are inactive.
for _, addr := range addrs { for _, addr := range addrs {
if IsLoopback(addr.String()) || IsUnix(addr) { if IsLoopback(addr.String()) || IsUnix(addr) || IsPrivate(addr) {
continue continue
} }
@ -117,6 +117,39 @@ func IsUnix(addr net.Addr) bool {
return strings.HasPrefix(addr.Network(), "unix") return strings.HasPrefix(addr.Network(), "unix")
} }
// IsPrivate returns true if the address is private. The definitions are,
// https://en.wikipedia.org/wiki/Link-local_address
// https://en.wikipedia.org/wiki/Multicast_address
// Local IPv4 addresses, https://tools.ietf.org/html/rfc1918
// Local IPv6 addresses, https://tools.ietf.org/html/rfc4193
func IsPrivate(addr net.Addr) bool {
switch addr := addr.(type) {
case *net.TCPAddr:
// Check 169.254.0.0/16 and fe80::/10.
if addr.IP.IsLinkLocalUnicast() {
return true
}
// Check 224.0.0.0/4 and ff00::/8.
if addr.IP.IsLinkLocalMulticast() {
return true
}
// Check 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16.
if ip4 := addr.IP.To4(); ip4 != nil {
return ip4[0] == 10 ||
(ip4[0] == 172 && ip4[1]&0xf0 == 16) ||
(ip4[0] == 192 && ip4[1] == 168)
}
// Check fc00::/7.
return len(addr.IP) == net.IPv6len && addr.IP[0]&0xfe == 0xfc
default:
return false
}
}
// ParseAddressString converts an address in string format to a net.Addr that is // ParseAddressString converts an address in string format to a net.Addr that is
// compatible with lnd. UDP is not supported because lnd needs reliable // compatible with lnd. UDP is not supported because lnd needs reliable
// connections. We accept a custom function to resolve any TCP addresses so // connections. We accept a custom function to resolve any TCP addresses so

@ -9,6 +9,7 @@ import (
"testing" "testing"
"github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/btcec"
"github.com/stretchr/testify/require"
) )
// addressTest defines a test vector for an address that contains the non- // addressTest defines a test vector for an address that contains the non-
@ -265,3 +266,57 @@ func validateAddr(t *testing.T, addr net.Addr, test addressTest) {
) )
} }
} }
func TestIsPrivate(t *testing.T) {
nonPrivateIPList := []net.IP{
net.IPv4(169, 255, 0, 0),
{0xfe, 0x79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
net.IPv4(225, 0, 0, 0),
{0xff, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
net.IPv4(11, 0, 0, 0),
net.IPv4(172, 15, 0, 0),
net.IPv4(192, 169, 0, 0),
{0xfe, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
net.IPv4(8, 8, 8, 8),
{2, 0, 0, 1, 4, 8, 6, 0, 4, 8, 6, 0, 8, 8, 8, 8},
}
privateIPList := []net.IP{
net.IPv4(169, 254, 0, 0),
{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
net.IPv4(224, 0, 0, 0),
{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
net.IPv4(10, 0, 0, 1),
net.IPv4(172, 16, 0, 1),
net.IPv4(172, 31, 255, 255),
net.IPv4(192, 168, 0, 1),
{0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
}
testParams := []struct {
name string
ipList []net.IP
private bool
}{
{
"Non-private addresses should return false",
nonPrivateIPList, false,
},
{
"Private addresses should return true",
privateIPList, true,
},
}
for _, tt := range testParams {
test := tt
t.Run(test.name, func(t *testing.T) {
for _, ip := range test.ipList {
addr := &net.TCPAddr{IP: ip}
require.Equal(
t, test.private, IsPrivate(addr),
"expected IP: %s to be %v", ip, test.private,
)
}
})
}
}