From 7200fc1c290ca23b366a42d8db1460c35006552b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B6rg=20Sachse?= <joerg.sachse@slub-dresden.de>
Date: Thu, 7 Dec 2023 11:35:46 +0100
Subject: [PATCH] feat: prepare tasks for NFSv3 rpcbind risk mitigations.
 CAUTION: as we're lacking NetApp interface info, this code is not yet tested!

---
 handlers/main.yml           |  4 +++
 tasks/configure_rpcbind.yml | 57 +++++++++++++++++++++++++++++++++++++
 tasks/main.yml              |  4 +++
 3 files changed, 65 insertions(+)
 create mode 100644 tasks/configure_rpcbind.yml

diff --git a/handlers/main.yml b/handlers/main.yml
index 5fd9a4c..93eb289 100644
--- a/handlers/main.yml
+++ b/handlers/main.yml
@@ -85,3 +85,7 @@
     name: "clamav-freshclam"
     state: restarted
   when: ansible_os_family == "RedHat"
+
+- name: daemon_reload
+  ansible.builtin.systemd:
+    daemon_reload: true
diff --git a/tasks/configure_rpcbind.yml b/tasks/configure_rpcbind.yml
new file mode 100644
index 0000000..3a11e29
--- /dev/null
+++ b/tasks/configure_rpcbind.yml
@@ -0,0 +1,57 @@
+---
+- name: find out if rpcbind is installed by checking for systemd socket unit
+  ansible.builtin.stat:
+    path: "/lib/systemd/system/rpcbind.socket"
+    get_attributes: false
+    get_checksum: false
+    get_mime: false
+  register: rpcbind_installed
+  changed_when: false
+
+- name: create directory for Systemd unit override
+  ansible.builtin.file:
+    path: "/etc/systemd/system/rpcbind.socket.d/"
+    state: directory
+    mode: "0755"
+  when: rpcbind_installed
+
+- name: implement access control in rpcbind socket unit by creating an override - general settings
+  ansible.builtin.blockinfile:
+    path: "/etc/systemd/system/rpcbind.socket.d/override.conf"
+    create: true
+    marker: "### {mark} ANSIBLE MANAGED BLOCK - clear previous settings"
+    block: |
+      # from `man 5 systemd.socket`:
+      # "SOCK_STREAM (i.e. ListenStream=) when used for IP sockets refers to
+      # TCP sockets, SOCK_DGRAM (i.e. ListenDatagram=) to UDP."
+
+      # Clear any previously set options...
+      #ListenStream=0.0.0.0:111      # DISTRO DEFAULT
+      #ListenDatagram=0.0.0.0:111    # DISTRO DEFAULT
+      ListenStream=
+      ListenDatagram=
+      # ...and now set new stricter values in subsequent blocks.
+  when: rpcbind_installed
+  notify: daemon_reload
+
+- name: implement access control in rpcbind socket unit by creating an override - general settings
+  ansible.builtin.blockinfile:
+    path: "/etc/systemd/system/rpcbind.socket.d/override.conf"
+    create: true
+    marker: ### {mark} ANSIBLE MANAGED BLOCK - allow access for {{ item.source }}
+    block: |
+      ListenStream={{ item.source }}
+      ListenDatagram={{ item.source }}
+  loop: "{{ nfs_server_interfaces }}"
+  when: rpcbind_installed
+  notify: daemon_reload
+
+- name: implement rpcbind access control in iptables
+  ansible.builtin.iptables:
+    action: "insert"
+    chain: "INPUP"
+    comment: "{{ item.comment }}"
+    source: "{{ item.source }}"
+    jump: "ACCEPT"
+  loop: "{{ nfs_server_interfaces }}"
+  notify: "save iptables rules"
diff --git a/tasks/main.yml b/tasks/main.yml
index 41350ca..532b830 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -44,6 +44,10 @@
   ansible.builtin.import_tasks: "configure_iptables.yml"
   tags: [iptables]
 
+- name: configure mitigations for NFSv3 rpcbind
+  ansible.builtin.import_tasks: "configure_rpcbind.yml"
+  tags: [nfs, network, iptables, rpc, rpcbind]
+
 - name: include rkhunter install task
   ansible.builtin.import_tasks: "install_rkhunter.yml"
   tags: [rkhunter]
-- 
GitLab