Skip to content

Commit

Permalink
Merge pull request #804 from AkihiroSuda/sshocker-0.3.0
Browse files Browse the repository at this point in the history
sshfs: support setting `sftpDriver: "openssh-sftp-server"`
  • Loading branch information
jandubois authored Apr 18, 2022
2 parents 30864a1 + ae059f0 commit e237573
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 6 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ The current default spec:
## How it works

- Hypervisor: QEMU with HVF accelerator
- Filesystem sharing: [reverse sshfs](https://github.com/lima-vm/sshocker/blob/v0.2.0/pkg/reversesshfs/reversesshfs.go) (likely to be replaced with 9p or Samba in future)
- Filesystem sharing: [Reverse SSHFS (default), or virtio-9p-pci aka virtfs](./docs/mount.md)
- Port forwarding: `ssh -L`, automated by watching `/proc/net/tcp` and `iptables` events in the guest

## Developer guide
Expand All @@ -266,6 +266,7 @@ The current default spec:
- Performance optimization
- More guest distros
- Windows hosts
- virtio-fs to replace virtio-9p-pci aka virtfs (work has to be done on QEMU repo)
- [vsock](https://github.com/apple/darwin-xnu/blob/xnu-7195.81.3/bsd/man/man4/vsock.4) to replace SSH (work has to be done on QEMU repo)

## FAQs & Troubleshooting
Expand Down
77 changes: 77 additions & 0 deletions docs/mount.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Filesystem mounts

Lima supports several methods for mounting the host filesystem into the guest.

The default mount type is shown in the following table:

| Lima Version | Default |
| ---------------- | ----------------------------------- |
| < 0.10 | reverse-sshfs + Builtin SFTP server |
| >= 0.10 | reverse-sshfs + OpenSSH SFTP server |
| >= 1.0 (Planned) | 9p |

## Mount types

### reverse-sshfs
The "reverse-sshfs" mount type exposes the host filesystem by running an SFTP server on the host.
While the host works as an SFTP server, the host does not open any TCP port,
as the host initiates an SSH connection into the guest and let the guest connect to the SFTP server via the stdin.

An example configuration:
```yaml
mountType: "reverse-sshfs"
mounts:
- location: "~"
sshfs:
# Enabling the SSHFS cache will increase performance of the mounted filesystem, at
# the cost of potentially not reflecting changes made on the host in a timely manner.
# Warning: It looks like PHP filesystem access does not work correctly when
# the cache is disabled.
# 🟢 Builtin default: true
cache: null
# SSHFS has an optional flag called 'follow_symlinks'. This allows mounts
# to be properly resolved in the guest os and allow for access to the
# contents of the symlink. As a result, symlinked files & folders on the Host
# system will look and feel like regular files directories in the Guest OS.
# 🟢 Builtin default: false
followSymlinks: null
# SFTP driver, "builtin" or "openssh-sftp-server". "openssh-sftp-server" is recommended.
# 🟢 Builtin default: "openssh-sftp-server" if OpenSSH SFTP Server binary is found, otherwise "builtin"
sftpDriver: null
```
The default value of `sftpDriver` has been set to "openssh-sftp-server" since Lima v0.10, when an OpenSSH SFTP Server binary
such as `/usr/libexec/sftp-server` is detected on the host.
Lima prior to v0.10 had used "builtin" as the SFTP driver.

#### Caveats
- A mount is disabled when the SSH connection was shut down.
- A compromised `sshfs` process in the guest may have an access to unexposed host directories.

### 9p
The "9p" mount type is implemented by using QEMU's virtio-9p-pci devices.
virtio-9p-pci is also known as "virtfs", but note that this is unrelated to [virtio-fs](https://virtio-fs.gitlab.io/).

An example configuration:
```yaml
mountType: "9p"
mounts:
- location: "~"
9p:
# Supported security models are "passthrough", "mapped-xattr", "mapped-file" and "none".
# 🟢 Builtin default: "mapped-xattr"
securityModel: null
# Select 9P protocol version. Valid options are: "9p2000" (legacy), "9p2000.u", "9p2000.L".
# 🟢 Builtin default: "9p2000.L"
protocolVersion: null
# The number of bytes to use for 9p packet payload, where 4KiB is the absolute minimum.
# 🟢 Builtin default: "128KiB"
msize: null
# Specifies a caching policy. Valid options are: "none", "loose", "fscache" and "mmap".
# Try choosing "mmap" or "none" if you see a stability issue with the default "fscache".
# See https://www.kernel.org/doc/Documentation/filesystems/9p.txt
# 🟢 Builtin default: "fscache" for non-writable mounts, "mmap" for writable mounts
cache: null
```
#### Caveats
- The "9p" mount type is known to be incompatible with CentOS, Rocky Linux, and AlmaLinux as their kernel do not support `CONFIG_NET_9P_VIRTIO`.
3 changes: 3 additions & 0 deletions examples/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ mounts:
# system will look and feel like regular files directories in the Guest OS.
# 🟢 Builtin default: false
followSymlinks: null
# SFTP driver, "builtin" or "openssh-sftp-server". "openssh-sftp-server" is recommended.
# 🟢 Builtin default: "openssh-sftp-server" if OpenSSH SFTP Server binary is found, otherwise "builtin"
sftpDriver: null
9p:
# Supported security models are "passthrough", "mapped-xattr", "mapped-file" and "none".
# 🟢 Builtin default: "mapped-xattr"
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ require (
github.com/google/go-cmp v0.5.7
github.com/gorilla/mux v1.8.0
github.com/hashicorp/go-multierror v1.1.1
github.com/lima-vm/sshocker v0.2.3
github.com/lima-vm/sshocker v0.3.0
github.com/mattn/go-isatty v0.0.14
github.com/mattn/go-shellwords v1.0.12
github.com/miekg/dns v1.1.48
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lima-vm/sshocker v0.2.3 h1:z4xTGS51Bo03adLHcetl3WjSK4zbJeFe6GT0ChiZI7I=
github.com/lima-vm/sshocker v0.2.3/go.mod h1:tdwxS0o2d2vNfe2CN+QN9J8XF3VPX4y9IUu7fpy2ibc=
github.com/lima-vm/sshocker v0.3.0 h1:4W7AFfwqkhPwBIOtwfnxxggdS3/bs6JkTYT1RfrXwfQ=
github.com/lima-vm/sshocker v0.3.0/go.mod h1:LtQ68MCRh2MPgAczFNyElrOObNR1lsb31YCeFGgeLyc=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
Expand Down
1 change: 1 addition & 0 deletions pkg/hostagent/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func (a *HostAgent) setupMount(ctx context.Context, m limayaml.Mount) (*mount, e
}
logrus.Infof("Mounting %q", expanded)
rsf := &reversesshfs.ReverseSSHFS{
Driver: *m.SSHFS.SFTPDriver,
SSHConfig: a.sshConfig,
LocalPath: expanded,
Host: "127.0.0.1",
Expand Down
6 changes: 6 additions & 0 deletions pkg/limayaml/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,9 @@ func FillDefault(y, d, o *LimaYAML, filePath string) {
if mount.SSHFS.FollowSymlinks != nil {
mounts[i].SSHFS.FollowSymlinks = mount.SSHFS.FollowSymlinks
}
if mount.SSHFS.SFTPDriver != nil {
mounts[i].SSHFS.SFTPDriver = mount.SSHFS.SFTPDriver
}
if mount.NineP.SecurityModel != nil {
mounts[i].NineP.SecurityModel = mount.NineP.SecurityModel
}
Expand Down Expand Up @@ -406,6 +409,9 @@ func FillDefault(y, d, o *LimaYAML, filePath string) {
if mount.SSHFS.FollowSymlinks == nil {
mount.SSHFS.FollowSymlinks = pointer.Bool(false)
}
if mount.SSHFS.SFTPDriver == nil {
mount.SSHFS.SFTPDriver = pointer.String("")
}
if mount.NineP.SecurityModel == nil {
mounts[i].NineP.SecurityModel = pointer.String(Default9pSecurityModel)
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/limayaml/defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ func TestFillDefault(t *testing.T) {
expect.Mounts[0].Writable = pointer.Bool(false)
expect.Mounts[0].SSHFS.Cache = pointer.Bool(true)
expect.Mounts[0].SSHFS.FollowSymlinks = pointer.Bool(false)
expect.Mounts[0].SSHFS.SFTPDriver = pointer.String("")
expect.Mounts[0].NineP.SecurityModel = pointer.String(Default9pSecurityModel)
expect.Mounts[0].NineP.ProtocolVersion = pointer.String(Default9pProtocolVersion)
expect.Mounts[0].NineP.Msize = pointer.String(Default9pMsize)
Expand Down Expand Up @@ -297,6 +298,7 @@ func TestFillDefault(t *testing.T) {
expect.Containerd.Archives[0].Arch = *d.Arch
expect.Mounts[0].SSHFS.Cache = pointer.Bool(true)
expect.Mounts[0].SSHFS.FollowSymlinks = pointer.Bool(false)
expect.Mounts[0].SSHFS.SFTPDriver = pointer.String("")
expect.Mounts[0].NineP.SecurityModel = pointer.String(Default9pSecurityModel)
expect.Mounts[0].NineP.ProtocolVersion = pointer.String(Default9pProtocolVersion)
expect.Mounts[0].NineP.Msize = pointer.String(Default9pMsize)
Expand Down
12 changes: 10 additions & 2 deletions pkg/limayaml/limayaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,17 @@ type Mount struct {
NineP NineP `yaml:"9p,omitempty" json:"9p,omitempty"`
}

type SFTPDriver = string

const (
SFTPDriverBuiltin = "builtin"
SFTPDriverOpenSSHSFTPServer = "openssh-sftp-server"
)

type SSHFS struct {
Cache *bool `yaml:"cache,omitempty" json:"cache,omitempty"`
FollowSymlinks *bool `yaml:"followSymlinks,omitempty" json:"followSymlinks,omitempty"`
Cache *bool `yaml:"cache,omitempty" json:"cache,omitempty"`
FollowSymlinks *bool `yaml:"followSymlinks,omitempty" json:"followSymlinks,omitempty"`
SFTPDriver *SFTPDriver `yaml:"sftpDriver,omitempty" json:"sftpDriver,omitempty"`
}

type NineP struct {
Expand Down

0 comments on commit e237573

Please sign in to comment.