Normale Ansicht

Received before yesterday

RHEL System Roles: nbde_client

04. Dezember 2023 um 06:00

In diesem Artikel stelle ich euch die RHEL System Role nbde_client vor, mit welcher sich Hosts für Network Bound Disk Encryption (NBDE) installieren lassen. Er ist Bestandteil einer losen Serie, in der ich eine Reihe von System Roles vorstelle, mit denen häufig anfallende Aufgaben in der Systemadministration erledigt werden können.

Wer sich zuerst über die genannten Begriffe informieren möchte, lese:

Umgebung

Für das folgende Beispiel verwende ich eine Umgebung, bestehend aus:

  • Einem Ansible-Controller (RHEL 9) mit den Paketen
    • ansible-core
    • rhel-system-roles
  • Jeweils einem RHEL 8 und RHEL 9 Server mit Minimalinstallation und einem LUKS-Gerät (/dev/sdc in den Beispielen in diesem Text)

Die Installation von RHEL sowie der genannten Pakete sind nicht Bestandteil dieses Artikels. Wer hierzu einen Einstieg sucht, findet entsprechende Dokumentation unter:

Die Rolle

Durch die Installation des Pakets rhel-system-roles existiert diese Rolle bereits auf meinem System und muss nur noch konfiguriert werden. Die Rolle selbst findet man im Pfad /usr/share/ansible/roles/rhel-system-roles.nbde_client/ und die Dokumentation in /usr/share/doc/rhel-system-roles/nbde_client/README.md. Letztere enthält verschiedene Beispiele für häufige Anwendungsfälle.

Anwendungsfall

In meinem Labor betreibe ich zwei NBDE-Server (TANG-Server) rhel-hetz-tang1 und rhel-hetz-tang2 sowie zwei NBDE-Clients (Clevis-Clients) rhel-hetz-clevis1 und rhel-hetz-clevis2. Die beiden NBDE-Clients besitzen jeweils ein LUKS-Device /dev/sdc, welches aktuell durch eine LUKS-Passphrase gesichert ist.

Zukünftig sollen diese LUKS-Devices durch die Kommunikation mit einem NBDE-Server entschlüsselt werden. Die LUKS-Passphrase soll entfernt werden.

Damit wird zukünftig ein Neustart der Clients aus der Ferne ermöglicht. Gleichzeitig bleibt das verschlüsselte Gerät bei Diebstahl vor unbefugtem Zugriff geschützt.

Das Playbook

Hinweis: Das folgende Playbook ist nicht idempotent. Um dies zu ändern, ist dem ersten Task eine Bedingung hinzuzufügen, damit dieser nur dann ausgeführt werden, wenn die Bedingung erfüllt ist.

Für dieses Beispiel ist die fehlende Idempotenz des Playbooks jedoch kein Problem, da grubby das Argument nur dann hinzufügt, wenn es nicht bereits vorhanden ist.

---
- hosts: clevis
  tasks:
  - name: Configure ip address for interface during early boot
    ansible.builtin.command:
      cmd: grubby --update-kernel=ALL --args='GRUB_CMDLINE_LINUX_DEFAULT="net.ifnames=0 biosdevname=0 ip={{ ansible_default_ipv4.address }}::{{ ansible_default_ipv4.gateway }}:{{ ansible_default_ipv4.netmask }}::{{ ansible_default_ipv4.alias }}:none"'

  - name: Enroll Clevis clients
    include_role:
      name: rhel-system-roles.nbde_client
    vars:
      nbde_client_bindings:
        - device: /dev/sdc
          encryption_password: "{{ luks_password }}"
          password_temporary: true
          slot: 2
          servers:
            - http://rhel-hetz-tang1.example.com
            - http://rhel-hetz-tang2.example.com
  • Der erste Task stellt sicher, dass das Netzwerkinterface aktiviert und mit einer IP-Adresse konfiguriert wird; dies ist notwendig, um den Tang-Server kontaktieren zu können, da in dem genutzten Netzwerk-Segment kein DHCP verfügbar ist; Solltet ihr ein Netzwerk-Segment nutzen, in dem DHCP zur Verfügung steht, kann der erste Task entfallen
  • Um das LUKS-Device für NBDE zu konfigurieren wird die LUKS-Passphrase benötigt, welche in der Variablen luks_password steckt
  • Ich empfehle die Variable luks_password mit ansible-vault vor neugierigen Blicken zu schützen
  • Durch password_temporary: true wird die LUKS-Passphrase aus dem jeweiligen Key-Slot gelöscht, nachdem das LUKS-Device für NBDE konfiguriert wurde

