From ccc2d237306c8f22630809292f1960eb87f242d1 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 25 Feb 2021 13:17:43 -0800 Subject: [PATCH] feat: remove secio support We've had a reliable and enabled by default TLS implementation since 0.4.23 (over a year ago) and turned off SECIO in September of last year. We might as well remove support entirely in the next release and encourage users to upgrade their networks. Noise is faster, anyways. --- cmd/seccat/.gitignore | 1 - cmd/seccat/seccat.go | 255 ----------------------------- cmd/seccat/seccat_plan9.go | 8 - cmd/seccat/seccat_posix.go | 10 -- cmd/seccat/util.go | 47 ------ core/node/libp2p/sec.go | 14 +- docs/config.md | 12 +- docs/experimental-features.md | 24 +-- go.mod | 1 - go.sum | 1 - test/sharness/t0061-daemon-opts.sh | 1 - test/sharness/t0125-twonode.sh | 3 +- test/sharness/t0191-noise.sh | 1 - 13 files changed, 14 insertions(+), 364 deletions(-) delete mode 100644 cmd/seccat/.gitignore delete mode 100644 cmd/seccat/seccat.go delete mode 100644 cmd/seccat/seccat_plan9.go delete mode 100644 cmd/seccat/seccat_posix.go delete mode 100644 cmd/seccat/util.go diff --git a/cmd/seccat/.gitignore b/cmd/seccat/.gitignore deleted file mode 100644 index 5b0d9d049..000000000 --- a/cmd/seccat/.gitignore +++ /dev/null @@ -1 +0,0 @@ -seccat diff --git a/cmd/seccat/seccat.go b/cmd/seccat/seccat.go deleted file mode 100644 index 21724b4c5..000000000 --- a/cmd/seccat/seccat.go +++ /dev/null @@ -1,255 +0,0 @@ -// package main provides an implementation of netcat using the secio package. -// This means the channel is encrypted (and MACed). -// It is meant to exercise the spipe package. -// Usage: -// seccat [] -// seccat -l -// -// Address format is: [host]:port -package main - -import ( - "context" - "flag" - "fmt" - "io" - "net" - "os" - "os/signal" - "syscall" - - logging "github.com/ipfs/go-log" - ci "github.com/libp2p/go-libp2p-core/crypto" - peer "github.com/libp2p/go-libp2p-core/peer" - pstore "github.com/libp2p/go-libp2p-core/peerstore" - pstoremem "github.com/libp2p/go-libp2p-peerstore/pstoremem" - secio "github.com/libp2p/go-libp2p-secio" -) - -var verbose = false - -// Usage prints out the usage of this module. -// Assumes flags use go stdlib flag package. -var Usage = func() { - text := `seccat - secure netcat in Go - -Usage: - - listen: %s [] - dial: %s -l - -Address format is Go's: [host]:port -` - - fmt.Fprintf(os.Stderr, text, os.Args[0], os.Args[0]) - flag.PrintDefaults() -} - -type args struct { - listen bool - verbose bool - debug bool - localAddr string - remoteAddr string - // keyfile string - keybits int -} - -func parseArgs() args { - var a args - - // setup + parse flags - flag.BoolVar(&a.listen, "listen", false, "listen for connections") - flag.BoolVar(&a.listen, "l", false, "listen for connections (short)") - flag.BoolVar(&a.verbose, "v", true, "verbose") - flag.BoolVar(&a.debug, "debug", false, "debugging") - // flag.StringVar(&a.keyfile, "key", "", "private key file") - flag.IntVar(&a.keybits, "keybits", 2048, "num bits for generating private key") - flag.Usage = Usage - flag.Parse() - osArgs := flag.Args() - - if len(osArgs) < 1 { - exit("") - } - - if a.verbose { - out("verbose on") - } - - if a.listen { - a.localAddr = osArgs[0] - } else { - if len(osArgs) > 1 { - a.localAddr = osArgs[0] - a.remoteAddr = osArgs[1] - } else { - a.remoteAddr = osArgs[0] - } - } - - return a -} - -func main() { - args := parseArgs() - verbose = args.verbose - if args.debug { - logging.SetDebugLogging() - } - - go func() { - // wait until we exit. - sigc := make(chan os.Signal, 1) - signal.Notify(sigc, syscall.SIGABRT) - <-sigc - panic("ABORT! ABORT! ABORT!") - }() - - if err := connect(args); err != nil { - exit("%s", err) - } -} - -func setupPeer(a args) (peer.ID, pstore.Peerstore, error) { - if a.keybits < ci.MinRsaKeyBits { - return "", nil, ci.ErrRsaKeyTooSmall - } - - out("generating key pair...") - sk, pk, err := ci.GenerateKeyPair(ci.RSA, a.keybits) - if err != nil { - return "", nil, err - } - - p, err := peer.IDFromPublicKey(pk) - if err != nil { - return "", nil, err - } - - ps := pstoremem.NewPeerstore() - err = ps.AddPrivKey(p, sk) - if err != nil { - return "", nil, err - } - err = ps.AddPubKey(p, pk) - if err != nil { - return "", nil, err - } - - out("local peer id: %s", p) - return p, ps, nil -} - -func connect(args args) error { - p, ps, err := setupPeer(args) - if err != nil { - return err - } - - var conn net.Conn - if args.listen { - conn, err = Listen(args.localAddr) - } else { - conn, err = Dial(args.localAddr, args.remoteAddr) - } - if err != nil { - return err - } - - // log everything that goes through conn - rwc := &logConn{n: "conn", Conn: conn} - - // OK, let's setup the channel. - sk := ps.PrivKey(p) - sg, err := secio.New(sk) - if err != nil { - return err - } - sconn, err := sg.SecureInbound(context.TODO(), rwc) - if err != nil { - return err - } - out("remote peer id: %s", sconn.RemotePeer()) - netcat(sconn) - return nil -} - -// Listen listens and accepts one incoming UDT connection on a given port, -// and pipes all incoming data to os.Stdout. -func Listen(localAddr string) (net.Conn, error) { - l, err := net.Listen("tcp", localAddr) - if err != nil { - return nil, err - } - out("listening at %s", l.Addr()) - - c, err := l.Accept() - if err != nil { - return nil, err - } - out("accepted connection from %s", c.RemoteAddr()) - - // done with listener - l.Close() - - return c, nil -} - -// Dial connects to a remote address and pipes all os.Stdin to the remote end. -// If localAddr is set, uses it to Dial from. -func Dial(localAddr, remoteAddr string) (net.Conn, error) { - - var laddr net.Addr - var err error - if localAddr != "" { - laddr, err = net.ResolveTCPAddr("tcp", localAddr) - if err != nil { - return nil, fmt.Errorf("failed to resolve address %s", localAddr) - } - } - - if laddr != nil { - out("dialing %s from %s", remoteAddr, laddr) - } else { - out("dialing %s", remoteAddr) - } - - d := net.Dialer{LocalAddr: laddr} - c, err := d.Dial("tcp", remoteAddr) - if err != nil { - return nil, err - } - out("connected to %s", c.RemoteAddr()) - - return c, nil -} - -func netcat(c io.ReadWriteCloser) { - out("piping stdio to connection") - - done := make(chan struct{}, 2) - - go func() { - n, _ := io.Copy(c, os.Stdin) - out("sent %d bytes", n) - done <- struct{}{} - }() - go func() { - n, _ := io.Copy(os.Stdout, c) - out("received %d bytes", n) - done <- struct{}{} - }() - - // wait until we exit. - sigc := make(chan os.Signal, 1) - signal.Notify(sigc, notifySignals...) - - select { - case <-done: - case <-sigc: - return - } - - c.Close() -} diff --git a/cmd/seccat/seccat_plan9.go b/cmd/seccat/seccat_plan9.go deleted file mode 100644 index 3139500c5..000000000 --- a/cmd/seccat/seccat_plan9.go +++ /dev/null @@ -1,8 +0,0 @@ -package main - -import ( - "os" - "syscall" -) - -var notifySignals = []os.Signal{syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM} diff --git a/cmd/seccat/seccat_posix.go b/cmd/seccat/seccat_posix.go deleted file mode 100644 index 92906db62..000000000 --- a/cmd/seccat/seccat_posix.go +++ /dev/null @@ -1,10 +0,0 @@ -// +build !plan9 - -package main - -import ( - "os" - "syscall" -) - -var notifySignals = []os.Signal{syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT} diff --git a/cmd/seccat/util.go b/cmd/seccat/util.go deleted file mode 100644 index 05140e325..000000000 --- a/cmd/seccat/util.go +++ /dev/null @@ -1,47 +0,0 @@ -package main - -import ( - "fmt" - "net" - "os" - - logging "github.com/ipfs/go-log" -) - -var log = logging.Logger("seccat") - -func exit(format string, vals ...interface{}) { - if format != "" { - fmt.Fprintf(os.Stderr, "seccat: error: "+format+"\n", vals...) - } - Usage() - os.Exit(1) -} - -func out(format string, vals ...interface{}) { - if verbose { - fmt.Fprintf(os.Stderr, "seccat: "+format+"\n", vals...) - } -} - -type logConn struct { - net.Conn - n string -} - -func (r *logConn) Read(buf []byte) (int, error) { - n, err := r.Conn.Read(buf) - if n > 0 { - log.Debugf("%s read: %v", r.n, buf) - } - return n, err -} - -func (r *logConn) Write(buf []byte) (int, error) { - log.Debugf("%s write: %v", r.n, buf) - return r.Conn.Write(buf) -} - -func (r *logConn) Close() error { - return r.Conn.Close() -} diff --git a/core/node/libp2p/sec.go b/core/node/libp2p/sec.go index 8d6fde000..65b440ec4 100644 --- a/core/node/libp2p/sec.go +++ b/core/node/libp2p/sec.go @@ -4,10 +4,14 @@ import ( config "github.com/ipfs/go-ipfs-config" "github.com/libp2p/go-libp2p" noise "github.com/libp2p/go-libp2p-noise" - secio "github.com/libp2p/go-libp2p-secio" tls "github.com/libp2p/go-libp2p-tls" ) +const secioEnabledWarning = `The SECIO security transport was enabled in the config but is no longer supported. + +SECIO disabled by default in go-ipfs 0.7 removed in go-ipfs 0.9. Please remove +Swarm.Transports.Security.SECIO from your IPFS config.` + func Security(enabled bool, tptConfig config.Transports) interface{} { if !enabled { return func() (opts Libp2pOpts) { @@ -18,16 +22,16 @@ func Security(enabled bool, tptConfig config.Transports) interface{} { } } + if _, enabled := tptConfig.Security.SECIO.WithDefault(config.Disabled); enabled { + log.Error(secioEnabledWarning) + } + // Using the new config options. return func() (opts Libp2pOpts) { opts.Opts = append(opts.Opts, prioritizeOptions([]priorityOption{{ priority: tptConfig.Security.TLS, defaultPriority: 100, opt: libp2p.Security(tls.ID, tls.New), - }, { - priority: tptConfig.Security.SECIO, - defaultPriority: config.Disabled, - opt: libp2p.Security(secio.ID, secio.New), }, { priority: tptConfig.Security.Noise, defaultPriority: 300, diff --git a/docs/config.md b/docs/config.md index 61c9aad7c..3f70795bc 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1352,8 +1352,7 @@ receiver supports. When establishing an _inbound_ connection, go-ipfs will let the initiator choose the protocol, but will refuse to use any of the disabled transports. -Supported transports are: TLS (priority 100), SECIO (Disabled: i.e. priority false), Noise -(priority 300). +Supported transports are: TLS (priority 100) and Noise (priority 300). No default priority will ever be less than 100. @@ -1369,14 +1368,7 @@ Type: `priority` #### `Swarm.Transports.Security.SECIO` -[SECIO](https://github.com/libp2p/specs/tree/master/secio) was the most widely -supported IPFS & libp2p security transport. However, it is currently being -phased out in favor of more popular and better vetted protocols like TLS and -Noise. - -Default: `false` - -Type: `priority` +Support for SECIO has been removed. Please remove this option from your config. #### `Swarm.Transports.Security.Noise` diff --git a/docs/experimental-features.md b/docs/experimental-features.md index 725ccd462..fd8cd3318 100644 --- a/docs/experimental-features.md +++ b/docs/experimental-features.md @@ -544,26 +544,6 @@ ipfs config --json Experimental.GraphsyncEnabled true ### State -Experimental, enabled by default +Stable, 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 increase the priority of the noise transport: - -``` -ipfs config --json Swarm.Transports.Security.Noise 1 -``` - -Or even disable TLS and/or SECIO (not recommended for the moment): - -``` -ipfs config --json Swarm.Transports.Security.TLS false -ipfs config --json Swarm.Transports.Security.SECIO false -``` - -### Road to being a real feature - -- [ ] Needs real-world testing. -- [ ] Ideally a js-ipfs and a rust-ipfs release would include support for Noise. +[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 is thus the "interop" transport between IPFS and libp2p implementations. diff --git a/go.mod b/go.mod index b25330e4a..4b704de6b 100644 --- a/go.mod +++ b/go.mod @@ -78,7 +78,6 @@ require ( github.com/libp2p/go-libp2p-quic-transport v0.10.0 github.com/libp2p/go-libp2p-record v0.1.3 github.com/libp2p/go-libp2p-routing-helpers v0.2.3 - github.com/libp2p/go-libp2p-secio v0.2.2 github.com/libp2p/go-libp2p-swarm v0.4.0 github.com/libp2p/go-libp2p-testing v0.4.0 github.com/libp2p/go-libp2p-tls v0.1.3 diff --git a/go.sum b/go.sum index f4ac2a048..c06f71c13 100644 --- a/go.sum +++ b/go.sum @@ -638,7 +638,6 @@ github.com/libp2p/go-libp2p-secio v0.0.3/go.mod h1:hS7HQ00MgLhRO/Wyu1bTX6ctJKhVp github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= -github.com/libp2p/go-libp2p-secio v0.2.2 h1:rLLPvShPQAcY6eNurKNZq3eZjPWfU9kXF2eI9jIYdrg= github.com/libp2p/go-libp2p-secio v0.2.2/go.mod h1:wP3bS+m5AUnFA+OFO7Er03uO1mncHG0uVwGrwvjYlNY= github.com/libp2p/go-libp2p-swarm v0.0.6/go.mod h1:s5GZvzg9xXe8sbeESuFpjt8CJPTCa8mhEusweJqyFy8= github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= diff --git a/test/sharness/t0061-daemon-opts.sh b/test/sharness/t0061-daemon-opts.sh index 7d5cf7fe7..9d60852c8 100755 --- a/test/sharness/t0061-daemon-opts.sh +++ b/test/sharness/t0061-daemon-opts.sh @@ -19,7 +19,6 @@ apiaddr=$API_ADDR # Odd. this fails here, but the inverse works on t0060-daemon. test_expect_success SOCAT 'transport should be unencrypted ( needs socat )' ' socat - tcp:localhost:$SWARM_PORT,connect-timeout=1 > swarmnc < ../t0060-data/mss-ls && - grep -q -v "/secio" swarmnc && grep -q "/plaintext" swarmnc || test_fsh cat swarmnc ' diff --git a/test/sharness/t0125-twonode.sh b/test/sharness/t0125-twonode.sh index d8fb45e44..28c919c22 100755 --- a/test/sharness/t0125-twonode.sh +++ b/test/sharness/t0125-twonode.sh @@ -119,8 +119,7 @@ test_expect_success "re-enable yamux" ' echo "Running advanced tests with NOISE" test_expect_success "use noise only" ' - iptb run -- ipfs config --json Swarm.Transports.Security.TLS false && - iptb run -- ipfs config --json Swarm.Transports.Security.Secio false + iptb run -- ipfs config --json Swarm.Transports.Security.TLS false ' run_advanced_test diff --git a/test/sharness/t0191-noise.sh b/test/sharness/t0191-noise.sh index bffec2d80..c68073d14 100755 --- a/test/sharness/t0191-noise.sh +++ b/test/sharness/t0191-noise.sh @@ -15,7 +15,6 @@ tcp_addr='"[\"/ip4/127.0.0.1/tcp/0\"]"' test_expect_success "configure security transports" ' iptb run <