Skip to content

Releases: go-fileshare/fileshare

v0.31.0

Choose a tag to compare

@github-actions github-actions released this 18 Oct 14:42
b760279

What's Changed

  • internal/account: who a worker runs as (identity phase 1, step 2) by @tannevaled in #95
  • internal/launch and fileshare worker: start a person's worker as them (identity phase 1, step 3) by @tannevaled in #96
  • Serve directory shares as each person: identity phase 1 (SFTP, WebDAV) by @tannevaled in #97

Full Changelog: v0.30.0...v0.31.0

v0.30.0

Choose a tag to compare

@github-actions github-actions released this 18 Oct 07:46
373e691

What's Changed

  • release: run every binary on its own system before publishing (BSDs in a VM) by @tannevaled in #93
  • docs/identity.md: serving each person under their own system identity (design) by @tannevaled in #89
  • go-authn/directory v0.14.0: read what authnd v0.11.0 publishes by @tannevaled in #94

Full Changelog: v0.29.2...v0.30.0

v0.29.2: NetBSD and OpenBSD/arm64 binaries

Choose a tag to compare

@github-actions github-actions released this 17 Oct 20:24
4f5af84

fileshare serves a disk image, a device or a directory over SMB, NFS, WebDAV, SFTP and S3. The same users and the same per-share access apply over every protocol, and it all comes from one configuration file. It is pure Go, a single static binary, with no cgo.

New in v0.29.2: NetBSD (amd64) and OpenBSD on arm64. fileshare did not build on NetBSD. A dependency, awnumar/memcall v0.1.2 (via memguard v0.22.3 and OpenPubkey), used MADV_DONTDUMP, which NetBSD does not have. memguard v0.23.0 and memcall v0.4.0 fix that upstream. CI now cross-builds every release platform on every pull request, so a platform can no longer break unseen. The program is otherwise the same as v0.29.1.

Download and check

Pick the archive for your system below:

  • Linux: amd64, arm64, riscv64, ppc64le, s390x and loong64;
  • macOS: amd64 and arm64;
  • Windows: amd64 and arm64;
  • FreeBSD: amd64 and arm64;
  • OpenBSD: amd64 and arm64;
  • NetBSD: amd64.

Then check it, in either or both of these ways:

sha256sum -c --ignore-missing SHA256SUMS          # the file is the one published here
gh attestation verify fileshare_v0.29.2_linux_amd64.tar.gz -R go-fileshare/fileshare
                                                  # and GitHub Actions built it, from this tag

The archives are reproducible: hack/release.sh rebuilds them from a checkout of the tag, byte for byte. A Mac build and the Ubuntu CI build give identical SHA256SUMS, as measured on v0.29.1.

Try it in two minutes: a directory over WebDAV

tar -xzf fileshare_v0.29.2_linux_amd64.tar.gz && cd fileshare_v0.29.2_linux_amd64
mkdir shared
printf 'correct horse battery staple\n' > alice.pw && chmod 600 alice.pw
cat > fileshare.hcl <<'HCL'
user "alice" { password_file = "alice.pw" }

share "files" {
  directory = "shared"
  allow     = ["alice"]
  writers   = ["alice"]
}

serve "webdav" { addr = "127.0.0.1:8080" }
HCL
./fileshare check -c fileshare.hcl     # who gets what, over which protocol -- before serving
./fileshare -c fileshare.hcl           # webdav on 127.0.0.1:8080 -- files

From another terminal:

curl -u 'alice:correct horse battery staple' -T somefile http://127.0.0.1:8080/files/somefile   # 201
curl -u 'alice:correct horse battery staple' http://127.0.0.1:8080/files/somefile              # the file back
curl -i http://127.0.0.1:8080/files/somefile                                                   # 401: not anybody's

The file lands in shared/. Add serve "smb", serve "sftp", serve "s3" or serve "nfs" blocks for the other protocols; check says what each can carry.

The password comes from a file, never from a flag: a command-line argument is visible to every user in the process list. The documentation is at https://go-fileshare.github.io/docs/0.29/, in English, French, Spanish and German.

What changed

  • v0.29.2: NetBSD/amd64 and OpenBSD/arm64 binaries (memguard v0.23.0, memcall v0.4.0), and every release platform is cross-built in CI.
  • v0.29.1: on a reload, a group emptied in the directory grants nothing. The changes since v0.26.1 are listed on the v0.29.1 release.

Reporting a problem

Please open an issue at https://github.com/go-fileshare/fileshare/issues and include:

  • the output of fileshare --version;
  • your system;
  • the client you used;
  • fileshare check -c <your configuration>, with secrets removed.

v0.29.1: the first release with binaries

Choose a tag to compare

@github-actions github-actions released this 12 Oct 11:44
25dd5ce

fileshare serves a disk image, a device or a directory over SMB, NFS, WebDAV, SFTP and S3. The same users and the same per-share access apply over every protocol, and it all comes from one configuration file. It is pure Go, a single static binary, with no cgo.

