Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add noise support #7365

Merged
merged 2 commits into from
May 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/node/groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option {
fx.Invoke(libp2p.StartListening(cfg.Addresses.Swarm)),
fx.Invoke(libp2p.SetupDiscovery(cfg.Discovery.MDNS.Enabled, cfg.Discovery.MDNS.Interval)),

fx.Provide(libp2p.Security(!bcfg.DisableEncryptedConnections)),
fx.Provide(libp2p.Security(!bcfg.DisableEncryptedConnections, cfg.Experimental.OverrideSecurityTransports)),

fx.Provide(libp2p.Routing),
fx.Provide(libp2p.BaseRouting),
Expand Down
30 changes: 28 additions & 2 deletions core/node/libp2p/transport.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
package libp2p

import (
"fmt"

"github.com/libp2p/go-libp2p"
metrics "github.com/libp2p/go-libp2p-core/metrics"
noise "github.com/libp2p/go-libp2p-noise"
libp2pquic "github.com/libp2p/go-libp2p-quic-transport"
secio "github.com/libp2p/go-libp2p-secio"
tls "github.com/libp2p/go-libp2p-tls"

"go.uber.org/fx"
)

// default security transports for libp2p
var defaultSecurityTransports = []string{"tls", "secio", "noise"}

func Transports(pnet struct {
fx.In
Fprint PNetFingerprint `optional:"true"`
Expand All @@ -21,7 +27,7 @@ func Transports(pnet struct {
return opts
}

func Security(enabled bool) interface{} {
func Security(enabled bool, securityTransportOverride []string) interface{} {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Stebalien Why have we added the securityTransportOverride option ? Is there any use case for it right now ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the moment, go-ipfs prefers TLS, then SECIO, then Noise. That means the noise transport will never be used by default. The override option lets us actually use noise by:

  • Putting it before TLS.
  • Removing SECIO.
  • Etc...

See the tests and the new experimental-features documentation for details. If it doesn't make sense, I'll expand the documentation in a followup PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(also provides a way to disable noise if it causes problems)

if !enabled {
return func() (opts Libp2pOpts) {
// TODO: shouldn't this be Errorf to guarantee visibility?
Expand All @@ -31,8 +37,28 @@ func Security(enabled bool) interface{} {
return opts
}
}

securityTransports := defaultSecurityTransports
if len(securityTransportOverride) > 0 {
securityTransports = securityTransportOverride
}

var libp2pOpts []libp2p.Option
for _, tpt := range securityTransports {
switch tpt {
case "tls":
libp2pOpts = append(libp2pOpts, libp2p.Security(tls.ID, tls.New))
case "secio":
libp2pOpts = append(libp2pOpts, libp2p.Security(secio.ID, secio.New))
case "noise":
libp2pOpts = append(libp2pOpts, libp2p.Security(noise.ID, noise.New))
default:
return fx.Error(fmt.Errorf("invalid security transport specified in config: %s", tpt))
}
}

return func() (opts Libp2pOpts) {
opts.Opts = append(opts.Opts, libp2p.ChainOptions(libp2p.Security(tls.ID, tls.New), libp2p.Security(secio.ID, secio.New)))
opts.Opts = append(opts.Opts, libp2p.ChainOptions(libp2pOpts...))
return opts
}
}
Expand Down
24 changes: 24 additions & 0 deletions docs/experimental-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ the above issue.
- [AutoRelay](#autorelay)
- [Strategic Providing](#strategic-providing)
- [Graphsync](#graphsync)
- [Noise](#noise)

---

Expand Down Expand Up @@ -538,3 +539,26 @@ ipfs config --json Experimental.GraphsyncEnabled true
### Road to being a real feature

- [ ] We need to confirm that it can't be used to DoS a node. The server-side logic for GraphSync is quite complex and, if we're not careful, the server might end up performing unbounded work when responding to a malicious request.

## Noise

### State

Experimental, enabled by default

[Noise](https://github.com/libp2p/specs/tree/master/noise) libp2p transport based on the [Noise Protocol Framework](https://noiseprotocol.org/noise.html). While TLS remains the default transport in go-ipfs, Noise is easier to implement and will thus serve as the "interop" transport between IPFS and libp2p implementations, eventually replacing SECIO.

### How to enable

While the Noise transport is now shipped and enabled by default in go-ipfs, it won't be used by default for most connections because TLS and SECIO are currently preferred. If you'd like to test out the Noise transport, you can use the `Experimental.OverrideSecurityTransports` option to enable, disable, and reorder security transports.

For example, to prefer noise over TLS and disable SECIO, run:

```
ipfs config --json Experimental.OverrideSecurityTransports '["noise", "tls"]'
```

### Road to being a real feature

- [ ] Needs real-world testing.
- [ ] Ideally a js-ipfs and a rust-ipfs release would include support for Noise.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ require (
github.com/ipfs/go-ipfs-blockstore v0.1.4
github.com/ipfs/go-ipfs-chunker v0.0.5
github.com/ipfs/go-ipfs-cmds v0.2.9
github.com/ipfs/go-ipfs-config v0.7.0
github.com/ipfs/go-ipfs-config v0.7.1
github.com/ipfs/go-ipfs-ds-help v0.1.1
github.com/ipfs/go-ipfs-exchange-interface v0.0.1
github.com/ipfs/go-ipfs-exchange-offline v0.0.1
Expand Down Expand Up @@ -70,6 +70,7 @@ require (
github.com/libp2p/go-libp2p-kbucket v0.4.2
github.com/libp2p/go-libp2p-loggables v0.1.0
github.com/libp2p/go-libp2p-mplex v0.2.3
github.com/libp2p/go-libp2p-noise v0.1.1
github.com/libp2p/go-libp2p-peerstore v0.2.4
github.com/libp2p/go-libp2p-pubsub v0.3.0
github.com/libp2p/go-libp2p-pubsub-router v0.3.0
Expand Down
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 h1:u/UEqS66A5ckRmS4yNpjmVH56sVtS/RfclBAYocb4as=
github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ=
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
Expand Down Expand Up @@ -303,6 +305,8 @@ github.com/ipfs/go-ipfs-cmds v0.2.9 h1:zQTENe9UJrtCb2bOtRoDGjtuo3rQjmuPdPnVlqoBV
github.com/ipfs/go-ipfs-cmds v0.2.9/go.mod h1:ZgYiWVnCk43ChwoH8hAmI1IRbuVtq3GSTHwtRB/Kqhk=
github.com/ipfs/go-ipfs-config v0.7.0 h1:cClINg8v28//KaYMwt1aSjbS8eGJjNKIEnahpT/2hYk=
github.com/ipfs/go-ipfs-config v0.7.0/go.mod h1:GQUxqb0NfkZmEU92PxqqqLVVFTLpoGGUlBaTyDaAqrE=
github.com/ipfs/go-ipfs-config v0.7.1 h1:57ZzoiUIbOIT01x1RconKtCv1MElV/6+kqW8hZY9NJ4=
github.com/ipfs/go-ipfs-config v0.7.1/go.mod h1:GQUxqb0NfkZmEU92PxqqqLVVFTLpoGGUlBaTyDaAqrE=
github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw=
github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ=
github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw=
Expand Down Expand Up @@ -501,6 +505,7 @@ github.com/libp2p/go-libp2p v0.7.0 h1:qWmciout2lJclKfRlxqdepsQB7JihcbRhgcRcssP4r
github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xSU1ivxn0k=
github.com/libp2p/go-libp2p v0.7.4 h1:xVj1oSlN0C+FlxqiLuHC8WruMvq24xxfeVxmNhTG0r0=
github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw=
github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o=
github.com/libp2p/go-libp2p v0.8.2 h1:gVuk8nZGjnRagJ/mLpBCSJw7bW1yWJrq3EwOk/AC6FM=
github.com/libp2p/go-libp2p v0.8.2/go.mod h1:NQDA/F/qArMHGe0J7sDScaKjW8Jh4y/ozQqBbYJ+BnA=
github.com/libp2p/go-libp2p v0.8.3 h1:IFWeNzxkBaNO1N8stN9ayFGdC6RmVuSsKd5bou7qpK0=
Expand Down Expand Up @@ -620,6 +625,8 @@ github.com/libp2p/go-libp2p-net v0.0.2/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8
github.com/libp2p/go-libp2p-netutil v0.0.1/go.mod h1:GdusFvujWZI9Vt0X5BKqwWWmZFxecf9Gt03cKxm2f/Q=
github.com/libp2p/go-libp2p-netutil v0.1.0 h1:zscYDNVEcGxyUpMd0JReUZTrpMfia8PmLKcKF72EAMQ=
github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU=
github.com/libp2p/go-libp2p-noise v0.1.1 h1:vqYQWvnIcHpIoWJKC7Al4D6Hgj0H012TuXRhPwSMGpQ=
github.com/libp2p/go-libp2p-noise v0.1.1/go.mod h1:QDFLdKX7nluB7DEnlVPbz7xlLHdwHFA9HiohJRr3vwM=
github.com/libp2p/go-libp2p-peer v0.0.1/go.mod h1:nXQvOBbwVqoP+T5Y5nCjeH4sP9IX/J0AMzcDUVruVoo=
github.com/libp2p/go-libp2p-peer v0.1.1/go.mod h1:jkF12jGB4Gk/IOo+yomm+7oLWxF278F7UnrYUQ1Q8es=
github.com/libp2p/go-libp2p-peer v0.2.0 h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY=
Expand Down
4 changes: 2 additions & 2 deletions test/sharness/lib/iptb-lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ startup_cluster() {

if test -n "$other_args"; then
test_expect_success "start up nodes with additional args" "
iptb start -wait -- ${other_args[@]}
iptb start -wait [0-$bound] -- ${other_args[@]}
"
else
test_expect_success "start up nodes" '
iptb start -wait
iptb start -wait [0-$bound]
'
fi

Expand Down
29 changes: 22 additions & 7 deletions test/sharness/t0125-twonode.sh
Original file line number Diff line number Diff line change
Expand Up @@ -89,23 +89,38 @@ test_expect_success "set up tcp testbed" '
iptb testbed create -type localipfs -count 2 -force -init
'

# Test TCP transport
echo "Testing TCP"
tcp_addr='"[\"/ip4/127.0.0.1/tcp/0\"]"'
test_expect_success "use TCP only" '
ipfsi 0 config --json Addresses.Swarm '${tcp_addr}' &&
ipfsi 1 config --json Addresses.Swarm '${tcp_addr}'
'
run_advanced_test

# test multiplex muxer
echo "Running advanced tests with mplex"
export LIBP2P_MUX_PREFS="/mplex/6.7.0"
run_advanced_test "--enable-mplex-experiment"
unset LIBP2P_MUX_PREFS

# test default configuration
echo "Running advanced tests with default config"
# test Noise

echo "Running advanced tests with NOISE"
noise_transports='"[\"noise\"]"'
test_expect_success "use noise only" '
ipfsi 0 config --json Experimental.OverrideSecurityTransports '${noise_transports}' &&
ipfsi 1 config --json Experimental.OverrideSecurityTransports '${noise_transports}'
'

run_advanced_test

# test QUIC
echo "Running advanced tests over QUIC"
addr1='"[\"/ip4/127.0.0.1/udp/0/quic/\"]"'
addr2='"[\"/ip4/127.0.0.1/udp/0/quic/\"]"'
test_expect_success "add QUIC swarm addresses" '
ipfsi 0 config --json Addresses.Swarm '$addr1' &&
ipfsi 1 config --json Addresses.Swarm '$addr2'
addr1='"[\"/ip4/127.0.0.1/udp/0/quic\"]"'
test_expect_success "use QUIC only" '
ipfsi 0 config --json Addresses.Swarm '${quic_addr}' &&
ipfsi 1 config --json Addresses.Swarm '${quic_addr}'
'

run_advanced_test
Expand Down
47 changes: 47 additions & 0 deletions test/sharness/t0191-noise.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env bash

test_description="Test ping over NOISE command"

. lib/test-lib.sh

test_init_ipfs

# start iptb + wait for peering
test_expect_success 'init iptb' '
iptb testbed create -type localipfs -count 3 -init
'

noise_transports='"[\"noise\"]"'
other_transports='"[\"tls\",\"secio\"]"'
tcp_addr='"[\"/ip4/127.0.0.1/tcp/0\"]"'
test_expect_success "configure security transports" '
ipfsi 0 config --json Experimental.OverrideSecurityTransports '${noise_transports}' &&
ipfsi 1 config --json Experimental.OverrideSecurityTransports '${noise_transports}' &&
ipfsi 2 config --json Experimental.OverrideSecurityTransports '${other_transports}' &&
iptb run -- ipfs config --json Addresses.Swarm '${tcp_addr}'
'

startup_cluster 2

test_expect_success 'peer ids' '
PEERID_0=$(iptb attr get 0 id) &&
PEERID_1=$(iptb attr get 1 id)
'

test_expect_success "test ping other" '
ipfsi 0 ping -n2 -- "$PEERID_1" &&
ipfsi 1 ping -n2 -- "$PEERID_0"
'

test_expect_success "test tls incompatible" '
iptb start --wait 2 &&
test_must_fail iptb connect 2 0 > connect_error 2>&1 &&
test_should_contain "failed to negotiate security protocol" connect_error ||
test_fsh cat connect_error
'

test_expect_success 'stop iptb' '
iptb stop
'

test_done