All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH kdevops] ktls: allow setting up hosts with tlshd
@ 2023-12-12 19:35 Jeff Layton
  2023-12-12 19:43 ` Chuck Lever
  2023-12-13  6:11 ` Luis Chamberlain
  0 siblings, 2 replies; 4+ messages in thread
From: Jeff Layton @ 2023-12-12 19:35 UTC (permalink / raw)
  To: Luis Chamberlain; +Cc: Chuck Lever, kdevops, Jeff Layton

Add a new option to the post-install "goals" phase to configure tlshd
for TLS handshake upcalls. This adds a new playbook to build a CA,
generate certs for the hosts, and then configure tlshd to use them.

Finally, it also adds a new NFS fstests option to test RPC over TLS
(using xprtsec=mtls).

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 Makefile                                           |   4 +
 kconfigs/Kconfig.bringup.goals                     |   9 ++
 playbooks/ktls.yml                                 |   4 +
 playbooks/roles/fstests/templates/nfs/nfs.config   |   7 ++
 .../roles/ktls/tasks/install-deps/debian/main.yml  |  10 ++
 playbooks/roles/ktls/tasks/install-deps/main.yml   |   9 ++
 .../roles/ktls/tasks/install-deps/redhat/main.yml  |  15 +++
 .../roles/ktls/tasks/install-deps/suse/main.yml    |   9 ++
 playbooks/roles/ktls/tasks/main.yml                | 110 +++++++++++++++++++++
 playbooks/roles/ktls/templates/tlshd.conf          |  39 ++++++++
 scripts/bringup.Makefile                           |   5 +
 scripts/ktls.Makefile                              |   8 ++
 workflows/fstests/nfs/Kconfig                      |   9 +-
 workflows/fstests/nfs/Makefile                     |   3 +
 14 files changed, 240 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 895a0a67c705..0f6fa024f14c 100644
--- a/Makefile
+++ b/Makefile
@@ -114,6 +114,10 @@ ifeq (y,$(CONFIG_WORKFLOWS))
 include workflows/Makefile
 endif # CONFIG_WORKFLOWS
 
+ifeq (y,$(CONFIG_KDEVOPS_SETUP_KTLS))
+include scripts/ktls.Makefile
+endif # CONFIG_KDEVOPS_SETUP_KTLS
+
 ifeq (y,$(CONFIG_KDEVOPS_SETUP_NFSD))
 include scripts/nfsd.Makefile
 endif # CONFIG_KDEVOPS_SETUP_NFSD
diff --git a/kconfigs/Kconfig.bringup.goals b/kconfigs/Kconfig.bringup.goals
index 5df74d4bcb08..a2af3ffba499 100644
--- a/kconfigs/Kconfig.bringup.goals
+++ b/kconfigs/Kconfig.bringup.goals
@@ -56,6 +56,15 @@ config KDEVOPS_TRY_INSTALL_KDEV_TOOLS
 	  most kernel developers might prefer to have installed on target
 	  systems.
 
+config KDEVOPS_SETUP_KTLS
+	bool "Configure ktls on the hosts with self-signed CA"
+	default n
+	help
+	  Enabling this will have kdevops create a self-signed certificate
+	  authority, and configure tlshd on the hosts to use it. This is
+	  necessary for testing RPC over TLS, or some NVMe over fabrics
+	  configurations.
+
 config KDEVOPS_SETUP_NFSD
 	bool "Set up the kernel nfs server"
 	default n
diff --git a/playbooks/ktls.yml b/playbooks/ktls.yml
new file mode 100644
index 000000000000..8b7044c7ef2d
--- /dev/null
+++ b/playbooks/ktls.yml
@@ -0,0 +1,4 @@
+---
+- hosts: all
+  roles:
+    - role: ktls
diff --git a/playbooks/roles/fstests/templates/nfs/nfs.config b/playbooks/roles/fstests/templates/nfs/nfs.config
index 60915f824764..e2265f3f3ee2 100644
--- a/playbooks/roles/fstests/templates/nfs/nfs.config
+++ b/playbooks/roles/fstests/templates/nfs/nfs.config
@@ -15,6 +15,13 @@ CANON_DEVS=yes
 # Test with default mount options
 [nfs_default]
 {% endif %}
