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.
Steven Allen committed
Feb 25, 2021 at 13:17 UTC
ccc2d237306c8f22630809292f1960eb87f242d1
13 files changed
+14
-364
cmd/seccat/.gitignore
deleted
-1
@@ -1 +0,0 @@
1
-seccat
cmd/seccat/seccat.go
deleted
-255
@@ -1,255 +0,0 @@
1
-// package main provides an implementation of netcat using the secio package.
2
-// This means the channel is encrypted (and MACed).
3
-// It is meant to exercise the spipe package.
4
-// Usage:
5
-// seccat [<local address>] <remote address>
6
-// seccat -l <local address>
7
-//
8
-// Address format is: [host]:port
9
-package main
10
-
11
-import (
12
- "context"
13
- "flag"
14
- "fmt"
15
- "io"
16
- "net"
17
- "os"
18
- "os/signal"
19
- "syscall"
20
-
21
- logging "github.com/ipfs/go-log"
22
- ci "github.com/libp2p/go-libp2p-core/crypto"
23
- peer "github.com/libp2p/go-libp2p-core/peer"
24
- pstore "github.com/libp2p/go-libp2p-core/peerstore"
25
- pstoremem "github.com/libp2p/go-libp2p-peerstore/pstoremem"
26
- secio "github.com/libp2p/go-libp2p-secio"
27
-)
28
-
29
-var verbose = false
30
-
31
-// Usage prints out the usage of this module.
32
-// Assumes flags use go stdlib flag package.
33
-var Usage = func() {
34
- text := `seccat - secure netcat in Go
35
-
36
-Usage:
37
-
38
- listen: %s [<local address>] <remote address>
39
- dial: %s -l <local address>
40
-
41
-Address format is Go's: [host]:port
42
-`
43
-
44
- fmt.Fprintf(os.Stderr, text, os.Args[0], os.Args[0])
45
- flag.PrintDefaults()
46
-}
47
-
48
-type args struct {
49
- listen bool
50
- verbose bool
51
- debug bool
52
- localAddr string
53
- remoteAddr string
54
- // keyfile string
55
- keybits int
56
-}
57
-
58
-func parseArgs() args {
59
- var a args
60
-
61
- // setup + parse flags
62
- flag.BoolVar(&a.listen, "listen", false, "listen for connections")
63
- flag.BoolVar(&a.listen, "l", false, "listen for connections (short)")
64
- flag.BoolVar(&a.verbose, "v", true, "verbose")
65
- flag.BoolVar(&a.debug, "debug", false, "debugging")
66
- // flag.StringVar(&a.keyfile, "key", "", "private key file")
67
- flag.IntVar(&a.keybits, "keybits", 2048, "num bits for generating private key")
68
- flag.Usage = Usage
69
- flag.Parse()
70
- osArgs := flag.Args()
71
-
72
- if len(osArgs) < 1 {
73
- exit("")
74
- }
75
-
76
- if a.verbose {
77
- out("verbose on")
78
- }
79
-
80
- if a.listen {
81
- a.localAddr = osArgs[0]
82
- } else {
83
- if len(osArgs) > 1 {
84
- a.localAddr = osArgs[0]
85
- a.remoteAddr = osArgs[1]
86
- } else {
87
- a.remoteAddr = osArgs[0]
88
- }
89
- }
90
-
91
- return a
92
-}
93
-
94
-func main() {
95
- args := parseArgs()
96
- verbose = args.verbose
97
- if args.debug {
98
- logging.SetDebugLogging()
99
- }
100
-
101
- go func() {
102
- // wait until we exit.
103
- sigc := make(chan os.Signal, 1)
104
- signal.Notify(sigc, syscall.SIGABRT)
105
- <-sigc
106
- panic("ABORT! ABORT! ABORT!")
107
- }()
108
-
109
- if err := connect(args); err != nil {
110
- exit("%s", err)
111
- }
112
-}
113
-
114
-func setupPeer(a args) (peer.ID, pstore.Peerstore, error) {
115
- if a.keybits < ci.MinRsaKeyBits {
116
- return "", nil, ci.ErrRsaKeyTooSmall
117
- }
118
-
119
- out("generating key pair...")
120
- sk, pk, err := ci.GenerateKeyPair(ci.RSA, a.keybits)
121
- if err != nil {
122
- return "", nil, err
123
- }
124
-
125
- p, err := peer.IDFromPublicKey(pk)
126
- if err != nil {
127
- return "", nil, err
128
- }
129
-
130
- ps := pstoremem.NewPeerstore()
131
- err = ps.AddPrivKey(p, sk)
132
- if err != nil {
133
- return "", nil, err
134
- }
135
- err = ps.AddPubKey(p, pk)
136
- if err != nil {
137
- return "", nil, err
138
- }
139
-
140
- out("local peer id: %s", p)
141
- return p, ps, nil
142
-}
143
-
144
-func connect(args args) error {
145
- p, ps, err := setupPeer(args)
146
- if err != nil {
147
- return err
148
- }
149
-
150
- var conn net.Conn
151
- if args.listen {
152
- conn, err = Listen(args.localAddr)
153
- } else {
154
- conn, err = Dial(args.localAddr, args.remoteAddr)
155
- }
156
- if err != nil {
157
- return err
158
- }
159
-
160
- // log everything that goes through conn
161
- rwc := &logConn{n: "conn", Conn: conn}
162
-
163
- // OK, let's setup the channel.
164
- sk := ps.PrivKey(p)
165
- sg, err := secio.New(sk)
166
- if err != nil {
167
- return err
168
- }
169
- sconn, err := sg.SecureInbound(context.TODO(), rwc)
170
- if err != nil {
171
- return err
172
- }
173
- out("remote peer id: %s", sconn.RemotePeer())
174
- netcat(sconn)
175
- return nil
176
-}
177
-
178
-// Listen listens and accepts one incoming UDT connection on a given port,
179
-// and pipes all incoming data to os.Stdout.
180
-func Listen(localAddr string) (net.Conn, error) {
181
- l, err := net.Listen("tcp", localAddr)
182
- if err != nil {
183
- return nil, err
184
- }
185
- out("listening at %s", l.Addr())
186
-
187
- c, err := l.Accept()
188
- if err != nil {
189
- return nil, err
190
- }
191
- out("accepted connection from %s", c.RemoteAddr())
192
-
193
- // done with listener
194
- l.Close()
195
-
196
- return c, nil
197
-}
198
-
199
-// Dial connects to a remote address and pipes all os.Stdin to the remote end.
200
-// If localAddr is set, uses it to Dial from.
201
-func Dial(localAddr, remoteAddr string) (net.Conn, error) {
202
-
203
- var laddr net.Addr
204
- var err error
205
- if localAddr != "" {
206
- laddr, err = net.ResolveTCPAddr("tcp", localAddr)
207
- if err != nil {
208
- return nil, fmt.Errorf("failed to resolve address %s", localAddr)
209
- }
210
- }
211
-
212
- if laddr != nil {
213
- out("dialing %s from %s", remoteAddr, laddr)
214
- } else {
215
- out("dialing %s", remoteAddr)
216
- }
217
-
218
- d := net.Dialer{LocalAddr: laddr}
219
- c, err := d.Dial("tcp", remoteAddr)
220
- if err != nil {
221
- return nil, err
222
- }
223
- out("connected to %s", c.RemoteAddr())
224
-
225
- return c, nil
226
-}
227
-
228
-func netcat(c io.ReadWriteCloser) {
229
- out("piping stdio to connection")
230
-
231
- done := make(chan struct{}, 2)
232
-
233
- go func() {
234
- n, _ := io.Copy(c, os.Stdin)
235
- out("sent %d bytes", n)
236
- done <- struct{}{}
237
- }()
238
- go func() {
239
- n, _ := io.Copy(os.Stdout, c)
240
- out("received %d bytes", n)
241
- done <- struct{}{}
242
- }()
243
-
244
- // wait until we exit.
245
- sigc := make(chan os.Signal, 1)
246
- signal.Notify(sigc, notifySignals...)
247
-
248
- select {
249
- case <-done:
250
- case <-sigc:
251
- return
252
- }
253
-
254
- c.Close()
255
-}
cmd/seccat/seccat_plan9.go
deleted
-8
@@ -1,8 +0,0 @@
1
-package main
2
-
3
-import (
4
- "os"
5
- "syscall"
6
-)
7
-
8
-var notifySignals = []os.Signal{syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM}
cmd/seccat/seccat_posix.go
deleted
-10
@@ -1,10 +0,0 @@
1
-// +build !plan9
2
-
3
-package main
4
-
5
-import (
6
- "os"
7
- "syscall"
8
-)
9
-
10
-var notifySignals = []os.Signal{syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT}
cmd/seccat/util.go
deleted
-47
@@ -1,47 +0,0 @@
1
-package main
2
-
3
-import (
4
- "fmt"
5
- "net"
6
- "os"
7
-
8
- logging "github.com/ipfs/go-log"
9
-)
10
-
11
-var log = logging.Logger("seccat")
12
-
13
-func exit(format string, vals ...interface{}) {
14
- if format != "" {
15
- fmt.Fprintf(os.Stderr, "seccat: error: "+format+"\n", vals...)
16
- }
17
- Usage()
18
- os.Exit(1)
19
-}
20
-
21
-func out(format string, vals ...interface{}) {
22
- if verbose {
23
- fmt.Fprintf(os.Stderr, "seccat: "+format+"\n", vals...)
24
- }
25
-}
26
-
27
-type logConn struct {
28
- net.Conn
29
- n string
30
-}
31
-
32
-func (r *logConn) Read(buf []byte) (int, error) {
33
- n, err := r.Conn.Read(buf)
34
- if n > 0 {
35
- log.Debugf("%s read: %v", r.n, buf)
36
- }
37
- return n, err
38
-}
39
-
40
-func (r *logConn) Write(buf []byte) (int, error) {
41
- log.Debugf("%s write: %v", r.n, buf)
42
- return r.Conn.Write(buf)
43
-}
44
-
45
-func (r *logConn) Close() error {
46
- return r.Conn.Close()
47
-}
core/node/libp2p/sec.go
+9
-5
@@ -4,10 +4,14 @@ import (
4
config "github.com/ipfs/go-ipfs-config"
5
"github.com/libp2p/go-libp2p"
6
noise "github.com/libp2p/go-libp2p-noise"
7
- secio "github.com/libp2p/go-libp2p-secio"
7
tls "github.com/libp2p/go-libp2p-tls"
8
)
9
10
+const secioEnabledWarning = `The SECIO security transport was enabled in the config but is no longer supported.
11
+
12
+SECIO disabled by default in go-ipfs 0.7 removed in go-ipfs 0.9. Please remove
13
+Swarm.Transports.Security.SECIO from your IPFS config.`
14
+
15
func Security(enabled bool, tptConfig config.Transports) interface{} {
16
if !enabled {
17
return func() (opts Libp2pOpts) {
@@ -18,16 +22,16 @@ func Security(enabled bool, tptConfig config.Transports) interface{} {
22
}
23
}
24
25
+ if _, enabled := tptConfig.Security.SECIO.WithDefault(config.Disabled); enabled {
26
+ log.Error(secioEnabledWarning)
27
+ }
28
+
29
// Using the new config options.
30
return func() (opts Libp2pOpts) {
31
opts.Opts = append(opts.Opts, prioritizeOptions([]priorityOption{{
32
priority: tptConfig.Security.TLS,
33
defaultPriority: 100,
34
opt: libp2p.Security(tls.ID, tls.New),
27
- }, {
28
- priority: tptConfig.Security.SECIO,
29
- defaultPriority: config.Disabled,
30
- opt: libp2p.Security(secio.ID, secio.New),
35
}, {
36
priority: tptConfig.Security.Noise,
37
defaultPriority: 300,
docs/config.md
+2
-10
@@ -1352,8 +1352,7 @@ receiver supports. When establishing an _inbound_ connection, go-ipfs will let
1352
the initiator choose the protocol, but will refuse to use any of the disabled
1353
transports.
1354
1355
-Supported transports are: TLS (priority 100), SECIO (Disabled: i.e. priority false), Noise
1356
-(priority 300).
1355
+Supported transports are: TLS (priority 100) and Noise (priority 300).
1356
1357
No default priority will ever be less than 100.
1358
@@ -1369,14 +1368,7 @@ Type: `priority`
1368
1369
#### `Swarm.Transports.Security.SECIO`
1370
1372
-[SECIO](https://github.com/libp2p/specs/tree/master/secio) was the most widely
1373
-supported IPFS & libp2p security transport. However, it is currently being
1374
-phased out in favor of more popular and better vetted protocols like TLS and
1375
-Noise.
1376
-
1377
-Default: `false`
1378
-
1379
-Type: `priority`
1371
+Support for SECIO has been removed. Please remove this option from your config.
1372
1373
#### `Swarm.Transports.Security.Noise`
1374
docs/experimental-features.md
+2
-22
@@ -544,26 +544,6 @@ ipfs config --json Experimental.GraphsyncEnabled true
544
545
### State
546
547
-Experimental, enabled by default
547
+Stable, enabled by default
548
549
-[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.
550
-
551
-### How to enable
552
-
553
-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:
554
-
555
-```
556
-ipfs config --json Swarm.Transports.Security.Noise 1
557
-```
558
-
559
-Or even disable TLS and/or SECIO (not recommended for the moment):
560
-
561
-```
562
-ipfs config --json Swarm.Transports.Security.TLS false
563
-ipfs config --json Swarm.Transports.Security.SECIO false
564
-```
565
-
566
-### Road to being a real feature
567
-
568
-- [ ] Needs real-world testing.
569
-- [ ] Ideally a js-ipfs and a rust-ipfs release would include support for Noise.
549
+[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.
go.mod
-1
@@ -78,7 +78,6 @@ require (
78
github.com/libp2p/go-libp2p-quic-transport v0.10.0
79
github.com/libp2p/go-libp2p-record v0.1.3
80
github.com/libp2p/go-libp2p-routing-helpers v0.2.3
81
- github.com/libp2p/go-libp2p-secio v0.2.2
81
github.com/libp2p/go-libp2p-swarm v0.4.0
82
github.com/libp2p/go-libp2p-testing v0.4.0
83
github.com/libp2p/go-libp2p-tls v0.1.3
go.sum
-1
@@ -638,7 +638,6 @@ github.com/libp2p/go-libp2p-secio v0.0.3/go.mod h1:hS7HQ00MgLhRO/Wyu1bTX6ctJKhVp
638
github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8=
639
github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g=
640
github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8=
641
-github.com/libp2p/go-libp2p-secio v0.2.2 h1:rLLPvShPQAcY6eNurKNZq3eZjPWfU9kXF2eI9jIYdrg=
641
github.com/libp2p/go-libp2p-secio v0.2.2/go.mod h1:wP3bS+m5AUnFA+OFO7Er03uO1mncHG0uVwGrwvjYlNY=
642
github.com/libp2p/go-libp2p-swarm v0.0.6/go.mod h1:s5GZvzg9xXe8sbeESuFpjt8CJPTCa8mhEusweJqyFy8=
643
github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4=
test/sharness/t0061-daemon-opts.sh
-1
@@ -19,7 +19,6 @@ apiaddr=$API_ADDR
19
# Odd. this fails here, but the inverse works on t0060-daemon.
20
test_expect_success SOCAT 'transport should be unencrypted ( needs socat )' '
21
socat - tcp:localhost:$SWARM_PORT,connect-timeout=1 > swarmnc < ../t0060-data/mss-ls &&
22
- grep -q -v "/secio" swarmnc &&
22
grep -q "/plaintext" swarmnc ||
23
test_fsh cat swarmnc
24
'
test/sharness/t0125-twonode.sh
+1
-2
@@ -119,8 +119,7 @@ test_expect_success "re-enable yamux" '
119
120
echo "Running advanced tests with NOISE"
121
test_expect_success "use noise only" '
122
- iptb run -- ipfs config --json Swarm.Transports.Security.TLS false &&
123
- iptb run -- ipfs config --json Swarm.Transports.Security.Secio false
122
+ iptb run -- ipfs config --json Swarm.Transports.Security.TLS false
123
'
124
125
run_advanced_test
test/sharness/t0191-noise.sh
-1
@@ -15,7 +15,6 @@ tcp_addr='"[\"/ip4/127.0.0.1/tcp/0\"]"'
15
test_expect_success "configure security transports" '
16
iptb run <<CMDS
17
[0,1] -- ipfs config --json Swarm.Transports.Security.TLS false &&
18
- [0,1] -- ipfs config --json Swarm.Transports.Security.SECIO false &&
18
2 -- ipfs config --json Swarm.Transports.Security.Noise false &&
19
-- ipfs config --json Addresses.Swarm '${tcp_addr}'
20
CMDS