#
# NFSv4.2/NFSv4.1 server setup for testing
#

#
# Debian Linux "Bullseye" NFSv4.2 server setup
#

##### 1. Setup
---- snip ----
# install packages
apt-get install nfs-kernel-server nfs-common nfs4-acl-tools autofs

# turn idmapper on, even for AUTH_SYS
{
        printf '[General]\n'
        printf '# Verbosity = 8 logs all idmapper lookups\n'
        printf 'Verbosity = 8\n'
        printf '# Value for "Domain" must be lowercase, value for "Local-Realms" uppercase\n'
        printf 'Domain = global.loc\n'
        printf 'Local-Realms = GLOBAL.LOC\n'
} >>'/etc/idmapd.conf'
printf "options nfsd nfs4_disable_idmapping=N\noptions nfs nfs4_disable_idmapping=N\n" >>'/etc/modprobe.d/nfs.conf'
printf "NEED_IDMAPD=yes\n" >>'/etc/default/nfs-common'

# put an export in '/etc/exports'

# start NFS server
service nfs-server start
---- snip ----


##### 2. Setup a 16GB XFS filesystem with block cloning support
---- snip ----
time dd if=/dev/zero of=/bigdisk/xfstestfs001.img bs=$((1024*1024)) count=$((16*1024))
mkfs.xfs -m reflink=1 /bigdisk/xfstestfs001.img
mkdir /xfstestfs001
chmod a+rwxt /xfstestfs001
echo '/bigdisk/xfstestfs001.img /xfstestfs001 xfs loop 0 0' >>'/etc/fstab'
#mount -o loop /bigdisk/xfstestfs001.img /xfstestfs001
echo '/xfstestfs001 *(sec=sys,rw,async,insecure,no_root_squash,fsid=2172423)' >>'/etc/exports'
mount /xfstestfs001
service nfs-server restart
---- snip ----


##### 3. Setup a 16GB DOS FAT32 filesystem for testing:
---- snip ----
dd if='/dev/zero' of='/bigdisk/fat32_image.img' bs=$((1024*1024)) count=$((16*1024))
mkfs.fat -F 32 '/bigdisk/fat32_image.img'
mkdir /fat32_mount
chmod -R a+rwx /fat32_mount
chown 65534:65534 /fat32_mount
#mount -o loop,uid=65534,gid=65534,fmask=0000,dmask=0000 /bigdisk/fat32_image.img /fat32_mount
echo '/bigdisk/fat32_image.img /fat32_mount vfat loop,uid=65534,gid=65534,fmask=0000,dmask=0000 0 0' >>'/etc/fstab'
mount /fat32_mount
echo '/fat32_mount *(sec=sys,rw,async,insecure,all_squash,anonuid=65534,anongid=65534,fsid=5272429)' >>'/etc/exports'
service nfs-server restart
---- snip ----


##### 4. Setup a 32GB EXT4 filesystem in case-INSENSITIVE mode for testing:
# * Notes:
# - requires CONFIG_UNICODE in the kernel, otherwise mount will FAIL
# - Linux nfsd has a bug which will report FATTR4_WORD0_CASE_INSENSITIVE==0 even
# if the filesystem is case-insensitive (FATTR4_WORD0_CASE_INSENSITIVE and
# FATTR4_WORD0_CASE_PRESERVING are currently hardcoded in Linux nfsd)
---- snip ----
dd if='/dev/zero' of='/bigdisk/ext4_caseinsensitive_image.img' bs=$((1024*1024)) count=$((32*1024))
mkfs.ext4 -O casefold -E encoding=utf8 /bigdisk/ext4_caseinsensitive_image.img
mkdir /ext4caseinsensitive
chmod -R a+rwx /ext4caseinsensitive
echo '/bigdisk/ext4_caseinsensitive_image.img /ext4caseinsensitive ext4 loop 0 0' >>'/etc/fstab'
mount /ext4caseinsensitive
mkdir /ext4caseinsensitive/nfsexport
# chattr +F is inherited by subdirs (of /ext4caseinsensitive/nfsexport) automatically
chattr +F /ext4caseinsensitive/nfsexport
chmod a+rwxt /ext4caseinsensitive/nfsexport
echo '/ext4caseinsensitive/nfsexport *(sec=sys,rw,async,insecure,no_root_squash,fsid=3272524)' >>'/etc/exports'
service nfs-server restart
---- snip ----


#
# Windows Server 2019/2022/2025 NFSv4.1 server setup
#

