Skip to content

Commit

Permalink
Restrict access to the server's private networks (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
alalamav authored Jan 31, 2019
1 parent 4e4c498 commit 8972cd6
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 0 deletions.
43 changes: 43 additions & 0 deletions net/private_net.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2019 Jigsaw Operations LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package net

import "net"

var privateNetworks []*net.IPNet

func init() {
for _, cidr := range []string{
// RFC 1918: private IPv4 networks
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16",
// RFC 4193: IPv6 ULAs
"fc00::/7",
} {
_, subnet, _ := net.ParseCIDR(cidr)
privateNetworks = append(privateNetworks, subnet)
}
}

// IsPrivateAddress returns whether an IP address belongs to the LAN.
func IsPrivateAddress(ip net.IP) bool {
for _, network := range privateNetworks {
if network.Contains(ip) {
return true
}
}
return false
}
46 changes: 46 additions & 0 deletions net/private_net_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2019 Jigsaw Operations LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package net

import (
"net"
"testing"
)

var privateAddressTests = []struct {
address string
expected bool
}{
{"10.0.2.11", true},
{"172.16.1.2", true},
{"172.32.0.0", false},
{"192.168.0.23", true},
{"192.169.1.1", false},
{"127.0.0.1", false},
{"8.8.8.8", false},
{"::", false},
{"fd66:f83a:c650::1", true},
{"fde4:8dba:82e1::", true},
{"fe::123", false},
}

func TestIsLanAddress(t *testing.T) {
for _, tt := range privateAddressTests {
actual := IsPrivateAddress(net.ParseIP(tt.address))
if actual != tt.expected {
t.Errorf("IsLanAddress(%s): expected %t, actual %t", tt.address, tt.expected, actual)
}
}
}
3 changes: 3 additions & 0 deletions shadowsocks/tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ func proxyConnection(clientConn onet.DuplexConn, proxyMetrics *metrics.ProxyMetr
if !tgtTCPAddr.IP.IsGlobalUnicast() {
return onet.NewConnectionError("ERR_ADDRESS_INVALID", fmt.Sprintf("Target address is not global unicast: %v", tgtAddr.String()), err)
}
if onet.IsPrivateAddress(tgtTCPAddr.IP) {
return onet.NewConnectionError("ERR_ADDRESS_PRIVATE", fmt.Sprintf("Target address is a private address: %v", tgtAddr.String()), nil)
}

tgtTCPConn, err := net.DialTCP("tcp", nil, tgtTCPAddr)
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions shadowsocks/udp.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ func (s *udpService) Start() {
if !tgtUDPAddr.IP.IsGlobalUnicast() {
return onet.NewConnectionError("ERR_ADDRESS_INVALID", fmt.Sprintf("Target address is not global unicast: %v", tgtAddr.String()), err)
}
if onet.IsPrivateAddress(tgtUDPAddr.IP) {
return onet.NewConnectionError("ERR_ADDRESS_PRIVATE", fmt.Sprintf("Target address is a private address: %v", tgtAddr.String()), nil)
}

payload := buf[len(tgtAddr):]

Expand Down

0 comments on commit 8972cd6

Please sign in to comment.