This is an automated email from the ASF dual-hosted git repository.

weizhouapache pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack-documentation.git


The following commit(s) were added to refs/heads/main by this push:
     new 49d5339d Update settings for SELinux and Apparmor (#662)
49d5339d is described below

commit 49d5339d927ad155274273b25894b30b7a88298a
Author: Wei Zhou <[email protected]>
AuthorDate: Thu Nov 5 09:31:44 2026 +0100

    Update settings for SELinux and Apparmor (#662)
    
    * Update settings for SELinux and Apparmor
    
    * Update AppArmor and SELinux docs per review comments
    
    - Target only the libvirt AppArmor profiles with aa-enforce
    - Remove the disable links left by previous CloudStack versions
    - Explain AppArmor enforcement vs security_driver="none"
    - Add Debian and SUSE (zypper) instructions for AppArmor
    - Update intro and stale notes that said the mechanisms must be disabled
    
    * Add note on issues when security_driver is not set to none
    
    * Add release notice on SELinux and AppArmor no longer being configured
    
    * Add commands to check SELinux and AppArmor settings on KVM hosts
    
    * Mention that VM migration may be denied if security_driver differs 
between hosts
---
 source/developersguide/ansible.rst                 |  10 --
 source/installguide/hypervisor/kvm.rst             | 130 ++++++++++++++++-----
 .../installguide/management-server/_database.rst   |  32 +----
 source/quickinstallationguide/qig.rst              |  12 +-
 source/releasenotes/about.rst                      |  13 +++
 5 files changed, 124 insertions(+), 73 deletions(-)

diff --git a/source/developersguide/ansible.rst 
b/source/developersguide/ansible.rst
index f6bd73a0..23b73751 100644
--- a/source/developersguide/ansible.rst
+++ b/source/developersguide/ansible.rst
@@ -272,16 +272,6 @@ For the management server role we create a main.yml task 
like this:
      template: src=cloudstack.repo.j2 dest=/etc/yum.repos.d/cloudstack.repo
 
 
-   - name: Ensure selinux is in permissive mode
-
-     command: setenforce permissive
-
-
-   - name: Ensure selinux is set permanently
-
-     selinux: policy=targeted state=permissive
-
-
    -name: Ensure CloudStack packages are installed
 
      yum: name=cloud-client state=present
diff --git a/source/installguide/hypervisor/kvm.rst 
b/source/installguide/hypervisor/kvm.rst
index 46d3eb8b..e2b48230 100644
--- a/source/installguide/hypervisor/kvm.rst
+++ b/source/installguide/hypervisor/kvm.rst
@@ -587,14 +587,17 @@ cloudstack-agent and should already be installed.
         $ systemctl restart libvirtd
 
 
+.. _kvm-security-policies:
+
 Configure the Security Policies
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 CloudStack does various things which can be blocked by security
-mechanisms like AppArmor and SELinux. These have to be disabled to
-ensure the Agent has all the required permissions.
+mechanisms like AppArmor and SELinux. Both mechanisms can stay enabled on the
+host, but the libvirt per-Instance security driver must be turned off so that
+the Agent has all the required permissions for Instance and storage operations.
 
-#. Configure SELinux (RHEL, CentOS, SUSE)
+#. Configure SELinux (RHEL, CentOS)
 
    #. Check to see whether SELinux is installed on your machine. If not,
       you can skip this section.
@@ -607,68 +610,137 @@ ensure the Agent has all the required permissions.
          $ rpm -qa | grep selinux
 
    #. Set the SELINUX variable in ``/etc/selinux/config`` to
-      "permissive". This ensures that the permissive setting will be
+      "enforcing" or "permissive". This ensures that the setting will be
       maintained after a system reboot.
 
-      In RHEL or CentOS:
+   #. Then set SELinux to enforcing or permissive starting immediately, without
+      requiring a system reboot.
 
       .. parsed-literal::
 
-         $ vi /etc/selinux/config
+         $ setenforce enforcing
 
-      Change the following line
+   #. Set the security driver in ``/etc/libvirt/qemu.conf`` to "none".
 
       .. parsed-literal::
 
-         SELINUX=enforcing
+         security_driver="none"
 
-      to this
+   .. note:: In a production environment, SELinux should be set to enforcing
+      and the necessary SELinux policies should be created to allow the
+      services to run.
 
-      .. parsed-literal::
+#. Configure AppArmor (Ubuntu, Debian, SUSE)
 
-         SELINUX=permissive
+   AppArmor enforcement and ``security_driver="none"`` control different
+   security layers. The AppArmor profiles of ``libvirtd`` and
+   ``virt-aa-helper`` still protect the libvirt daemon itself, while
+   ``security_driver="none"`` disables the dynamic per-Instance AppArmor 
(sVirt)
+   confinement. This keeps the basic host protection while avoiding possible
+   compatibility problems with CloudStack Instance and storage operations.
 
-   #. Then set SELinux to permissive starting immediately, without
-      requiring a system reboot.
+   #. Check to see whether AppArmor is installed on your machine. If
+      not, you can skip this section.
+
+      In Ubuntu and Debian, AppArmor is installed and enabled by default. You
+      can verify this with:
 
       .. parsed-literal::
 
-         $ setenforce permissive
+         $ dpkg --list 'apparmor'
 
-.. note:: In a production environment, selinux should be set to enforcing
-   and the necessary selinux policies are created to allow the
-   services to run.
+      If the ``apparmor-utils`` package is not present, install it.
 
-#. Configure Apparmor (Ubuntu)
+      On Ubuntu and Debian:
 
+      .. parsed-literal::
 
-   #. Check to see whether AppArmor is installed on your machine. If
-      not, you can skip this section.
+         $ apt install apparmor-utils
 
-      In Ubuntu AppArmor is installed and enabled by default. You can
-      verify this with:
+      On SUSE:
 
       .. parsed-literal::
 
-         $ dpkg --list 'apparmor'
+         $ zypper install apparmor-utils
+
+   #. Set the libvirt AppArmor profiles to enforcing mode. This step is mainly
+      needed on existing hosts, because previous CloudStack versions disabled
+      these profiles. On fresh hosts, the libvirt profiles are normally already
+      enabled.
 
-   #. Disable the AppArmor profiles for libvirt
+      On existing hosts, first remove the links which were created by previous
+      CloudStack versions to disable the profiles. Otherwise the profiles will
+      be skipped again at the next boot.
 
       .. parsed-literal::
 
-         $ ln -s /etc/apparmor.d/usr.sbin.libvirtd /etc/apparmor.d/disable/
+         $ rm -f /etc/apparmor.d/disable/usr.sbin.libvirtd
+         $ rm -f /etc/apparmor.d/disable/usr.lib.libvirt.virt-aa-helper
+
+      Then enforce only the libvirt profiles:
 
       .. parsed-literal::
 
-         $ ln -s /etc/apparmor.d/usr.lib.libvirt.virt-aa-helper 
/etc/apparmor.d/disable/
+         $ aa-enforce /usr/sbin/libvirtd
+         $ aa-enforce /usr/lib/libvirt/virt-aa-helper
+
+   #. Set the security driver in ``/etc/libvirt/qemu.conf`` to "none".
+      Existing hosts may already have this setting, while it must be
+      configured manually on fresh hosts.
 
       .. parsed-literal::
 
-         $ apparmor_parser -R /etc/apparmor.d/usr.sbin.libvirtd
+         security_driver="none"
 
-      .. parsed-literal::
+      .. note:: If ``security_driver`` is not set to "none", the per-Instance
+         AppArmor profiles generated by libvirt may block some CloudStack
+         Instance and storage operations, for example starting an Instance or
+         accessing volumes and ISOs on primary and secondary storage.
+
+
+To check the current security settings of a KVM host, the following commands 
can be used:
+
+- SELinux (RHEL, CentOS, Rocky Linux, Alma Linux, etc.):
+
+  .. parsed-literal::
+
+     # Show the SELinux status, mode and loaded policy
+     $ sestatus
+     # Show the current mode (Enforcing, Permissive or Disabled)
+     $ getenforce
+     # List the SELinux booleans related to virtualization
+     $ getsebool -a | grep -E 'virt|qemu'
+     # Check whether libvirt/QEMU is allowed to use NFS storage
+     $ getsebool virt_use_nfs
+     # Show recent SELinux denials
+     $ ausearch -m avc -ts recent
+
+- AppArmor (Ubuntu, Debian, SUSE):
+
+  .. parsed-literal::
+
+     # Show the loaded profiles and their modes
+     $ aa-status
+     # Show the libvirt profiles which are in enforce mode
+     $ aa-status --filter.mode=enforce | grep libvirt
+     # List the AppArmor profiles installed on the host
+     $ ls /etc/apparmor.d/
+     # List the profiles which are disabled (e.g. links created by previous 
CloudStack versions)
+     $ ls /etc/apparmor.d/disable
+     # Show recent AppArmor denials
+     $ dmesg | grep -i 'apparmor.*denied'
+
+- libvirt security driver:
+
+  .. parsed-literal::
+
+     # Show the security driver configured for libvirt QEMU (should be "none")
+     $ grep -E '^\s*security_driver' /etc/libvirt/qemu.conf
 
-         $ apparmor_parser -R /etc/apparmor.d/usr.lib.libvirt.virt-aa-helper
+.. warning:: Use the same ``security_driver`` setting on all KVM hosts of a
+   cluster. If the hosts have different ``security_driver`` settings (for
+   example "none" on one host and "apparmor" or "selinux" on another), the
+   migration of Instances between them may be denied by libvirt.
 
 
 Configuring the Networking
diff --git a/source/installguide/management-server/_database.rst 
b/source/installguide/management-server/_database.rst
index c1eec4ef..d1f85d9c 100644
--- a/source/installguide/management-server/_database.rst
+++ b/source/installguide/management-server/_database.rst
@@ -122,8 +122,8 @@ MySQL. See :ref:`install-database-on-separate-node`.
       mysql_secure_installation
 
 #. CloudStack can be blocked by security mechanisms, such as SELinux.
-   Disable SELinux to ensure + that the Agent has all the required
-   permissions.
+   SELinux can stay enabled, as long as the necessary SELinux policies allow
+   the services to run.
 
    Configure SELinux (RHEL and CentOS):
 
@@ -138,37 +138,15 @@ MySQL. See :ref:`install-database-on-separate-node`.
          rpm -qa | grep selinux
 
    #. Set the SELINUX variable in ``/etc/selinux/config`` to
-      "permissive". This ensures that the permissive setting will be
+      "enforcing" or "permissive". This ensures that the setting will be
       maintained after a system reboot.
 
-      In RHEL or CentOS:
-
-      .. parsed-literal::
-
-         vi /etc/selinux/config
-
-      Change the following line
-
-      .. parsed-literal::
-
-         SELINUX=enforcing
-
-      to this:
-
-      .. parsed-literal::
-
-         SELINUX=permissive
-
-   #. Set SELinux to permissive starting immediately, without requiring
+   #. Set SELinux to enforcing or permissive starting immediately, without 
requiring
       a system reboot.
 
       .. parsed-literal::
 
-         setenforce permissive
-
-.. note:: In a production environment, selinux should be set to enforcing
-   and the necessary selinux policies are created to allow the
-   services to run.
+         setenforce enforcing
 
 #. Set up the database.
 
diff --git a/source/quickinstallationguide/qig.rst 
b/source/quickinstallationguide/qig.rst
index 5cfdab03..92064156 100644
--- a/source/quickinstallationguide/qig.rst
+++ b/source/quickinstallationguide/qig.rst
@@ -192,19 +192,17 @@ SELinux
 ^^^^^^^
 
 In an ideal environment, selinux should be set to enforcing and the necessary
-selinux policies are created to allow the services to run. For this guide,
-we will set selinux to permissive mode. This will allow us to install and
-configure the services without having to worry about selinux policies.
+selinux policies are created to allow the services to run.
 
-To configure SELinux to be permissive in the running system we need to run the 
+To configure SELinux to be enforcing in the running system we need to run the 
 following command:
 
 .. parsed-literal::
 
-   # setenforce 0
+   # setenforce 1
 
 To ensure that it remains in that state we need to configure the file 
-/etc/selinux/config to reflect the permissive state, as shown in this example:
+/etc/selinux/config to reflect the enforcing state, as shown in this example:
 
 .. parsed-literal::
 
@@ -213,7 +211,7 @@ To ensure that it remains in that state we need to 
configure the file
    # enforcing - SELinux security policy is enforced.
    # permissive - SELinux prints warnings instead of enforcing.
    # disabled - No SELinux policy is loaded.
-   SELINUX=permissive
+   SELINUX=enforcing
    # SELINUXTYPE= can take one of these two values:
    # targeted - Targeted processes are protected,
    # mls - Multi Level Security protection.
diff --git a/source/releasenotes/about.rst b/source/releasenotes/about.rst
index 6f9ec7a8..27225f77 100644
--- a/source/releasenotes/about.rst
+++ b/source/releasenotes/about.rst
@@ -55,5 +55,18 @@ Known Issues
   primary storage, due to a regression in the restore-and-attach command 
handling. See
   https://github.com/apache/cloudstack/pull/14007 for details and status.
 
+SELinux and AppArmor on KVM Hosts
+---------------------------------
+
+In older versions, CloudStack set SELinux to permissive mode and disabled the
+libvirt AppArmor profiles when configuring a KVM host. Since 24.0.0,
+CloudStack no longer changes these settings. If you face issues on a KVM host,
+for example Instances failing to start or storage operations failing with
+permission errors, please check the SELinux and AppArmor settings of the host
+and the ``security_driver`` setting in ``/etc/libvirt/qemu.conf``. Please
+note that if the hosts of a cluster have different ``security_driver`` 
settings,
+the migration of Instances between them may be denied by libvirt. See
+:ref:`kvm-security-policies` for the recommended configuration.
+
 The full list of new features can be found in the project release notes at
 https://docs.cloudstack.apache.org/en/4.23.0.0/releasenotes/changes.html

Reply via email to