# Install Windows Server 2019, 2022 or 2025, then run these commands in an
# Adminstrator PowerShell
Install-WindowsFeature -name Telnet-Client

# make sure the time sync service is running and uses a valid ntp server:
sc config w32time start=auto
sc start w32time
w32tm /config /update /manualpeerlist:10.49.0.9
# wait 30sec and then verify the status:
w32tm /query /status

Import-Module ServerManager
Add-WindowsFeature FS-NFS-Service
Import-Module NFS

mkdir C:\shares\nfsfolder
echo "hello world" >C:\shares\nfsfolder\testfile
icacls.exe C:\shares\nfsfolder /grant "Everyone:(F)"

New-NfsShare -Name nfs1 -Path C:\shares\nfsfolder
Set-NfsShare -Name nfs1 -Permission readwrite -Authentication "sys" -EnableUnmappedAccess $True -AllowRootAccess $True
Set-NfsServerConfiguration -HideFilesBeginningInDot $True

# grant machines "192.168.209.129" and "localhost" (="127.0.0.1") access
Grant-NfsSharePermission -Name nfs1 -ClientName "192.168.209.129" -ClientType "host" -AllowRootAccess $True -Permission readwrite
Grant-NfsSharePermission -Name nfs1 -ClientName "127.0.0.1" -ClientType "host" -AllowRootAccess $True -Permission readwrite

nfsadmin server stop
nfsadmin server start

Start-Service -Name ms-nfs41-client-service

C:\cygwin64\sbin\nfs_mount -o rw N nfs://192.168.209.129//


#
# Solaris 11.4 NFSv4.1 server setup
#

##### 1. Server setup
# enable ntp server "10.49.0.9"
printf "server 10.49.0.9\n" >'/etc/inet/ntp.conf'
svcadm enable ntp

# configure&start NFS server
svcadm enable network/nfs/mapid
svcadm enable network/nfs/server
sharectl set -p nfsmapid_domain=global.loc nfs
sharectl set -p server_delegation=on nfs

# prepare test share
# (ZFS ROOT pool (e.g. "/nfsdata") cannot be used because '/'
# in the OpenIndiana distribution is mounted without the "xattr"
# mount option, see https://www.illumos.org/issues/17323
# ("NFSv4.1 server refuses creation of XATTR")
mkdir -p /export/nfsdata
chmod a+rwxt /export/nfsdata
# Note: Solaris 11.4 $ share -F nfs ... # shares are persistent across
# reboots, Illumos needs $ share -p -F nfs ... # for that
share -F nfs -o rw /export/nfsdata

# verify whether mapid and nfs/server are running
svcs network/nfs/mapid
svcs network/nfs/server

# performance: disable sync/ZIL on ZFS pool which exports NFS files
zfs set sync=disabled rpool

##### 2. Misc commands:
ls -v filename # list ACLs
chmod A... # to edit ACLs

##### 4. Troubleshooting:
See https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/manage-nfs/troubleshooting-network-file-systems1.html


#
# Illumos NFSv4.2 server setup
# (similar to Solaris 11.4)
#

##### 1. Server setup
# enable ntp server "10.49.0.9"
printf "server 10.49.0.9\n" >'/etc/inet/ntp.conf'
svcadm enable ntp
svcadm restart ntp

# configure&start NFS server
svcadm enable network/nfs/mapid
svcadm enable network/nfs/server
sharectl set -p nfsmapid_domain=global.loc nfs
sharectl set -p server_delegation=on nfs
sharectl set -p server_versmax=4.2 nfs

# prepare test share
# (ZFS ROOT pool (e.g. "/nfsdata") cannot be used because '/'
# in the OpenIndiana distribution is mounted without the "xattr"
# mount option, see https://www.illumos.org/issues/17323
# ("NFSv4.1 server refuses creation of XATTR")
mkdir -p /export/nfsdata
chmod a+rwxt /export/nfsdata
# Note: Solaris 11.4 $ share -F nfs ... # shares are persistent across
# reboots, Illumos needs $ share -p -F nfs ... # for that
share -p -F nfs -o rw /export/nfsdata

# verify whether mapid and nfs/server are running
svcs network/nfs/mapid
svcs network/nfs/server

# restarting network/nfs/server only restores shares in /etc/dfs/dfstab

# performance: disable sync/ZIL on ZFS pool which exports NFS files
zfs set sync=disabled rpool

##### 2. Misc commands:
ls -v filename # list ACLs
chmod A... # to edit ACLs

