mirror of
https://github.com/ipfs/kubo.git
synced 2025-10-25 10:27:01 +08:00
add in basic address dial filtering
License: MIT Signed-off-by: Jeromy <jeromyj@gmail.com>
This commit is contained in:
4
Godeps/Godeps.json
generated
4
Godeps/Godeps.json
generated
@ -239,6 +239,10 @@
|
||||
"ImportPath": "github.com/whyrusleeping/iptb",
|
||||
"Rev": "3970c95a864f1a40037f796ff596607ce8ae43be"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/whyrusleeping/multiaddr-filter",
|
||||
"Rev": "15837fcc356fddef27c634b0f6379b3b7f259114"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/crypto/blowfish",
|
||||
"Rev": "c84e1f8e3a7e322d497cd16c0e8a13c7e127baf3"
|
||||
|
||||
19
Godeps/_workspace/src/github.com/whyrusleeping/multiaddr-filter/mask.go
generated
vendored
Normal file
19
Godeps/_workspace/src/github.com/whyrusleeping/multiaddr-filter/mask.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
package mask
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func NewMask(a string) (*net.IPNet, error) {
|
||||
parts := strings.Split(a, "/")
|
||||
if len(parts) == 5 && parts[1] == "ip4" && parts[3] == "ipcidr" {
|
||||
_, ipn, err := net.ParseCIDR(parts[2] + "/" + parts[4])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ipn, nil
|
||||
}
|
||||
return nil, errors.New("invalid format")
|
||||
}
|
||||
36
Godeps/_workspace/src/github.com/whyrusleeping/multiaddr-filter/mask_test.go
generated
vendored
Normal file
36
Godeps/_workspace/src/github.com/whyrusleeping/multiaddr-filter/mask_test.go
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
package mask
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFiltered(t *testing.T) {
|
||||
var tests = map[string]map[string]bool{
|
||||
"/ip4/10.0.0.0/ipcidr/8": map[string]bool{
|
||||
"10.3.3.4": true,
|
||||
"10.3.4.4": true,
|
||||
"10.4.4.4": true,
|
||||
"15.52.34.3": false,
|
||||
},
|
||||
"/ip4/192.168.0.0/ipcidr/16": map[string]bool{
|
||||
"192.168.0.0": true,
|
||||
"192.168.1.0": true,
|
||||
"192.1.0.0": false,
|
||||
"10.4.4.4": false,
|
||||
},
|
||||
}
|
||||
|
||||
for mask, set := range tests {
|
||||
m, err := NewMask(mask)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for addr, val := range set {
|
||||
ip := net.ParseIP(addr)
|
||||
if m.Contains(ip) != val {
|
||||
t.Fatalf("expected contains(%s, %s) == %s", mask, addr, val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
core/core.go
24
core/core.go
@ -13,17 +13,17 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
b58 "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-base58"
|
||||
ctxgroup "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-ctxgroup"
|
||||
ds "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
|
||||
ma "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
|
||||
mamask "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/whyrusleeping/multiaddr-filter"
|
||||
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
|
||||
metrics "github.com/ipfs/go-ipfs/metrics"
|
||||
eventlog "github.com/ipfs/go-ipfs/thirdparty/eventlog"
|
||||
|
||||
diag "github.com/ipfs/go-ipfs/diagnostics"
|
||||
metrics "github.com/ipfs/go-ipfs/metrics"
|
||||
ic "github.com/ipfs/go-ipfs/p2p/crypto"
|
||||
discovery "github.com/ipfs/go-ipfs/p2p/discovery"
|
||||
p2phost "github.com/ipfs/go-ipfs/p2p/host"
|
||||
@ -32,6 +32,7 @@ import (
|
||||
swarm "github.com/ipfs/go-ipfs/p2p/net/swarm"
|
||||
addrutil "github.com/ipfs/go-ipfs/p2p/net/swarm/addr"
|
||||
peer "github.com/ipfs/go-ipfs/p2p/peer"
|
||||
eventlog "github.com/ipfs/go-ipfs/thirdparty/eventlog"
|
||||
|
||||
routing "github.com/ipfs/go-ipfs/routing"
|
||||
dht "github.com/ipfs/go-ipfs/routing/dht"
|
||||
@ -254,7 +255,18 @@ func (n *IpfsNode) startOnlineServices(ctx context.Context, routingOption Routin
|
||||
// Set reporter
|
||||
n.Reporter = metrics.NewBandwidthCounter()
|
||||
|
||||
peerhost, err := hostOption(ctx, n.Identity, n.Peerstore, n.Reporter)
|
||||
// get undialable addrs from config
|
||||
cfg := n.Repo.Config()
|
||||
var addrfilter []*net.IPNet
|
||||
for _, s := range cfg.DialBlocklist {
|
||||
f, err := mamask.NewMask(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("incorrectly formatter address filter in config: %s", s)
|
||||
}
|
||||
addrfilter = append(addrfilter, f)
|
||||
}
|
||||
|
||||
peerhost, err := hostOption(ctx, n.Identity, n.Peerstore, n.Reporter, addrfilter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -508,12 +520,12 @@ func listenAddresses(cfg *config.Config) ([]ma.Multiaddr, error) {
|
||||
return listen, nil
|
||||
}
|
||||
|
||||
type HostOption func(ctx context.Context, id peer.ID, ps peer.Peerstore, bwr metrics.Reporter) (p2phost.Host, error)
|
||||
type HostOption func(ctx context.Context, id peer.ID, ps peer.Peerstore, bwr metrics.Reporter, fs []*net.IPNet) (p2phost.Host, error)
|
||||
|
||||
var DefaultHostOption HostOption = constructPeerHost
|
||||
|
||||
// isolates the complex initialization steps
|
||||
func constructPeerHost(ctx context.Context, id peer.ID, ps peer.Peerstore, bwr metrics.Reporter) (p2phost.Host, error) {
|
||||
func constructPeerHost(ctx context.Context, id peer.ID, ps peer.Peerstore, bwr metrics.Reporter, fs []*net.IPNet) (p2phost.Host, error) {
|
||||
|
||||
// no addresses to begin with. we'll start later.
|
||||
network, err := swarm.NewNetwork(ctx, nil, id, ps, bwr)
|
||||
|
||||
@ -4,6 +4,7 @@ package swarm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -50,6 +51,9 @@ type Swarm struct {
|
||||
notifmu sync.RWMutex
|
||||
notifs map[inet.Notifiee]ps.Notifiee
|
||||
|
||||
// filters for addresses that shouldnt be dialed
|
||||
filters []*net.IPNet
|
||||
|
||||
cg ctxgroup.ContextGroup
|
||||
bwc metrics.Reporter
|
||||
}
|
||||
@ -84,6 +88,10 @@ func (s *Swarm) teardown() error {
|
||||
return s.swarm.Close()
|
||||
}
|
||||
|
||||
func (s *Swarm) AddDialFilter(f *net.IPNet) {
|
||||
s.filters = append(s.filters, f)
|
||||
}
|
||||
|
||||
// CtxGroup returns the Context Group of the swarm
|
||||
func filterAddrs(listenAddrs []ma.Multiaddr) ([]ma.Multiaddr, error) {
|
||||
if len(listenAddrs) > 0 {
|
||||
|
||||
@ -303,6 +303,8 @@ func (s *Swarm) dial(ctx context.Context, p peer.ID) (*Conn, error) {
|
||||
ila, _ := s.InterfaceListenAddresses()
|
||||
remoteAddrs = addrutil.Subtract(remoteAddrs, ila)
|
||||
remoteAddrs = addrutil.Subtract(remoteAddrs, s.peers.Addrs(s.local))
|
||||
remoteAddrs = s.filterAddrs(remoteAddrs)
|
||||
|
||||
log.Debugf("%s swarm dialing %s -- local:%s remote:%s", s.local, p, s.ListenAddresses(), remoteAddrs)
|
||||
if len(remoteAddrs) == 0 {
|
||||
err := errors.New("peer has no addresses")
|
||||
@ -454,6 +456,32 @@ func (s *Swarm) dialAddr(ctx context.Context, d *conn.Dialer, p peer.ID, addr ma
|
||||
return connC, nil
|
||||
}
|
||||
|
||||
func (s *Swarm) filterAddrs(addrs []ma.Multiaddr) []ma.Multiaddr {
|
||||
var out []ma.Multiaddr
|
||||
for _, a := range addrs {
|
||||
if !s.addrBlocked(a) {
|
||||
out = append(out, a)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (s *Swarm) addrBlocked(a ma.Multiaddr) bool {
|
||||
_, addr, err := manet.DialArgs(a)
|
||||
if err != nil {
|
||||
// if we cant parse it, its probably not blocked
|
||||
return false
|
||||
}
|
||||
|
||||
ip := net.ParseIP(addr)
|
||||
for _, f := range s.filters {
|
||||
if f.Contains(ip) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// dialConnSetup is the setup logic for a connection from the dial side. it
|
||||
// needs to add the Conn to the StreamSwarm, then run newConnSetup
|
||||
func dialConnSetup(ctx context.Context, s *Swarm, connC conn.Conn) (*Conn, error) {
|
||||
|
||||
@ -26,6 +26,7 @@ type Config struct {
|
||||
Tour Tour // local node's tour position
|
||||
Gateway Gateway // local node's gateway server options
|
||||
SupernodeRouting SupernodeClientConfig // local node's routing servers (if SupernodeRouting enabled)
|
||||
DialBlocklist []string
|
||||
Log Log
|
||||
}
|
||||
|
||||
|
||||
@ -6,4 +6,5 @@ import _ "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/dustin/go-hum
|
||||
|
||||
// similar to the above, only used in the tests makefile
|
||||
import _ "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/whyrusleeping/iptb"
|
||||
|
||||
import _ "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/chriscool/go-sleep"
|
||||
|
||||
Reference in New Issue
Block a user