feat(nfs): Restrict server to v4 by default

Can be changed with `nfs_v4_only=false` which defaults to true.

Information taken from: https://wiki.debian.org/NFSServerSetup
and applied directly through Ansible.

Currently _irreversible_, meaning once we set the server to v4 only
there is NO ansible-supported playbook to reset it to all NFSv2/3/4
versions.

Has to be done manually, or could be included as manually-run playbook.
This commit is contained in:
Marty Oehme 2025-11-28 14:06:07 +01:00
parent ef1823da20
commit a5a6e297ff
Signed by: Marty
GPG key ID: 4E535BC19C61886E
3 changed files with 56 additions and 1 deletions

View file

@ -4,3 +4,6 @@ nfs_export_lines:
- "/srv/media 192.168.0.0/24(rw,async,no_subtree_check) 100.112.0.0/16(rw,async,no_subtree_check)"
- "/srv/files 192.168.0.0/24(rw,async,no_subtree_check) 100.112.0.0/16(rw,async,no_subtree_check)"
- "/mnt/ext/data/videos 192.168.0.0/24(rw,async,no_subtree_check) 100.112.0.0/16(rw,async,no_subtree_check)"
nfs_v4_only: true
nfs_v4_disable_rpcbind_fallback: false # needed by Debian 13

View file

@ -10,7 +10,7 @@
ansible.builtin.template:
src: exports.jinja
dest: /etc/exports
mode: '0644'
mode: "0644"
become: true
notify: Reload nfs service
@ -22,6 +22,10 @@
become: true
loop: "{{ nfs_export_lines }}"
- name: Disable NFSv2/NFSv3 to leave NFSv4-only server
ansible.builtin.include_tasks: "nfs-v4-only.yaml"
when: "nfs_v4_only"
- name: Enable nfs server unit
ansible.builtin.systemd:
enabled: true

View file

@ -0,0 +1,48 @@
---
- name: Configure /etc/default/nfs-common for NFSv4-only
ansible.builtin.lineinfile:
path: /etc/default/nfs-common
regexp: '^(# *)?{{ item.key }}=.*'
line: '{{ item.key }}={{ item.val }}'
loop:
- { key: NEED_STATD, val: '"no"' }
- { key: NEED_IDMAPD, val: '"yes"' }
become: true
notify: Reload nfs service
- name: Configure /etc/default/nfs-kernel-server for NFSv4-only
ansible.builtin.lineinfile:
path: /etc/default/nfs-kernel-server
regexp: '^(# *)?{{ item.key }}=.*'
line: '{{ item.key }}={{ item.val }}'
create: true # in case the file or the var is missing
loop:
- { key: RPCNFSDOPTS, val: '"--no-nfs-version 2 --no-nfs-version 3"' }
- { key: RPCMOUNTDOPTS, val: '"--manage-gids --no-nfs-version 2 --no-nfs-version 3"' }
become: true
notify: Reload nfs service
# This _can_ be used on very modern kernels, but disables
# the rpcbind fallback if nfsdctl lockd configuration fails.
# Debian 13 still requires this so it is disabled by default
- name: Mask rpcbind units (not needed for NFSv4)
ansible.builtin.systemd:
name: "{{ item }}"
masked: true
state: stopped
loop:
- rpcbind.service
- rpcbind.socket
become: true
when: "nfs_v4_disable_rpcbind_fallback"
- name: Unmask rpcbind units to keep as fallback
ansible.builtin.systemd:
name: "{{ item }}"
masked: false
state: started
loop:
- rpcbind.socket
- rpcbind.service
become: true
when: "not nfs_v4_disable_rpcbind_fallback"