##### 4. Troubleshooting:
See https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/manage-nfs/troubleshooting-network-file-systems1.html


#
# FreeBSD NFSv4.2 server setup
# (tested with FreeBSD 14.3, FreeBSD 15.0 and FreeBSD 16.0)
#

##### 1. Server setup

# Install FreeBSD (>= 14.3) with NTP enabled

# enable time server
-- snip --
printf 'server 10.49.0.9 prefer minpoll 5 maxpoll 8\nlogfile /var/log/ntp.log\nleapfile "/var/db/ntpd.leap-seconds.list"\n' >'/etc/ntp.conf'
sysrc ntpd_enable="YES"
sysrc ntpd_flags=""
sysrc ntpd_sync_on_start="YES"
-- snip --

# Verify NTP config with
ntpq -np

# configure NFSv4.2 server with idmapping enabled
sysrc rpcbind_enable="YES"
sysrc mountd_enable="YES"
sysrc nfs_server_enable=YES
sysrc nfsv4_server_enable=YES
sysrc nfsuserd_flags="-domain GLOBAL.LOC"
sysrc nfsuserd_enable=YES
sysrc nfscbd_enable=YES
printf 'vfs.nfs.enable_uidtostring=0\n' >>'/etc/sysctl.conf'
printf 'vfs.nfsd.enable_stringtouid=0\n' >>'/etc/sysctl.conf'
printf 'vfs.nfsd.issue_delegations=1\n' >>'/etc/sysctl.conf'

# Add "SYSTEM" special account
pw groupadd group -n SYSTEM -g 18
pw useradd -n SYSTEM -u 18 -g SYSTEM -m -s /bin/sh

# configure an export
mkdir /nfsdata
chmod a+rwxt /nfsdata

# configure ZFS pool so it can support NFSv4 named attributes
# (NFSv4 named attributes require FreeBSD >= 15.0-only)
zfs set xattr=dir zroot
zfs set xattr=dir zroot/ROOT/default

# NFSv4.1 exports must come after the 'V4: /' line,
# otherwise you get a NFS4ERR_NOFILEHANDLE
printf 'V4: /\n' >'/etc/exports'
printf '/nfsdata -network=10.49.202.0 -mask=255.255.255.0  -sec=sys\n' >>'/etc/exports'
service nfsd start

#
# OPTIONAL 1: FreeBSD >= 16.0 case-insensitive filesystem with sparse file storage setup
#
mkdir -p /data
truncate -s 32G /data/zfs_casei001.img
zpool create -O xattr=dir -O casesensitivity=insensitive -O utf8only=on test_casei001_pool /data/zfs_casei001.img
zfs get xattr,casesensitivity test_casei001_pool # verify: Must be "casesensitivity=insensitive,xattr=dir"
printf '/test_casei001_pool -network=10.49.202.0 -mask=255.255.255.0  -sec=sys\n' >>'/etc/exports'
mkdir /test_casei001_pool/casei_tests
chmod a+rwxt /test_casei001_pool/casei_tests
service nfsd restart

#
# OPTIONAL 2: FreeBSD >= 16.0 case-insensitive filesystem with zpool storage setup
#
zfs create  -o mountpoint=/zroot_casei_pool001  -o xattr=dir  -o casesensitivity=insensitive -o utf8only=on "zroot/casei_pool001"
zfs get xattr,casesensitivity zroot/casei_pool001 # verify: Must be "casesensitivity=insensitive,xattr=dir"
printf '/zroot_casei_pool001 -network=10.49.202.0 -mask=255.255.255.0  -sec=sys\n' >>/etc/exports
mkdir /zroot_casei_pool001/casei_tests
chmod a+rwxt /zroot_casei_pool001/casei_tests
service nfsd restart

##### 2. FreeBSD-specific ms-nfs41-client setup:
- Normal setup

##### 3. Misc FreeBSD commands:
# (assumes we want to add an account+groups for a Windows user called "ced"
# on a Windows with English locale)
pw groupadd group -n None -g 197121
pw groupadd group -n ced -g 197608
pw useradd -n ced -u 197608 -g None -G None,ced -m -s /bin/sh
# later add more groups, and add user "ced" as member:
pw groupadd group -n cygwingrp1 -g 197611
pw groupadd group -n cygwingrp2 -g 197612
pw groupadd group -n cygwingrp_withspace5 -g 197618
pw groupmod cygwingrp1 -m ced
pw groupmod cygwingrp2 -m ced
pw groupmod cygwingrp_withspace5 -m ced

# EOF.
