NFS Server
This integration provides a wrapper around the upstream nixpkgs module to create and manage a NFS server declaratively, providing some options to configure features such as: - define default options to set on all exports - define exports declaratively - subnet/ip based ACLs to selectively allow access
NFS exports are generated by bind-mounting an existing directory to an /export
directory
Example Configurations
Basic Setup
This shows a simple NFS server with a single export.
provision.fs.nfs.server = {
enable = true;
# base directory for export directory
exportDir = "/export";
firewall.enable = true; # open firewall for interfaces defined in `interfaces`
firewall.interfaces = [ "eth1" ]; # interface to open firewall to
# adds bind-mounts for /path -> /export/path
default.addToFilesystem = true;
# default export options to add to all exports
default.export.options = {
rw = true;
insecure = true;
subtree_check = true;
nohide = true;
async = true;
};
exports = {
# Currently required to add root export
"/" = {
exportPath = "/export";
export.options.fsid = 0;
# allow to all hosts
subnets."*" = { };
};
# Media share available at server:/media
"/media" = {
hostPath = "/media";
# allow to two networks
subnets = {
"10.8.0.0/24" = { };
"192.168.0.5/32" = { };
};
};
};
};
You can then connect to the server by running
# on samba server
nix shell nixpkgs#nfs-utils
mount.nfs localhost:/media /mnt
# on another machine accessible via network on eth0
mount.nfs <samba-ip>:/media /mnt
Subnet + IP based Access Control
You can also define shares in the provision.fs.nfs.server.subnets
option.
Example Configuration
users.users.media.uid = 3000;
users.users.media.isSystemUser = true;
users.groups.media.gid = 3000;
provision.fs.nfs.server = {
enable = true;
default.addToFilesystem = true;
default.export.options = {
rw = true;
insecure = true;
subtree_check = true;
nohide = true;
async = true;
};
subnets = {
mydevices = {
subnet = "10.77.1.0/24";
paths = [
"/media"
"/pictures"
"/documents"
"/backups"
];
};
lan = {
subnet = "192.168.1.0/24";
paths = [ "/media" ];
};
phone = {
subnet = "192.168.1.7/32";
paths = [
"/media"
"/pictures"
"/documents"
"/backups"
];
};
thinclient = {
subnet = "192.168.1.88/32";
paths = [
"/documents"
"/backups"
];
};
};
exports = {
# Currently required to add root export
"/" = {
exportPath = "/export";
export.options.fsid = 0;
# allow to all hosts
subnets."*" = { };
};
"/pictures".export.options = {
anonuid = config.users.users.media.uid;
anongid = config.users.users.media.uid;
};
"/media".export.options = {
anonuid = config.users.users.media.uid;
anongid = config.users.users.media.uid;
};
"/documents".export.options = {
anonuid = 2000;
anongid = 2000;
};
};
};
The generates an /etc/exports
like:
/export *(rw,insecure,subtree_check,nohide,async,fsid=0)
/export/backups 10.77.1.0/24(rw,insecure,subtree_check,nohide,async,rw,insecure,subtree_check,nohide,async) 192.168.1.7/32(rw,insecure,subtree_check,nohide,async,rw,insecure,subtree_check,nohide,async) 192.168.1.88/32(rw,insecure,subtree_check,nohide,async,rw,insecure,subtree_check,nohide,async)
/export/documents 10.77.1.0/24(rw,insecure,subtree_check,nohide,async,rw,insecure,subtree_check,nohide,async,anonuid=2000,anongid=2000) 192.168.1.7/32(rw,insecure,subtree_check,nohide,async,rw,insecure,subtree_check,nohide,async,anonuid=2000,anongid=2000) 192.168.1.88/32(rw,insecure,subtree_check,nohide,async,rw,insecure,subtree_check,nohide,async,anonuid=2000,anongid=2000)
/export/media 10.77.1.0/24(rw,insecure,subtree_check,nohide,async,rw,insecure,subtree_check,nohide,async,anonuid=3000,anongid=3000) 192.168.1.0/24(rw,insecure,subtree_check,nohide,async,rw,insecure,subtree_check,nohide,async,anonuid=3000,anongid=3000) 192.168.1.7/32(rw,insecure,subtree_check,nohide,async,rw,insecure,subtree_check,nohide,async,anonuid=3000,anongid=3000)
/export/pictures 10.77.1.0/24(rw,insecure,subtree_check,nohide,async,rw,insecure,subtree_check,nohide,async,anonuid=3000,anongid=3000) 192.168.1.7/32(rw,insecure,subtree_check,nohide,async,rw,insecure,subtree_check,nohide,async,anonuid=3000,anongid=3000)
Test Configuration
The server + client integrations are tested in tests/nfs/basic.nix
Troubleshooting
The below is a miscellaneous list of tools you can use to debug issues, or comments on configurations:
- run
exportfs
to list current exports - some logs may be available at
nfs-server.service