Achtung (I know, the warning comes after the spell): Wenn zur Laufzeit ein Fehler auftritt und der Key-Slot mit der LUKS-Passphrase bereits gelöscht wurde, die NBDE-Konfiguration jedoch nicht erfolgreich war, verliert man Zugriff auf das LUKS-Device. In meiner Labor-Umgebung bin ich das Risiko eingegangen. In der echten Welt, müsst ihr selbst entscheiden, ob ihr mehr Vorsicht walten lasst.

Fazit

Zur Erstellung des Playbooks habe ich die Informationen aus /usr/share/doc/rhel-system-roles/nbde_client/README.md und dem Kapitel 12.18. Using the nbde_client System Role for setting up multiple Clevis clients genutzt. Bis ich festgestellt habe, dass ich auch noch den Task „Configure ip address for interface during early boot“ benötige, hat es ein wenig gedauert. Nun habe ich allerdings ein Playbook, dass ich zukünftig wiederverwenden kann.

In der erstellten Konfiguration, können die LUKS-Devices nur entschlüsselt werden, wenn mindestens einer der beiden Tang-Server im Netzwerk erreichbar ist. Wird ein so gesicherter Server gestohlen und sind die Tang-Server nicht aus dem Internet erreichbar, bleiben die Daten in der verschlüsselten Partition wie gewohnt geschützt. Es ist jedoch möglich den Server neuzustarten, ohne manuell die LUKS-Passphrase an der Konsole eingeben zu müssen.

Quellen und weiterführende Links

  1. Red Hat Enterprise Linux (RHEL) System Roles {en}
  2. Ansible Documentation: Role Directory Structure {en}
  3. Red Hat Software and Download Center {en}
  4. Die Vorteile einer Red Hat Subskription
  5. RHEL System Roles: selinux
  6. RHEL System Roles: timesync
  7. RHEL System Roles: sshd
  8. RHEL System Roles: firewall
  9. RHEL System Roles: rhc
  10. RHEL System Roles: nbde_server

RHEL System Roles: nbde_server

27. November 2023 um 05:00

In diesem Artikel stelle ich euch die RHEL System Role nbde_server vor, mit welcher sich Tang-Server für Network Bound Disk Encryption (NBDE) installieren lassen. Er ist Bestandteil einer losen Serie, in der ich eine Reihe von System Roles vorstelle, mit denen häufig anfallende Aufgaben in der Systemadministration erledigt werden können.

Wer sich zuerst über die genannten Begriffe informieren möchte, lese zuerst:

Im folgenden Text verwende ich die Begriffe NBDE-Server und Tang-Server synonym. Bitte lasst euch dadurch nicht verwirren.

Umgebung

Für das folgende Beispiel verwende ich eine Umgebung, bestehend aus:

  • Einem Ansible-Controller mit den Paketen (RHEL 9)
    • ansible-core
    • rhel-system-roles
  • Jeweils einem RHEL 8 und RHEL 9 Server mit Minimalinstallation

Die Installation von RHEL sowie der genannten Pakete sind nicht Bestandteil dieses Artikels. Wer hierzu einen Einstieg sucht, findet entsprechende Dokumentation unter:

Die Rolle

Durch die Installation des Pakets rhel-system-roles existiert diese Rolle bereits auf meinem System und muss nur noch konfiguriert werden. Die Rolle selbst findet man im Pfad /usr/share/ansible/roles/rhel-system-roles.nbde_server/ und die Dokumentation in /usr/share/doc/rhel-system-roles/nbde_server/README.md. Letztere enthält verschiedene Beispiele für häufige Anwendungsfälle.

Ich möchte mit dieser Rolle Folgendes erreichen:

  • Installation von Tang auf den beiden Zielsystemen
  • Konfiguration von SELinux im Modus enforcing
  • Konfiguration der Host-Firewall

Das Playbook

Das Playbook ist recht übersichtlich. tang bezeichnet eine Gruppe aus meinem Ansible-Inventory, welche die Systeme enthält, die ich als NBDE-Server konfigurieren möchte.