+{% if fstests_nfs_section_tls -%}
+
+# Test NFS with RPC over TLS
+[nfs_tls]
+TEST_FS_MOUNT_OPTS="-o xprtsec=mtls"
+MOUNT_OPTIONS="-o xprtsec=mtls"
+{% endif %}
 {% if fstests_nfs_section_v40 -%}
 
 # Test NFSv4.0
diff --git a/playbooks/roles/ktls/tasks/install-deps/debian/main.yml b/playbooks/roles/ktls/tasks/install-deps/debian/main.yml
new file mode 100644
index 000000000000..704c394e0c49
--- /dev/null
+++ b/playbooks/roles/ktls/tasks/install-deps/debian/main.yml
@@ -0,0 +1,10 @@
+---
+- name: Install ktls dependencies
+  become: yes
+  become_method: sudo
+  apt:
+    name:
+      - python3-cryptography
+      - ktls-utils
+    state: present
+    update_cache: yes
diff --git a/playbooks/roles/ktls/tasks/install-deps/main.yml b/playbooks/roles/ktls/tasks/install-deps/main.yml
new file mode 100644
index 000000000000..ab343e8b05c6
--- /dev/null
+++ b/playbooks/roles/ktls/tasks/install-deps/main.yml
@@ -0,0 +1,9 @@
+---
+# tasks to install dependencies for pynfs
+- name: oscheck distribution ospecific setup
+  import_tasks: tasks/install-deps/debian/main.yml
+  when: ansible_facts['os_family']|lower == 'debian'
+- import_tasks: tasks/install-deps/suse/main.yml
+  when: ansible_facts['os_family']|lower == 'suse'
+- import_tasks: tasks/install-deps/redhat/main.yml
+  when: ansible_facts['os_family']|lower == 'redhat'
diff --git a/playbooks/roles/ktls/tasks/install-deps/redhat/main.yml b/playbooks/roles/ktls/tasks/install-deps/redhat/main.yml
new file mode 100644
index 000000000000..0e1ab7505b3e
--- /dev/null
+++ b/playbooks/roles/ktls/tasks/install-deps/redhat/main.yml
@@ -0,0 +1,15 @@
+---
+- name: Install ktls dependencies
+  become: yes
+  become_method: sudo
+  dnf:
+    update_cache: yes
+    name: "{{ packages }}"
+  retries: 3
+  delay: 5
+  register: result
+  until: result.rc == 0
+  vars:
+    packages:
+      - python3-cryptography
+      - ktls-utils
diff --git a/playbooks/roles/ktls/tasks/install-deps/suse/main.yml b/playbooks/roles/ktls/tasks/install-deps/suse/main.yml
new file mode 100644
index 000000000000..ce5935154038
--- /dev/null
+++ b/playbooks/roles/ktls/tasks/install-deps/suse/main.yml
@@ -0,0 +1,9 @@
+---
+- name: Install ktls dependencies
+  become: yes
+  become_method: sudo
+  zypper:
+    state: present
+    name:
+      - python3-cryptography
+      - ktls-utils
diff --git a/playbooks/roles/ktls/tasks/main.yml b/playbooks/roles/ktls/tasks/main.yml
new file mode 100644
index 000000000000..1aa545835502
--- /dev/null
+++ b/playbooks/roles/ktls/tasks/main.yml
@@ -0,0 +1,110 @@
+- name: Import optional extra_args file
+  include_vars: "{{ item }}"
+  ignore_errors: yes
+  with_first_found:
+    - files:
+      - "../extra_vars.yml"
+      - "../extra_vars.yaml"
+      - "../extra_vars.json"
+      skip: true
+
+- name: Install dependencies
+  import_tasks: install-deps/main.yml
+
+- name: Construct the path to the CA directory
+  delegate_to: localhost
+  set_fact:
+    ca_dir: "{{ topdir_path }}/ca/{{ kdevops_host_prefix }}"
+
+- name: Create directory to hold the CA on local host
+  delegate_to: localhost
+  run_once: true
+  ansible.builtin.file:
+    path: "{{ ca_dir }}"
+    state: directory
+
+- name: Create private key for CA
+  delegate_to: localhost
+  run_once: true
+  community.crypto.openssl_privatekey:
+    path: "{{ ca_dir }}/ca-cert.key"
+
+- name: Create certificate signing request (CSR) for CA certificate
+  delegate_to: localhost
+  run_once: true
+  community.crypto.openssl_csr_pipe:
+    privatekey_path: "{{ ca_dir }}/ca-cert.key"
+    common_name: "kdevops {{ kdevops_host_prefix }} CA"
+    use_common_name_for_san: false  # since we do not specify SANs, don't use CN as a SAN
+    basic_constraints:
+      - 'CA:TRUE'
+    basic_constraints_critical: true
+    key_usage:
+      - keyCertSign
+    key_usage_critical: true
+  register: ca_csr
+
+- name: Create self-signed CA certificate from CSR
+  delegate_to: localhost
+  run_once: true
+  community.crypto.x509_certificate:
+    path: "{{ ca_dir }}/ca-cert.pem"
+    csr_content: "{{ ca_csr.csr }}"
+    privatekey_path: "{{ ca_dir }}/ca-cert.key"
+    provider: selfsigned
+
+- name: Create private key for new TLS certificate
+  community.crypto.openssl_privatekey:
+    path: "/etc/pki/tls/private/ktls.key"
+  become: yes
+
+- name: Copy CA cert to all of the hosts
+  ansible.builtin.copy:
+    src: "{{ ca_dir }}/ca-cert.pem"
+    dest: "/etc/pki/tls/certs/ca-cert.pem"
+    owner: root
+    group: root
+    mode: 0644
+  become: yes
+
+- name: Create certificate signing request (CSR) for new certificate
+  community.crypto.openssl_csr_pipe:
+    privatekey_path: "/etc/pki/tls/private/ktls.key"
+    subject_alt_name:
+      - "DNS:{{ ansible_host }}"
+      - "IP:{{ ansible_default_ipv4.address }}"
+  register: csr
+  become: yes
+
+- name: Sign certificate with our CA
+  community.crypto.x509_certificate_pipe:
+    csr_content: "{{ csr.csr }}"
+    provider: ownca
+    ownca_path: "{{ ca_dir }}/ca-cert.pem"
+    ownca_privatekey_path: "{{ ca_dir }}/ca-cert.key"
+    ownca_not_after: +365d  # valid for one year
+    ownca_not_before: "-1d"  # valid since yesterday
+  delegate_to: localhost
+  register: certificate
+
+- name: Write certificate file on host
+  copy:
+    dest: "/etc/pki/tls/certs/ktls.pem"
+    content: "{{ certificate.certificate }}"
+  become: yes
+
+- name: Install new /etc/tlshd.conf
+  ansible.builtin.copy:
+    src: "{{ playbook_dir }}/roles/ktls/templates/tlshd.conf"
+    dest: "/etc/tlshd.conf"
+    owner: root
+    group: root
+    mode: 0644
+  become: yes
+
+- name: Enable and start tlshd
+  become: yes
+  ansible.builtin.systemd_service:
+    name: tlshd.service
+    enabled: true
+    state: reloaded
diff --git a/playbooks/roles/ktls/templates/tlshd.conf b/playbooks/roles/ktls/templates/tlshd.conf
new file mode 100644
index 000000000000..63ee5b59a8bd
--- /dev/null
+++ b/playbooks/roles/ktls/templates/tlshd.conf
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2022 Oracle and/or its affiliates.
+#
+# This file is part of ktls-utils.
+#
+# ktls-utils is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; version 2.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# See tlshd.conf(5) for details.
+#
+
+[debug]
+loglevel=0
+tls=0
+nl=0
+
+[authenticate]
+#keyrings= <keyring>;<keyring>;<keyring>
+
+[authenticate.client]
+x509.truststore=/etc/pki/tls/certs/ca-cert.pem
+x509.certificate=/etc/pki/tls/certs/ktls.pem
+x509.private_key=/etc/pki/tls/private/ktls.key
+
+[authenticate.server]
+x509.truststore=/etc/pki/tls/certs/ca-cert.pem
+x509.certificate=/etc/pki/tls/certs/ktls.pem
+x509.private_key=/etc/pki/tls/private/ktls.key
diff --git a/scripts/bringup.Makefile b/scripts/bringup.Makefile
index 0051bc3d5e0d..520e2993a7b1 100644
--- a/scripts/bringup.Makefile
+++ b/scripts/bringup.Makefile
@@ -21,6 +21,11 @@ ifeq (y,$(CONFIG_KDEVOPS_SETUP_NFSD))
 KDEVOPS_BRING_UP_DEPS += nfsd
 endif # KDEVOPS_SETUP_NFSD
 