This is the first release with prebuilt binaries, so you can try it without Go.

Download and check

Pick the archive for your system below:

  • Linux: amd64, arm64, riscv64, ppc64le, s390x and loong64;
  • macOS: amd64 and arm64;
  • Windows: amd64 and arm64;
  • FreeBSD: amd64 and arm64;
  • OpenBSD: amd64.

Then check it, in either or both of these ways:

sha256sum -c --ignore-missing SHA256SUMS          # the file is the one published here
gh attestation verify fileshare_v0.29.1_linux_amd64.tar.gz -R go-fileshare/fileshare
                                                  # and GitHub Actions built it, from this tag

The archives are reproducible: hack/release.sh rebuilds them from a checkout of the tag, byte for byte. A Mac build and the Ubuntu CI build of this release give identical SHA256SUMS.

Try it in two minutes: a directory over WebDAV

tar -xzf fileshare_v0.29.1_linux_amd64.tar.gz && cd fileshare_v0.29.1_linux_amd64
mkdir shared
printf 'correct horse battery staple\n' > alice.pw && chmod 600 alice.pw
cat > fileshare.hcl <<'HCL'
user "alice" { password_file = "alice.pw" }

share "files" {
  directory = "shared"
  allow     = ["alice"]
  writers   = ["alice"]
}

serve "webdav" { addr = "127.0.0.1:8080" }
HCL
./fileshare check -c fileshare.hcl     # who gets what, over which protocol -- before serving
./fileshare -c fileshare.hcl           # webdav on 127.0.0.1:8080 -- files

From another terminal:

curl -u 'alice:correct horse battery staple' -T somefile http://127.0.0.1:8080/files/somefile   # 201
curl -u 'alice:correct horse battery staple' http://127.0.0.1:8080/files/somefile              # the file back
curl -i http://127.0.0.1:8080/files/somefile                                                   # 401: not anybody's

The file lands in shared/. Add serve "smb", serve "sftp", serve "s3" or serve "nfs" blocks for the other protocols; check says what each can carry.

The password comes from a file, never from a flag: a command-line argument is visible to every user in the process list. The documentation is at https://go-fileshare.github.io/docs/0.29/, in English, French, Spanish and German.

Since the last release page (v0.26.1)

  • v0.27.0: with ACME, the certificate is now requested when the server starts, and retried with backoff while it keeps serving. A client that sends no SNI gets the first domain's certificate.
  • v0.28.0: the admin API is also served over HTTPS, for OIDC tokens (Connect, gRPC-Web and gRPC). This is what the web and native UIs use: portal, console, explorer.
  • v0.28.1, security: built with Go 1.27.2 and x/net v0.60.0, which fix GO-2026-6617 (an HTTP/2 HPACK race that could crash a server) and its batch.
  • v0.29.0, WebDAV:
    • a PROPFIND of the root lists the shares, so a file manager can mount the whole server;
    • an upload can go in pieces, each Content-Range appended where the last ended.
  • v0.29.1: on a reload, a group emptied in the directory grants nothing, just like a deleted group.

Reporting a problem

Please open an issue at https://github.com/go-fileshare/fileshare/issues and include:

  • the output of fileshare --version;
  • your system;
  • the client you used;
  • fileshare check -c <your configuration>, with secrets removed.

v0.26.1: command names

Choose a tag to compare

@tannevaled tannevaled released this 09 Oct 07:21
07c1c0b

Documentation only: the README names the go-authn commands by their new names, authn-bridge (go-authn/bridge v0.20.0) and authn-revokd (go-authn/revocation v0.6.0). No behaviour change.

v0.22.2: source-address tested beyond 127.0.0.1

Choose a tag to compare

@tannevaled tannevaled released this 07 Oct 15:54
efc8aa2

Tests and documentation only; no behaviour change.

  • source-address is now tested from ::1 and from a second IPv4 address (127.0.0.2), under ssh_domains, and on the OpenPubkey path (TestOpksshCertificateSourceAddress).
  • On Linux, these run under FILESHARE_REQUIRE_JUDGE: a missing judge fails instead of skipping.
  • README: the OpenPubkey path enforces source-address too.

v0.22.1: source-address certificates accepted under ssh_domains, from their own address

Choose a tag to compare

@tannevaled tannevaled released this 07 Oct 15:18
12c8baf

With ssh_domains set (v0.22.0), a certificate carrying the source-address critical option was refused even from an address it allows, because the SFTP server's certificate path refused every critical option. go-filesystems/sftp v0.5.1 (go-filesystems/sftp#20) accepts and enforces it there:

  • such a certificate is let in from its own address only, on the trusted_user_ca_file and OIDC ssh_ca_file paths alike;
  • every other critical option is still refused.

This means go-authn/bridge v0.19.0 certificates issued with ssh_source_address work under ssh_domains.

Tested with ssh-keygen-signed certificates through the OpenSSH sftp client; against sftp v0.5.0 the same test fails.

