Skip to content

Commit 852704b

Browse files
committed
Compatibility with OpenSSH 7.1p1 (Ubuntu 18.04 LTS)
The feature to add algorithms to the front of the default set by using a leading `^` has been added in OpenSSH 8.0 and cause an error on earlier versions. Specifying a different cipher is just a (minor) performance tweak, not a requirement. Signed-off-by: Jan Dubois <jan.dubois@suse.com>
1 parent 9daceae commit 852704b

File tree

3 files changed

+55
-14
lines changed

3 files changed

+55
-14
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ require (
88
github.com/cheggaaa/pb/v3 v3.0.8
99
github.com/containerd/containerd v1.5.7
1010
github.com/containerd/continuity v0.2.0
11+
github.com/coreos/go-semver v0.3.0
1112
github.com/digitalocean/go-qemu v0.0.0-20210326154740-ac9e0b687001
1213
github.com/diskfs/go-diskfs v1.2.0
1314
github.com/docker/go-units v0.4.0

go.sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmeka
247247
github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
248248
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
249249
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
250+
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
250251
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
251252
github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
252253
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=

pkg/sshutil/sshutil.go

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
package sshutil
22

33
import (
4+
"bytes"
45
"errors"
56
"fmt"
67
"io/fs"
78
"os"
89
"os/exec"
910
"path/filepath"
11+
"regexp"
1012
"strings"
13+
"sync"
1114

15+
"github.com/coreos/go-semver/semver"
1216
"github.com/lima-vm/lima/pkg/lockutil"
1317
"github.com/lima-vm/lima/pkg/osutil"
1418
"github.com/lima-vm/lima/pkg/store/dirnames"
@@ -102,6 +106,15 @@ func DefaultPubKeys(loadDotSSH bool) ([]PubKey, error) {
102106
return res, nil
103107
}
104108

109+
var sshInfo struct {
110+
sync.Once
111+
// aesAccelerated is set to true when AES acceleration is available.
112+
// Available on almost all modern Intel/AMD processors.
113+
aesAccelerated bool
114+
// openSSHVersion is set to the version of OpenSSH, or semver.New("0.0.0") if the version cannot be determined.
115+
openSSHVersion semver.Version
116+
}
117+
105118
func CommonArgs(useDotSSH bool) ([]string, error) {
106119
configDir, err := dirnames.LimaConfigDir()
107120
if err != nil {
@@ -159,16 +172,24 @@ func CommonArgs(useDotSSH bool) ([]string, error) {
159172
"-F", "/dev/null",
160173
)
161174

162-
// By default, `ssh` choose chacha20-poly1305@openssh.com, even when AES accelerator is available.
163-
// (OpenSSH_8.1p1, macOS 11.6, MacBookPro 2020, Core i7-1068NG7)
164-
//
165-
// We prioritize AES algorithms when AES accelerator is available.
166-
if aesAccelerated {
167-
logrus.Debugf("AES accelerator seems available, prioritizing aes128-gcm@openssh.com and aes256-gcm@openssh.com")
168-
args = append(args, "-o", "Ciphers=^aes128-gcm@openssh.com,aes256-gcm@openssh.com")
169-
} else {
170-
logrus.Debugf("AES accelerator does not seem available, prioritizing chacha20-poly1305@openssh.com")
171-
args = append(args, "-o", "Ciphers=^chacha20-poly1305@openssh.com")
175+
sshInfo.Do(func() {
176+
sshInfo.aesAccelerated = detectAESAcceleration()
177+
sshInfo.openSSHVersion = detectOpenSSHVersion()
178+
})
179+
180+
// Only OpenSSH version 8.0 and later support adding ciphers to the front of the default set
181+
if !sshInfo.openSSHVersion.LessThan(*semver.New("8.0.0")) {
182+
// By default, `ssh` choose chacha20-poly1305@openssh.com, even when AES accelerator is available.
183+
// (OpenSSH_8.1p1, macOS 11.6, MacBookPro 2020, Core i7-1068NG7)
184+
//
185+
// We prioritize AES algorithms when AES accelerator is available.
186+
if sshInfo.aesAccelerated {
187+
logrus.Debugf("AES accelerator seems available, prioritizing aes128-gcm@openssh.com and aes256-gcm@openssh.com")
188+
args = append(args, "-o", "Ciphers=^aes128-gcm@openssh.com,aes256-gcm@openssh.com")
189+
} else {
190+
logrus.Debugf("AES accelerator does not seem available, prioritizing chacha20-poly1305@openssh.com")
191+
args = append(args, "-o", "Ciphers=^chacha20-poly1305@openssh.com")
192+
}
172193
}
173194
return args, nil
174195
}
@@ -195,7 +216,25 @@ func SSHArgs(instDir string, useDotSSH bool) ([]string, error) {
195216
return args, nil
196217
}
197218

198-
// aesAccelerated is set to true when AES acceleration is available.
199-
//
200-
// Available on almost all modern Intel/AMD processors.
201-
var aesAccelerated = detectAESAcceleration()
219+
func detectOpenSSHVersion() semver.Version {
220+
var (
221+
v semver.Version
222+
stderr bytes.Buffer
223+
)
224+
cmd := exec.Command("ssh", "-V")
225+
cmd.Stderr = &stderr
226+
if err := cmd.Run(); err != nil {
227+
logrus.Warn("failed to run %v: stderr=%q", cmd.Args, stderr.String())
228+
} else {
229+
regex := regexp.MustCompile(`^OpenSSH_(\d+\.\d+)(?:p(\d+))?\b`)
230+
matches := regex.FindSubmatch(stderr.Bytes())
231+
if len(matches) == 3 {
232+
if len(matches[2]) == 0 {
233+
matches[2] = []byte("0")
234+
}
235+
v = *semver.New(fmt.Sprintf("%s.%s", matches[1], matches[2]))
236+
}
237+
}
238+
logrus.Debugf("OpenSSH version %s detected", v)
239+
return v
240+
}

0 commit comments

Comments
 (0)