+ifeq (y,$(CONFIG_KDEVOPS_SETUP_KTLS))
+KDEVOPS_BRING_UP_DEPS += ktls
+KDEVOPS_DESTROY_DEPS += ktls-destroy
+endif # KDEVOPS_SETUP_KTLS
+
 update_etc_hosts:
 	$(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
 		-f 30 -i hosts playbooks/update_etc_hosts.yml
diff --git a/scripts/ktls.Makefile b/scripts/ktls.Makefile
new file mode 100644
index 000000000000..977538041ae8
--- /dev/null
+++ b/scripts/ktls.Makefile
@@ -0,0 +1,8 @@
+ktls:
+	$(Q)ansible-playbook $(ANSIBLE_VERBOSE) --extra-vars=@./extra_vars.yaml \
+		-f 30 -i hosts playbooks/ktls.yml
+
+ktls-destroy:
+	$(Q)rm -rf $(TOPDIR)/ca
+
+PHONY += ktls ktls-destroy
diff --git a/workflows/fstests/nfs/Kconfig b/workflows/fstests/nfs/Kconfig
index 7e202778d286..7e8731dc4dc1 100644
--- a/workflows/fstests/nfs/Kconfig
+++ b/workflows/fstests/nfs/Kconfig
@@ -54,11 +54,18 @@ config FSTESTS_NFS_SECTION_DEFAULT
 	  time of this writing, this makes the client autonegotiate an NFS
 	  version, starting with v4.2 if it's available.
 
+config FSTESTS_NFS_SECTION_TLS
+	bool "Enable testing section: nfs_tls"
+	default n
+	depends on KDEVOPS_SETUP_KTLS
+	help
+	  Enabling this will test with the xprtsec=tls mount option.
+
 config FSTESTS_NFS_SECTION_V40
 	bool "Enable testing section: nfs_v40"
 	default n
 	help
-	  Enabling this will test NFSv4.0
+	  Enabling this will test NFSv4.0.
 
 config FSTESTS_NFS_SECTION_V3
 	bool "Enable testing section: nfs_v3"
diff --git a/workflows/fstests/nfs/Makefile b/workflows/fstests/nfs/Makefile
index 7a057532be67..0e5245920ee9 100644
--- a/workflows/fstests/nfs/Makefile
+++ b/workflows/fstests/nfs/Makefile
@@ -9,6 +9,9 @@ FSTESTS_ARGS += fstests_nfs_server_host='$(FSTESTS_NFS_SERVER_HOST)'
 ifeq (y,$(CONFIG_FSTESTS_NFS_SECTION_DEFAULT))
 FSTESTS_ARGS += fstests_nfs_section_default=True
 endif
+ifeq (y,$(CONFIG_FSTESTS_NFS_SECTION_TLS))
+FSTESTS_ARGS += fstests_nfs_section_tls=True
+endif
 ifeq (y,$(CONFIG_FSTESTS_NFS_SECTION_V40))
 FSTESTS_ARGS += fstests_nfs_section_v40=True
 endif

---
base-commit: 2f7d9b13a7ac734e2fb40ed68e45150af9d727ef
change-id: 20231212-ktls-5534fde5777c

Best regards,
-- 
Jeff Layton <jlayton@kernel.org>


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-12-13  6:11 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-12 19:35 [PATCH kdevops] ktls: allow setting up hosts with tlshd Jeff Layton
2023-12-12 19:43 ` Chuck Lever
2023-12-12 20:12   ` Jeff Layton
2023-12-13  6:11 ` Luis Chamberlain

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.