Dependencies: go-filesystems/sftp v0.5.1, go-filesystems/interface v0.4.0.

v0.22.0: SFTP certificates checked against the EuroHPC domain grant

Choose a tag to compare

@tannevaled tannevaled released this 07 Oct 11:32
b7b8230

SFTP certificates checked against the EuroHPC SSH CA profile's domain grant (ssh-domain-grant@core.aai.geant.org), through go-authn/sshcert v0.1.0.

  • ssh_domains = ["files.example.org"]: this host's names. A certificate signed by a trusted CA (trusted_user_ca_file, or the OIDC block's ssh_ca_file) is accepted only if its grant names one of them.
  • Fail-closed by default: a certificate with no grant is refused. ssh_accept_ungranted = true lets one in and logs it; a malformed grant is always refused.
  • Without ssh_domains, nothing changes, and a test proves it.
  • Metric: fileshare_sftp_domain_grant_total{result=…}.
  • Pairs with: go-authn/bridge v0.19.0's EFP-profile clients (ssh_domain_grants), and with EFP's own CA, whose key goes in trusted_user_ca_file.

Known limit: with ssh_domains set, a certificate carrying the source-address critical option is refused, even from an allowed address. The SFTP server checks these certificates with a CertChecker that refuses every critical option (go-filesystems/sftp). It fails closed.

go-authn/krl moves from v0.5.0 to v0.6.0, which sshcert requires.

v0.21.1

Choose a tag to compare

@tannevaled tannevaled released this 06 Oct 19:57
1f1f69f

A full share now says so on every protocol (#61):

  • SMB answers STATUS_DISK_FULL (0xC000007F) for no space and for an exceeded quota alike, as Samba does (go-filesystems/smb v0.4.1); it answered STATUS_ACCESS_DENIED.
  • NFS answers NFS3ERR_NOSPC (28) for no space and NFS3ERR_DQUOT (69) for a quota, as RFC 1813 and Linux's nfsd do (go-filesystems/nfs v0.6.1); a quota answered NFS3ERR_IO.
  • WebDAV 507 and SFTP "no space left on device (the share is full)" are unchanged.
  • On Windows hosts, ERROR_DISK_FULL / ERROR_DISK_QUOTA_EXCEEDED are recognised too.

Also: go-filesystems/smb v0.2.0 → v0.4.1 and nfs v0.5.0 → v0.6.1 bring their intermediate releases; a provisioner test no longer races the connection it has just seen closed.

v0.21.0: volumes — ZFS datasets, btrfs subvolumes, XFS/ext4 project quotas, as shares

Choose a tag to compare

@tannevaled tannevaled released this 06 Oct 19:14
09ffbf1

fileshare can now CREATE the storage a share serves, sized and tracked, through its admin gRPC API — and does it without becoming privileged itself (design: docs/volumes.md).

Two roles of one binary

  • fileshare provisioner (new, #59): a small privileged process (CAP_SYS_ADMIN, plus CAP_CHOWN/CAP_FOWNER) behind a unix socket, speaking a closed protocol (fileshare.provision.v1): GetCapabilities, CreateVolume, ResizeVolume, SnapshotVolume, DeleteVolume, GetVolume, ListVolumes. Only the configured uid is answered (SO_PEERCRED, checked before anything is decoded); an unknown method or a malformed message closes the connection. A request never carries a path — a parent id from the provisioner's own configuration and a name matched by a strict grammar. Every volume carries an ownership mark (ZFS: a fileshare:volume property set ON the dataset, not inherited; btrfs: subvolume id and uuid in its state; XFS/ext4: a project id from a configured range), checked before any resize, snapshot or delete. Create and delete are idempotent by name.
  • fileshare serve (#60) stays unprivileged and relays: the admin API gains ListParents, CreateVolume, ResizeVolume, SnapshotVolume, DeleteVolume, GetVolume, ListVolumes, and CreateShare accepts volume { parent, name } as a source. Before serving one it checks the path is under source_roots, a directory, on the expected filesystem (and a ZFS mount, a btrfs subvolume root, an XFS/ext4 directory with a project id).

Backends (go-fsctl v0.1.0, pure Go, no CLI): ZFS datasets with refquota, btrfs subvolumes with qgroup limits, XFS and ext4 directories with project quotas (new go-fsctl/projquota). Ceph is not supported yet.

Measured in CI as root on real pools and loop filesystems, with fileshare serve running as nobody and driven through the admin API: writes over WebDAV and SFTP stop at a 32 MiB volume's quota on all four kinds.

⛔ ext4 lets CAP_SYS_RESOURCE (root) write past a project quota, so fileshare serve refuses to serve volumes when it runs as root or holds CAP_SYS_RESOURCE in its effective or permitted set.

Also: ENOSPC and EDQUOT now give the same "full" answer (WebDAV 507, NFS NOSPC, SFTP "no space left"); SMB still answers access denied, pending go-filesystems/smb. The admin socket accepts an optional allowed_uids.