---
- name: Manage nbde server with selinux and firewall
  hosts: tang
  vars:
    nbde_server_manage_firewall: true
    nbde_server_manage_selinux: true
  roles:
    - rhel-system-roles.nbde_server

Nach der Anwendung der Rolle lauscht der Tang-Service auf Port 80/tcp der Zielsysteme und ist aus dem Netzwerk erreichbar.

Probleme

Leider läuft es dieses Mal nicht ganz so rund wie üblich. Der Task [redhat.rhel_system_roles.selinux : Set an SELinux label on a port] schlägt auf dem RHEL 8 Host mit folgender Fehlermeldung fehl: „Failed to import the required Python library (libselinux-python)“

Das Problem und die Lösung beschreibt Red Hat in dem Solution Article: Ansible playbook fails with libselinux-python aren’t installed on RHEL8 (Login required)

Fazit

Diesmal lief es nicht ganz so reibungslos wie gewohnt.

Letztendlich konnten die beiden NBDE-Server dennoch schneller konfiguriert werden, als wäre ich der manuellen Prozedur in Chapter 12. Configuring automated unlocking of encrypted volumes using policy-based decryption gefolgt.

Die Server sind damit aufgesetzt, nächste Woche beschreibe ich, wie die Clients konfiguriert werden.

Quellen und weiterführende Links

  1. Red Hat Enterprise Linux (RHEL) System Roles {en}
  2. Ansible Documentation: Role Directory Structure {en}
  3. Red Hat Software and Download Center {en}
  4. Die Vorteile einer Red Hat Subskription
  5. RHEL System Roles: selinux
  6. RHEL System Roles: timesync
  7. RHEL System Roles: sshd
  8. RHEL System Roles: firewall
  9. RHEL System Roles: rhc

RHEL System Roles: storage

19. Juni 2023 um 05:00

Willkommen zu Teil 6 meiner losen Reihe über die RHEL System Roles. In diesem Teil stelle ich euch die Rolle storage vor, mit welcher sich unpartitionierte Laufwerke und LVM-Volumes verwalten lassen.

Zuerst stelle ich meinen Anwendungsfall vor. Anschließend beschreibe ich, wie ich diesen mithilfe der RHEL System Role storage löse.

Während mir dieser Artikel zur Dokumentation dient, soll er euch den Einsatz von RHEL System Roles verdeutlichen.

Hinweis: Zum Zeitpunkt der Erstellung dieses Artikels unterstützt die Rolle die LVM-Konfiguration lediglich auf unpartitionierten Laufwerken, welche komplett als Physical Volume (PV) genutzt werden.

Wer sich an dieser Stelle fragt, was RHEL System Roles sind, wie man sie installiert und nutzt, dem empfehle ich am Anfang zu beginnen: Vorstellung der Red Hat Enterprise Linux (RHEL) System Roles.

Anwendungsfall

Mit der Ansible-Rolle kvm_provision_lab (siehe [1,2]) provisioniere ich virtuelle Maschinen (VM) auf KVM/QEMU-Hypervisoren. In „Labor-Umgebung mit Ansible in KVM erstellen“ habe ich die Anwendung dieser Rolle bereits detailliert beschrieben. Eine VM wird darin als ein YAML-Dictionary nach folgendem Muster definiert:

test-vm1:
    vm_ram_mb: 512
    vm_vcpus: 1
    vm_iftype: network
    vm_net: default
    os_type: rhel9
    file_type: qcow2
    base_image_name: rhel9-template
    vm_template: "rhel9-template"
    second_hdd: true
    second_hdd_size: "2G"

Das Beispiel im Code-Block provisioniert eine VM mit einem zweiten Blocklaufwerk. Dieses wird in der VM als /dev/vdb konfigruiert.

Um das zweite Laufwerk nutzen zu können, müssen zuerst eine Partitionstabelle und eine Partition erstellt und diese mit einem Dateisystem formatiert werden. Alternativ kann das Gerät auch für LVM verwendet werden.

Ich möchte aus /dev/vdb ein PV für LVM machen, um es einer Volume Group (VG) vg_data hinzuzufügen und ein Logical Volume (LV) zu erstellen, welches die gesamte Speicherkapazität von /dev/vdb nutzt.

Die Rolle

