How to allow NFS server traffic through UFW

An NFS server can export the right directory and still reject clients when UFW blocks the server-side network path. The firewall rule should allow only the client host or subnet that is supposed to mount the export, because TCP 2049 exposes file service access rather than a general web-style endpoint.

Current Linux NFS servers normally use TCP 2049 for NFSv4 traffic. Servers that still accept NFSv3 also depend on rpcbind and auxiliary RPC services such as mountd, statd, and lockd, so those older paths need fixed ports before UFW rules can target them predictably.

Use source-scoped UFW rules for the client network, such as 192.0.2.0/24, and keep the final test on a real allowed client. A local rule listing proves that UFW accepted the policy, while a client mount proves that the firewall, export selector, server listener, and client path line up.

Steps to allow NFS server traffic through UFW:

  1. Check that UFW is active and the incoming policy is restrictive.
    $ sudo ufw status verbose
    Status: active
    Logging: on (low)
    Default: deny (incoming), allow (outgoing), deny (routed)
    New profiles: skip

    If UFW is inactive and the server is remote, allow SSH or the management port before enabling the firewall. Enabling UFW with no management rule can disconnect the current session.

  2. Check the NFS protocol versions exposed by the server.
    $ cat /proc/fs/nfsd/versions
    +3 +4 +4.1 +4.2

    A plus sign before 3 means the server still accepts NFSv3 clients. A strict NFSv4 server usually needs only TCP 2049 through UFW.

  3. Confirm that the server is listening on the NFS port.
    $ ss -ltn 'sport = :2049'
    State  Recv-Q Send-Q Local Address:Port Peer Address:Port
    LISTEN 0      64           0.0.0.0:2049      0.0.0.0:*
    LISTEN 0      64              [::]:2049         [::]:*

    No listener on TCP 2049 means the firewall rule is not the only missing piece. Check the nfs-server service and active exports before retrying clients.

  4. Allow NFSv4 traffic from the client subnet.
    $ sudo ufw allow proto tcp from 192.0.2.0/24 to any port 2049 comment 'NFSv4 from client subnet'
    Rules updated

    Use a single client address such as 192.0.2.15 instead of 192.0.2.0/24 when only one host should mount the export.

  5. Verify the active UFW rule list for the NFSv4 rule.
    $ sudo ufw status numbered
    Status: active
    
         To                         Action      From
         --                         ------      ----
    [ 1] 2049/tcp                   ALLOW IN    192.0.2.0/24              # NFSv4 from client subnet
  6. Confirm fixed NFSv3 helper ports before adding legacy rules.
    $ rpcinfo -p localhost
       program vers proto   port  service
        100000    4   tcp    111  portmapper
        100000    3   tcp    111  portmapper
        100003    4   tcp   2049  nfs
        100005    3   tcp  20048  mountd
        100024    1   tcp  32765  status
        100021    4   tcp  32766  nlockmgr

    Skip the legacy NFSv3 firewall rules on a strict NFSv4 server. If mountd, statd, or lockd use dynamic ports, pin them first and open only the chosen values.

  7. Allow rpcbind traffic when legacy clients still need NFSv3 discovery.
    $ sudo ufw allow proto tcp from 192.0.2.0/24 to any port 111 comment 'rpcbind for NFSv3 clients'
    Rules updated

    Add a matching proto udp rule only when the server intentionally supports UDP-based legacy clients.

  8. Allow the fixed mountd port when legacy clients still need NFSv3 mounts.
    $ sudo ufw allow proto tcp from 192.0.2.0/24 to any port 20048 comment 'mountd for NFSv3 clients'
    Rules updated

    Use the port shown by rpcinfo -p or by the approved /etc/nfs.conf setting for the server.

  9. Allow the fixed statd port when legacy clients still need network status recovery.
    $ sudo ufw allow proto tcp from 192.0.2.0/24 to any port 32765 comment 'statd for NFSv3 clients'
    Rules updated

    Use the port shown by rpcinfo -p or by the approved /etc/nfs.conf setting for the server.

  10. Allow the fixed lockd port when legacy clients still need NFSv3 file locking.
    $ sudo ufw allow proto tcp from 192.0.2.0/24 to any port 32766 comment 'lockd for NFSv3 clients'
    Rules updated

    Open UDP for lockd only when legacy clients and the server configuration require it.

  11. Verify the final UFW rule list.
    $ sudo ufw status numbered
    Status: active
    
         To                         Action      From
         --                         ------      ----
    [ 1] 2049/tcp                   ALLOW IN    192.0.2.0/24              # NFSv4 from client subnet
    [ 2] 111/tcp                    ALLOW IN    192.0.2.0/24              # rpcbind for NFSv3 clients
    [ 3] 20048/tcp                  ALLOW IN    192.0.2.0/24              # mountd for NFSv3 clients
    [ 4] 32765/tcp                  ALLOW IN    192.0.2.0/24              # statd for NFSv3 clients
    [ 5] 32766/tcp                  ALLOW IN    192.0.2.0/24              # lockd for NFSv3 clients

    A strict NFSv4 server should show only the TCP 2049 rule for NFS traffic. The legacy rows should appear only when NFSv3 support remains intentional.

  12. Create a temporary mount point on an allowed client.
    $ sudo mkdir --parents /mnt/projects

    The client must match both the export selector and the UFW source rule. The examples use files.example.net and /mnt/projects.

  13. Mount the export from the allowed client.
    $ sudo mount -t nfs4 files.example.net:/srv/nfs/projects /mnt/projects

    Use nfs with a version option such as vers=3 only when the server intentionally supports NFSv3 clients.

  14. Verify the mounted source on the client.
    $ findmnt -o TARGET,SOURCE,FSTYPE /mnt/projects
    TARGET        SOURCE                                FSTYPE
    /mnt/projects files.example.net:/srv/nfs/projects  nfs4
  15. Unmount the temporary client test mount.
    $ sudo umount /mnt/projects
  16. Remove the temporary mount point when it is not a permanent client path.
    $ sudo rmdir /mnt/projects