mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-21 10:27:46 +08:00
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.
This commit is contained in:
parent
6527675401
commit
ccc2d23730
1
cmd/seccat/.gitignore
vendored
1
cmd/seccat/.gitignore
vendored
@ -1 +0,0 @@
|
||||
seccat
|
||||
@ -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 [<local address>] <remote address>
|
||||
// seccat -l <local address>
|
||||
//
|
||||
// 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 [<local address>] <remote address>
|
||||
dial: %s -l <local address>
|
||||
|
||||
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()
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
var notifySignals = []os.Signal{syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM}
|
||||
@ -1,10 +0,0 @@
|
||||
// +build !plan9
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
var notifySignals = []os.Signal{syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT}
|
||||
@ -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()
|
||||
}
|
||||
@ -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,
|
||||
|
||||
@ -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`
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
1
go.mod
1
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
|
||||
|
||||
1
go.sum
1
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=
|
||||
|
||||
@ -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
|
||||
'
|
||||
|
||||
@ -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
|
||||
|
||||
@ -15,7 +15,6 @@ tcp_addr='"[\"/ip4/127.0.0.1/tcp/0\"]"'
|
||||
test_expect_success "configure security transports" '
|
||||
iptb run <<CMDS
|
||||
[0,1] -- ipfs config --json Swarm.Transports.Security.TLS false &&
|
||||
[0,1] -- ipfs config --json Swarm.Transports.Security.SECIO false &&
|
||||
2 -- ipfs config --json Swarm.Transports.Security.Noise false &&
|
||||
-- ipfs config --json Addresses.Swarm '${tcp_addr}'
|
||||
CMDS
|
||||
|
||||
Loading…
Reference in New Issue
Block a user