All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@kernel.org>
To: Luis Chamberlain <mcgrof@kernel.org>
Cc: Chuck Lever <chuck.lever@oracle.com>,
	kdevops@lists.linux.dev,  Jeff Layton <jlayton@kernel.org>
Subject: [PATCH kdevops] ktls: allow setting up hosts with tlshd
Date: Tue, 12 Dec 2023 14:35:38 -0500	[thread overview]
Message-ID: <20231212-ktls-v1-1-acfba0d36f75@kernel.org> (raw)

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>


             reply	other threads:[~2023-12-12 19:35 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-12 19:35 Jeff Layton [this message]
2023-12-12 19:43 ` [PATCH kdevops] ktls: allow setting up hosts with tlshd Chuck Lever
2023-12-12 20:12   ` Jeff Layton
2023-12-13  6:11 ` Luis Chamberlain

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231212-ktls-v1-1-acfba0d36f75@kernel.org \
    --to=jlayton@kernel.org \
    --cc=chuck.lever@oracle.com \
    --cc=kdevops@lists.linux.dev \
    --cc=mcgrof@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.