Durch die Installation des Pakets rhel-system-roles existiert diese Rolle storage bereits auf meinem System und muss nur noch konfiguriert werden. Die Rolle selbst findet man im Pfad /usr/share/ansible/roles/rhel-system-roles.stroage/ und die Dokumentation in /usr/share/doc/rhel-system-roles/storage/README.md. Aus letzterer stammt auch folgendes Beispiel:

Example Playbook
----------------

```yaml
- hosts: all

  roles:
    - name: rhel-system-roles.storage
      storage_pools:
        - name: app
          disks:
            - sdb
            - sdc
          volumes:
            - name: shared
              size: "100 GiB"
              mount_point: "/mnt/app/shared"
              #fs_type: xfs
              state: present
            - name: users
              size: "400g"
              fs_type: ext4
              mount_point: "/mnt/app/users"
      storage_volumes:
        - name: images
          type: disk
          disks: ["mpathc"]
          mount_point: /opt/images
          fs_label: images

```

Da ich auf /dev/vdb ein LVM konfigurieren möchte, kopiere ich mir das Dictionary storage_pools aus obigen Beispiel und passe es für mein Playbook an.

Das Playbook

---
- hosts: test-vm1

  roles:
    - name: rhel-system-roles.storage
      storage_pools:
        - name: vg_data
          disks:
            - vdb
          volumes:
            - name: data1
              size: "2 GiB"
              mount_point: "/mnt"
              fs_type: ext4
              state: present

Obiges Playbook führt folgende Schritte auf dem Host test-vm1 durch:

  1. Das Blockgerät /dev/vdb wird als PV für LVM konfiguriert.
  2. Es wird die Volume Group (VG) vg_data auf dem PV /dev/vdb erstellt.
  3. In der VG vg_data wird das LV data1 erstellt.
  4. Das LV wird mit dem Dateisystem Ext4 formatiert.
  5. Das LV wird unterhalb von /mnt eingehängt.

Innerhalb des Gast-Betriebssystems lässt sich mit folgenden Kommandos prüfen, dass die Konfiguration wie gewünscht durchgeführt wurde.

[root@test-vm1 ~]# lsblk vdb
lsblk: vdb: not a block device
[root@test-vm1 ~]# lsblk /dev/vdb
NAME            MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
vdb             252:16   0   2G  0 disk 
└─vg_data-data1 253:0    0   2G  0 lvm  /mnt
[root@test-vm1 ~]# pvs
  PV         VG      Fmt  Attr PSize  PFree
  /dev/vdb   vg_data lvm2 a--  <2.00g    0 
[root@test-vm1 ~]# vgs
  VG      #PV #LV #SN Attr   VSize  VFree
  vg_data   1   1   0 wz--n- <2.00g    0 
[root@test-vm1 ~]# lvs
  LV    VG      Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  data1 vg_data -wi-ao---- <2.00g                                                    
[root@test-vm1 ~]# mount | grep mnt
/dev/mapper/vg_data-data1 on /mnt type ext4 (rw,relatime,seclabel)
[root@test-vm1 ~]# echo "Hallo Welt!" >/mnt/world.txt
[root@test-vm1 ~]# cat /mnt/world.txt
Hallo Welt!

Fazit

Der betrachtete Anwendungsfall lässt sich mit der vorgestellten Ansible-Rolle schnell und einfach umsetzen. Man deklariert lediglich die Wunschkonfiguration im Ansible-Playbook und die Rolle kümmert sich um den Rest, wie die Installation der notwendigen Pakete auf den Zielsystemen.

Unterstützt werden als Zielsysteme aktuell EL 7-9 sowie Fedora. Damit ist sie für die Anwendung auf Debian bzw. darauf basierende Systeme nicht geeignet. Wie man auch für diese Systeme ein einfaches Playbook entwirft, um LVM für Blockgeräte zu konfigurieren, werde ich in einem folgenden Artikel zeigen.

Ich hoffe, dass euch auch die Vorstellung dieser Rolle gefallen hat und wünsche euch viel Spaß bei der Nutzung der RHEL System Roles.

Quellen und weiterführende Links

  1. https://galaxy.ansible.com/Tronde/kvm_provision_lab
  2. https://github.com/Tronde/kvm_provision_lab
  3. https://github.com/linux-system-roles/storage
  4. Vorstellung der Red Hat Enterprise Linux (RHEL) System Roles
  5. RHEL System Roles: selinux
  6. RHEL System Roles: timesync
  7. RHEL System Roles: sshd
  8. RHEL System Roles: firewall
❌