SMB3 With NixOS
Adding SMB3 to a NixOS client
Samba recently gained support for the POSIX Extensions for SMB3 which add some features you’d expect from a Linux filesystem, like symbolic links. These are different from SMB1 Unix extensions. They were introduced in Samba 4.23, which by now is in Nixpkgs. Here’s a quick write-up on how to use them. Note that this isn’t a full SMB on NixOS tutorial, you can just consult the wiki for that.
Server settings
There isn’t really much to change here, in fact I changed nothing and it just
worked. But it’s probably a good idea to have "server min protocol" = "SMB3";
in your config unless you have some really old clients that require an older
protocol version.
Client settings
My NixOS client settings should look somewhat like this:
1fileSystems."/mnt/smb/network-mount" = {
2 device = "//network/path/to/mount";
3 fsType = "smb3";
4 options = [
5 "x-systemd.automount"
6 "noauto"
7 "credentials=${config.sops.secrets.smb.path}"
8 "vers=3.1.1"
9 "posix"
10 "mfsymlinks"
11 "nomapposix"
12 "noperm"
13 ];I took these options from the Samba wiki under the link in the first paragraph.
The first three options aren’t really relevant to this particular change and
rather concern automatic mounting and secrets handling. vers=3.1.1 enables
the latest version of SMB, though automatic negotiation should also yield that
version if your server is configured properly. posix (also available as unix
and linux) enables the new extensions for this mount. Interesting enough, this
is the same switch that enables them for the old CIFS protocol, and for that
reason, some people have these explicitly disabled. posix is the default, so
you don’t need to specify it. noperm disables client permission checks, which
from my understanding is needed in most environments because it only works when
server UIDs and client UIDs map. The client will check for for permissions and
the checks will most likely fail because of the mismatch. Server-side checks
are unaffected.
However, if you try to mount this without any further settings, you’ll see it
fail. It turns out that cifs-utils from nixpkgs are required to mount SMB3
shares or else you’ll get a cryptic error message about lack of permissions or a
device not being read-write.
So you can do what a normal person would do (though I’m not sure they’d be using
NixOS in the first place) and just add environment.systemPackages = [ pkgs.cifs-utils ];
to your config and go your merry way.
Or…
Writing a NixOS module to conditionally add cifs-utils to your system packages
Of course, all this was just a pretense to justify writing another real NixOS module, not those static semi-configuration files, and I’m gonna tell you about it.

Me right now
Using the infrastructure from a previous
post,
this flake will add cifs-utils to your system packages if at least one mount has the type “smb3”:
1{
2 flake.modules.nixos.cifsUtilsForSMB3 =
3 {
4 config,
5 lib,
6 pkgs,
7 ...
8 }:
9 {
10 environment.systemPackages = lib.mkIf (builtins.any (x: x.fsType == "smb3") (
11 builtins.attrValues config.fileSystems
12 )) [ pkgs.cifs-utils ];
13 };
14}This creates a list from all filesystem for the given host (builtins.attrValues config.fileSystems), and if any attribute set in that list has "smb3" at
type, adds cifs-utils to the list of system packages (duh).
With this name, you could modify nixos-module-export.nix to also import
cifsUtilsForSMB3, update your host inputs via nix flake update and all hosts
that use the default module would automatically benefit.
Outlook
SMB has really improved over the years and in my opinion is no longer just a toy network filesystem, which I appreciate. Proper NFS is quite complex and Samba usually does what you want. There is now support for SMB over QUIC which would both protect the data in transit natively and be over UDP, which would make it suitable for use over the internet, at least theoretically. See here for some details.