From ace0287d7a59867d3a439c205c5accdcf309505e Mon Sep 17 00:00:00 2001 From: Elisamara Aoki Goncalves Date: Fri, 10 Mar 2023 16:42:03 -0300 Subject: [PATCH] AppArmor Support (dsR8) Story: 2010310 Task: 47620 Signed-off-by: Elisamara Aoki Goncalves Change-Id: I97065a0d0c345bb32663e1ff631c5c4ca524231d --- .../release/ansible_bootstrap_configs.rst | 9 + .../aio_duplex_install_kubernetes.rst | 2 + .../aio_simplex_install_kubernetes.rst | 2 + ...rapping-from-a-private-docker-registry.rst | 4 +- .../controller_storage_install_kubernetes.rst | 2 + ...ng-redfish-platform-management-service.rst | 4 +- ...ut-redfish-platform-management-service.rst | 2 + .../about-apparmor-ebdab8f1ed87.rst | 52 ++++ .../apply-a-profile-to-a-pod-c2fa4d958dec.rst | 99 +++++++ .../author-apparmor-profiles-b02de0a22771.rst | 148 ++++++++++ .../enable-apparmor-log-bb600560d794.rst | 31 +++ ...isable-apparmor-on-a-host-63a7a184d310.rst | 62 +++++ .../index-security-kub-81153c1254c3.rst | 15 + ...ecurity-profiles-operator-1b2f9a0f0108.rst | 121 +++++++++ .../profile-management-a8df19c86a5d.rst | 257 ++++++++++++++++++ doc/source/shared/abbrevs.txt | 2 + ...-registries-for-starlingx-installation.rst | 34 ++- .../kubernetes/change-the-registry-url.rst | 13 + .../create-the-registry-secrets.rst | 28 ++ ...validate-existing-registry-and-new-url.rst | 2 + 20 files changed, 872 insertions(+), 17 deletions(-) create mode 100644 doc/source/security/kubernetes/about-apparmor-ebdab8f1ed87.rst create mode 100644 doc/source/security/kubernetes/apply-a-profile-to-a-pod-c2fa4d958dec.rst create mode 100644 doc/source/security/kubernetes/author-apparmor-profiles-b02de0a22771.rst create mode 100644 doc/source/security/kubernetes/enable-apparmor-log-bb600560d794.rst create mode 100644 doc/source/security/kubernetes/enable-disable-apparmor-on-a-host-63a7a184d310.rst create mode 100644 doc/source/security/kubernetes/install-security-profiles-operator-1b2f9a0f0108.rst create mode 100644 doc/source/security/kubernetes/profile-management-a8df19c86a5d.rst diff --git a/doc/source/deploy_install_guides/release/ansible_bootstrap_configs.rst b/doc/source/deploy_install_guides/release/ansible_bootstrap_configs.rst index 23a9ec562..848d88335 100644 --- a/doc/source/deploy_install_guides/release/ansible_bootstrap_configs.rst +++ b/doc/source/deploy_install_guides/release/ansible_bootstrap_configs.rst @@ -112,6 +112,13 @@ Install-time-only parameters * ``password`` * ``secure`` + * ``registry.k8s.io`` + + * ``url`` + * ``username`` + * ``password`` + * ``secure`` + * ``defaults`` * ``url`` @@ -305,6 +312,8 @@ additionally specifies an alternate CA certificate. url: my.quayregistry.io docker.io: url: my.dockerregistry.io + registry.k8s.io: + url: my.registry.k8s.io defaults: url: my.registry.io username: myreguser diff --git a/doc/source/deploy_install_guides/release/bare_metal/aio_duplex_install_kubernetes.rst b/doc/source/deploy_install_guides/release/bare_metal/aio_duplex_install_kubernetes.rst index d7023557f..a6f879471 100644 --- a/doc/source/deploy_install_guides/release/bare_metal/aio_duplex_install_kubernetes.rst +++ b/doc/source/deploy_install_guides/release/bare_metal/aio_duplex_install_kubernetes.rst @@ -180,6 +180,8 @@ Bootstrap system on controller-0 url: myprivateregistry.abc.com:9001/k8s.gcr.io docker.io: url: myprivateregistry.abc.com:9001/docker.io + registry.k8s.io: + url: myprivateregistry.abc.com:9001/registry.k8s.io defaults: type: docker username: diff --git a/doc/source/deploy_install_guides/release/bare_metal/aio_simplex_install_kubernetes.rst b/doc/source/deploy_install_guides/release/bare_metal/aio_simplex_install_kubernetes.rst index 44fadd5c0..db41783b8 100644 --- a/doc/source/deploy_install_guides/release/bare_metal/aio_simplex_install_kubernetes.rst +++ b/doc/source/deploy_install_guides/release/bare_metal/aio_simplex_install_kubernetes.rst @@ -180,6 +180,8 @@ Bootstrap system on controller-0 url: myprivateregistry.abc.com:9001/k8s.gcr.io docker.io: url: myprivateregistry.abc.com:9001/docker.io + registry.k8s.io + url: myprivateregistry.abc.com:9001/registry.k8s.io defaults: type: docker username: diff --git a/doc/source/deploy_install_guides/release/bare_metal/bootstrapping-from-a-private-docker-registry.rst b/doc/source/deploy_install_guides/release/bare_metal/bootstrapping-from-a-private-docker-registry.rst index 43b05198b..9bcf94cd1 100644 --- a/doc/source/deploy_install_guides/release/bare_metal/bootstrapping-from-a-private-docker-registry.rst +++ b/doc/source/deploy_install_guides/release/bare_metal/bootstrapping-from-a-private-docker-registry.rst @@ -29,7 +29,9 @@ your server is isolated from the public Internet. docker.io: url: /docker.io docker.elastic.co: - url: /docker.elastic.co + url: /docker.elastic.co + registry.k8s.io: + url: /registry.k8s.io defaults: type: docker username: diff --git a/doc/source/deploy_install_guides/release/bare_metal/controller_storage_install_kubernetes.rst b/doc/source/deploy_install_guides/release/bare_metal/controller_storage_install_kubernetes.rst index 0db65df7f..f685585ba 100644 --- a/doc/source/deploy_install_guides/release/bare_metal/controller_storage_install_kubernetes.rst +++ b/doc/source/deploy_install_guides/release/bare_metal/controller_storage_install_kubernetes.rst @@ -243,6 +243,8 @@ Bootstrap system on controller-0 url: myprivateregistry.abc.com:9001/k8s.ghcr.io docker.io: url: myprivateregistry.abc.com:9001/docker.io + registry.k8s.io: + url: myprivateregistry.abc.com:9001/registry.k8s.io defaults: type: docker username: diff --git a/doc/source/dist_cloud/kubernetes/installing-a-subcloud-using-redfish-platform-management-service.rst b/doc/source/dist_cloud/kubernetes/installing-a-subcloud-using-redfish-platform-management-service.rst index d2f02d21e..04995e3d8 100644 --- a/doc/source/dist_cloud/kubernetes/installing-a-subcloud-using-redfish-platform-management-service.rst +++ b/doc/source/dist_cloud/kubernetes/installing-a-subcloud-using-redfish-platform-management-service.rst @@ -243,6 +243,8 @@ command with the ``install-values.yaml`` file containing the desired url: registry.central:9001/docker.io docker.elastic.co: url: registry.central:9001/docker.elastic.co + registry.k8s.io: + url: registry.central:9001/registry.k8s.io defaults: username: sysinv password: @@ -426,4 +428,4 @@ command with the ``install-values.yaml`` file containing the desired - For more information on bootstrapping and deploying, see the procedures listed under :ref:`install-a-subcloud`. - + diff --git a/doc/source/dist_cloud/kubernetes/installing-a-subcloud-without-redfish-platform-management-service.rst b/doc/source/dist_cloud/kubernetes/installing-a-subcloud-without-redfish-platform-management-service.rst index 90c9fb7a3..2dcd2584b 100644 --- a/doc/source/dist_cloud/kubernetes/installing-a-subcloud-without-redfish-platform-management-service.rst +++ b/doc/source/dist_cloud/kubernetes/installing-a-subcloud-without-redfish-platform-management-service.rst @@ -196,6 +196,8 @@ subcloud, the subcloud installation process has two phases: url: registry.central:9001/docker.io docker.elastic.co: url: registry.central:9001/docker.elastic.co + registry.k8s.io: + url: registry.central:9001/registry.k8s.io defaults: username: sysinv password: diff --git a/doc/source/security/kubernetes/about-apparmor-ebdab8f1ed87.rst b/doc/source/security/kubernetes/about-apparmor-ebdab8f1ed87.rst new file mode 100644 index 000000000..d56a63d97 --- /dev/null +++ b/doc/source/security/kubernetes/about-apparmor-ebdab8f1ed87.rst @@ -0,0 +1,52 @@ +.. _about-apparmor-ebdab8f1ed87: + +============== +About AppArmor +============== + +AppArmor is a Mandatory Access Control (MAC) system built on Linux's LSM (Linux +Security Modules) interface. In practice, the kernel queries AppArmor before +each system call to know whether the process is authorized to do the given +operation. Through this mechanism, AppArmor confines programs to a limited set +of resources. + +AppArmor helps administrators in running a more secure kubernetes deployment by +restricting what containers/pods are allowed to do, and/or provide better +auditing through system logs. The access needed by a container/pod is +configured through profiles tuned to allow access such as Linux capabilities, +network access, file permissions, etc. + +AppArmor applies a set of rules (known as a “profile”) on each program. The +profile applied by the kernel depends on the installation path of the program +being executed, the rules applied do not depend on the user. All users face the +same set of rules when they are executing the same program, but traditional +user permissions still apply and might result in different behavior. + +AppArmor profiles contain a list of access control rules on resources that each +program can make use of. Each profile can be loaded either in enforcing or +complaining mode. The former enforces the policy and reports violation +attempts, while the latter does not enforce the policy but still logs the +system calls that would have been denied. + +In order to apply a profile to a particular pod, the profile needs to be +available to the host machine where the pod is launched. Security Profile +Operator (SPO, https://github.com/kubernetes-sigs/security-profiles-operator) +provides AppArmor profile management (i.e. loading/unloading) across +Kubernetes nodes. |SPO| defines an AppArmor Profile |CRD|, such that end users +can define AppArmor profiles for |SPO| to manage. Once an AppArmor profile is +loaded to the Kubernetes nodes, it can be applied to a particular pod using +annotations on the pod specification. + +For example: + +.. code-block:: none + + container.apparmor.security.beta.kubernetes.io/:localhost/ + +For more information, refer to `Restrict a Container's Access to Resources with +AppArmor: Example +`__. + + + + diff --git a/doc/source/security/kubernetes/apply-a-profile-to-a-pod-c2fa4d958dec.rst b/doc/source/security/kubernetes/apply-a-profile-to-a-pod-c2fa4d958dec.rst new file mode 100644 index 000000000..bbe6f906b --- /dev/null +++ b/doc/source/security/kubernetes/apply-a-profile-to-a-pod-c2fa4d958dec.rst @@ -0,0 +1,99 @@ +.. _apply-a-profile-to-a-pod-c2fa4d958dec: + +======================== +Apply a Profile to a Pod +======================== + +AppArmor profiles are specified per-container. + +.. rubric:: |prereq| + +- AppArmor should be enabled on the host(s) (described in + :ref:`Enable/Disable AppArmor on a Host + `), where workloads need to + be protected using AppArmor. + +- Security Profiles Operator (SPO) should be installed. As described in + :ref:`Install Security Profiles Operator (SPO) + `. + +- A profile should be loaded using |SPO| (described in :ref:`Profile + Management `). + + +To specify the AppArmor profile to run a Pod container with, add an annotation +to the Pod's metadata: + +.. code-block:: none + + container.apparmor.security.beta.kubernetes.io/: + + +.. rubric:: |eg| + +#. Attach a profile to a container in the Pod. + + .. code-block:: none + + $ vi test-apparmor.yaml + apiVersion: v1 + kind: Pod + metadata: + name: test-apparmor + annotations: + # Tell Kubernetes to apply the AppArmor profile "test-profile". + container.apparmor.security.beta.kubernetes.io/test-apparmor: localhost/test-profile + spec: + containers: + - name: test-apparmor + image: busybox:1.28 + command: [ "sh", "-c", "echo 'Hello Test AppArmor!' && sleep 1h" ] + + $ kubectl apply -f test-apparmor.yaml + +#. Verify that the container is actually running with that profile by checking + its proc attr. + + .. code-block:: none + + $ kubectl exec test-apparmor -- cat /proc/1/attr/current + test-profile (complain) + +#. Verify if violations are blocked by writing to a file. + + .. code-block:: none + + $ kubectl exec test-apparmor -- touch /tmp/test + touch: /tmp/test: Permission denied + command terminated with exit code 1 + +.. note:: + + If a profile is not created/loaded on a host, ``kubelet`` will reject the + pod. + + .. code-block:: none + + $ kubectl get pods + NAME READY STATUS RESTARTS AGE + hello-apparmor 0/1 CreateContainerError 0 (49m ago) 113m + + Running ``kubectl describe pod hello-apparmor`` or + ``kubect get event | grep hello-apparmor`` will show the following error: + + .. code-block:: none + + Error: : failed to generate apparmor spec opts: apparmor profile not found test-profile + + Any profile rules updates are reflected to the running pods. + + Any profile deletion while it is attached to a pod will not have any impact + on the pod state (It will show in running state). The application in the + pod may not behave correctly as it might try to access + ``/proc/self/attr/apparmor/exec`` which throw error as profile is not + loaded. + +For more details, refer to `Restrict a Container's Access to Resources with +AppArmor: Example +`__. + diff --git a/doc/source/security/kubernetes/author-apparmor-profiles-b02de0a22771.rst b/doc/source/security/kubernetes/author-apparmor-profiles-b02de0a22771.rst new file mode 100644 index 000000000..d29ffec32 --- /dev/null +++ b/doc/source/security/kubernetes/author-apparmor-profiles-b02de0a22771.rst @@ -0,0 +1,148 @@ +.. _author-apparmor-profiles-b02de0a22771: + +======================== +Author AppArmor Profiles +======================== + +AppArmor profiles can be written using a variety of approaches: AppArmor +policy language, Bane and/or aa-logprof. + +Core Policy Reference +********************* + +AppArmor wiki provides the guidelines and semantics for AppArmor policy +enforcement and reference profile language which can be found at below link. + +https://gitlab.com/apparmor/apparmor/-/wikis/AppArmor_Core_Policy_Reference + + +Bane +**** + +`bane `__ is an AppArmor profile +generator for Docker that uses a simplified profile language. This could be +used for generating a profile using an easy-to-read configuration file. + +https://www.padok.fr/en/blog/security-docker-apparmor#Generate_an_AppArmor_profile_for_a_docker_container_with_bane + + +Generate a profile using aa-logprof +*********************************** + +#. Create a profile with name ``-profile`` under ``/etc/apparmor.d``, + which denies everything. + + For example: + + .. code-block:: none + + #include + + profile -profile flags=(attach_disconnected, complain) { + #include + } + +#. Use ``apparmor_parser`` to load the above created profile in complain mode: + + .. code-block:: none + + apparmor_parser -q /etc/apparmor.d/ + +#. Attach the profile to the pod, launch the pod and perform the pod's allowed + operations. + +#. Below permission change needs to be done by a user with sudo capability + (e.g. 'sysadmin' user) to allow a ``sys_protected`` group member (e.g. + 'sysadmin' user) to update the profile using :command:`aa-logprof`. + + .. code-block:: none + + sudo setfacl -m g:sys_protected:rwx /etc/apparmor.d/ + +#. Use :command:`aa-logprof` to update the profile as follows: + + .. code-block:: none + + aa-logprof -f <(sed 's/kernel: notice/kernel:/' < /var/log/kern.log) + + This would update the profile under ``/etc/apparmor.d``. + +#. Add the updated profile in the policy section of the AppArmor |CRD| after + changing complain to enforce and load it in enforced mode as specified in + :ref:`Load a profile in enforce mode across all hosts using SPO + `. + + +Example profiles 1 +****************** + +Below is an example of a sample profile which adds Linux capabilities, network +access rule, process limit, and file access. + +.. code-block:: none + + # This loads a file containing variable definitions. + include + + # profile name + profile Sample_profile flags=(attach_disconnected, mediate_deleted) { + # This keyword allows to include rules from other files - + #include + + # enables POSIX.1e draft capabilitie. application can change process UIDs and GIDs s + capability setuid, + capability setgid, + + # network access IPv4 TCP and IPv4 UPD is allowed - + network inet dgram, + network inet stream, + + # rlimit stack size is limited to 5KB + rlimit stack >= 5K, + + # file permissions application can read and write to ~/myfile and it can execute ~/app + @{HOME}/myfile rw, + @{HOME}/app ix, + } + } + + +Example profiles 2 +****************** + +Below is an example profile of tcpdump a packet analyzer application. The +rules are more focused on Linux capabilities and Network access. + +.. code-block:: none + + #include + + /usr/sbin/tcpdump { + #include + #include + #include + + capability net_raw, + capability setuid, + capability setgid, + capability dac_override, + network raw, + network packet, + + # for -D + capability sys_module, + @{PROC}/bus/usb/ r, + @{PROC}/bus/usb/** r, + + # for -F and -w + audit deny @{HOME}/.* mrwkl, + audit deny @{HOME}/.*/ rw, + audit deny @{HOME}/.*/** mrwkl, + audit deny @{HOME}/bin/ rw, + audit deny @{HOME}/bin/** mrwkl, + @{HOME}/ r, + @{HOME}/** rw, + + /usr/sbin/tcpdump r, + } + diff --git a/doc/source/security/kubernetes/enable-apparmor-log-bb600560d794.rst b/doc/source/security/kubernetes/enable-apparmor-log-bb600560d794.rst new file mode 100644 index 000000000..77cdb239e --- /dev/null +++ b/doc/source/security/kubernetes/enable-apparmor-log-bb600560d794.rst @@ -0,0 +1,31 @@ +.. _enable-apparmor-log-bb600560d794: + +=================== +Enable AppArmor Log +=================== + +AppArmor usually outputs messages when it is interacting with an application +and if there are AppArmor denied messages. A message is logged, via the Linux +Auditing System, when a profile is in complain mode and application tries to +access denied resources. The Linux Auditing System is disabled in the |prod| +kernel by default. To enable it, please refer to :ref:`Enable Auditd in the +Kernel `. + +.. note:: + + Enabling Auditd in the kernel is necessary for AppArmor logging. User do + NOT need to install Auditd system application. + +Once enabled, the logged message can be seen at ``/var/log/kern.log``. + +.. code-block:: none + + 2023-02-01T01:48:45.412 controller-0 kernel: notice [ 4028.407687] audit: type=1400 audit(1675216125.410:3110): apparmor="ALLOWED" operation="open" profile="test-profile" name="/proc/1/attr/current" pid=331323 comm="cat" requested_mask="r" denied_mask="r" fsuid=0 ouid=0 + +If auditd system application is installed as described in :ref:`Start Auditd +System Application `, the messages are logged at +``/var/log/audit/audit.log``. + + + + diff --git a/doc/source/security/kubernetes/enable-disable-apparmor-on-a-host-63a7a184d310.rst b/doc/source/security/kubernetes/enable-disable-apparmor-on-a-host-63a7a184d310.rst new file mode 100644 index 000000000..ad444c8ee --- /dev/null +++ b/doc/source/security/kubernetes/enable-disable-apparmor-on-a-host-63a7a184d310.rst @@ -0,0 +1,62 @@ +.. _enable-disable-apparmor-on-a-host-63a7a184d310: + +================================= +Enable/Disable AppArmor on a Host +================================= + +By default, AppArmor is disabled on a host. It can be enabled in the kernel +using system CLI commands as follows. In the below example AppArmor is enabled +on controller-0. + +.. note:: + + Enabling AppArmor can result in some performance degradation, see |org| + System Engineering Guidelines. + +.. note:: + + On a multi-host configuration, AppArmor should be enabled on all hosts to + ensure that the AppArmor profiles are loaded on any host where a pod may be + scheduled by kubernetes. + +#. To enable AppArmor on a host, run the following commands: + + .. code-block:: none + + ~(keystone_admin)]$ system host-lock controller-0 + ~(keystone_admin)]$ system host-update controller-0 apparmor=enabled + ~(keystone_admin)]$ system host-unlock controller-0 + + Wait for controller-0 to reset and return to an unlocked/enabled/available + state. + +#. Verify if AppArmor is enabled by running the following commands on the + host. + + .. code-block:: none + + sysadmin@controller-0:~$ aa-enabled + + Yes + +To disable AppArmor on a host, run the following commands. + +#. In the below example AppArmor is disabled on controller-0. + + .. code-block:: none + + ~(keystone_admin)]$ system host-lock controller-0 + ~(keystone_admin)]$ system host-update controller-0 apparmor=disabled + ~(keystone_admin)]$ system host-unlock controller-0 + + Wait for controller-0 to reset and return to an unlocked/enabled/available + state. + +#. Verify if AppArmor is disabled by running the following commands on the + host. + + .. code-block:: none + + sysadmin@controller-0:~$ aa-enabled + + No diff --git a/doc/source/security/kubernetes/index-security-kub-81153c1254c3.rst b/doc/source/security/kubernetes/index-security-kub-81153c1254c3.rst index 71e5bd35f..d471f3ed9 100644 --- a/doc/source/security/kubernetes/index-security-kub-81153c1254c3.rst +++ b/doc/source/security/kubernetes/index-security-kub-81153c1254c3.rst @@ -190,6 +190,21 @@ Linux Auditing System auditd-support-339a51d8ce16 +******** +AppArmor +******** +.. toctree:: + :maxdepth: 1 + + about-apparmor-ebdab8f1ed87 + enable-disable-apparmor-on-a-host-63a7a184d310 + install-security-profiles-operator-1b2f9a0f0108 + profile-management-a8df19c86a5d + apply-a-profile-to-a-pod-c2fa4d958dec + enable-apparmor-log-bb600560d794 + author-apparmor-profiles-b02de0a22771 + + ************************************* Operator Login/Authentication Logging ************************************* diff --git a/doc/source/security/kubernetes/install-security-profiles-operator-1b2f9a0f0108.rst b/doc/source/security/kubernetes/install-security-profiles-operator-1b2f9a0f0108.rst new file mode 100644 index 000000000..88e00a536 --- /dev/null +++ b/doc/source/security/kubernetes/install-security-profiles-operator-1b2f9a0f0108.rst @@ -0,0 +1,121 @@ +.. _install-security-profiles-operator-1b2f9a0f0108: + +======================================== +Install Security Profiles Operator (SPO) +======================================== + +In order to apply the profiles to a particular pod, the profiles need to be +available to the host machine where the pod is launched. Security Profile +Operator (SPO, https://github.com/kubernetes-sigs/security-profiles-operator) +provides AppArmor profile management (i.e. loading/unloading) across Kubernetes +nodes. |SPO| defines an AppArmor Profile |CRD|, such that end users' can define +AppArmor profiles for |SPO| to manage. + +|SPO| is packaged as a system application and is managed using system +application commands. To install |SPO|, use the following procedure. + +.. rubric:: |prereq| + +AppArmor should be enabled on the host(s) (described in :ref:`Enable/Disable +AppArmor on a Host `), where +workloads need to be protected using AppArmor. + +.. rubric:: |proc| + +#. Locate the |SPO| tarball in ``/usr/local/share/applications/helm``. + + For example: + + .. code-block:: none + + /usr/local/share/applications/helm/security-profiles-operator-.tgz + +#. Upload the application. + + .. code-block:: none + + ~(keystone_admin)]$ system application-upload /usr/local/share/applications/helm/security-profiles-operator-.tgz + +#. Verify the |SPO| tarball has been uploaded. + + .. code-block:: none + + ~(keystone_admin)]$ system application-list + +#. Apply the application. + + .. code-block:: none + + ~(keystone_admin)]$ system application-apply security-profiles-operator + +#. Monitor the status. + + .. code-block:: none + + ~(keystone_admin)]$ watch -n 5 system application-list + + OR + + ~(keystone_admin)]$ watch kubectl get pods -n security-profiles-operator + +The configuration of the installed ``security-profiles-operator`` application +is as follows: + +``security-profiles-operator`` + Runs as a deployment, replica count of 3 on the controller(s). + +``security-profiles-operator-webhook`` + Runs as a deployment, replica count of 3. + +``spod`` + Runs as a daemonset on every Kubernetes host (i.e., controller(s) and + worker(s)), where application pods can be scheduled. + +.. _remove-security-profiles-operator-spo: + +Remove Security Profiles Operator (SPO) +--------------------------------------- + +Run the following commands to remove |SPO|. This will remove pods and other +resources created by the application installation. + +.. note:: + + This procedure does not remove the apparmor profiles created using |SPO|, + You can delete the profiles previously created by following the procedure + described in :ref:`Delete a profile across all hosts using SPO + `. + + If an AppArmor profile is deleted, all pods with that AppArmor profile + annotation should be either removed or updated to remove the annotation. + +#. Remove the application. + + .. code-block:: none + + ~(keystone_admin)]$ system application-remove security-profiles-operator + +#. Delete the application. + + .. code-block:: none + + ~(keystone_admin)]$ system application-delete security-profiles-operator + +.. note:: + + To remove AppArmor from a |prod| deployment requires removing |SPO| as + specified in this section and then disabling AppArmor on all the host(s). + For more details, see :ref:`Enable/Disable AppArmor on a Host + `. + + +Disable AppArmor from a StarlingX deployment +-------------------------------------------- + +To disable AppArmor from a deployment, need to follow below steps: + +#. Remove |SPO| system app (refer to :ref:`Remove Security Profiles Operator + (SPO) `). + +#. Disable AppArmor on host(s) (refer to :ref:`Enable/Disable AppArmor on a + Host `). diff --git a/doc/source/security/kubernetes/profile-management-a8df19c86a5d.rst b/doc/source/security/kubernetes/profile-management-a8df19c86a5d.rst new file mode 100644 index 000000000..08b892936 --- /dev/null +++ b/doc/source/security/kubernetes/profile-management-a8df19c86a5d.rst @@ -0,0 +1,257 @@ +.. _profile-management-a8df19c86a5d: + +================== +Profile Management +================== + +AppArmor profiles can be managed using |SPO| |CRD| (``apparmorprofile``). A +user can load, update, and delete a profile. + +.. _load-a-profile-in-enforce-mode-across-all-hosts-using-spo: + +Load a profile in enforce mode across all hosts using SPO +--------------------------------------------------------- + +#. Apply the profile. + + .. code-block:: none + + $ vi apparmorprofile.yaml + --- + apiVersion: security-profiles-operator.x-k8s.io/v1alpha1 + kind: AppArmorProfile + metadata: + name: test-profile + annotations: + description: Block writing to any files in the disk. + spec: + policy: | + #include + profile test-profile flags=(attach_disconnected) { + #include + file, + # Deny all file writes. + deny /** w, + } + $ kubectl apply -f apparmorprofile.yaml + +#. Verify if ``apparmorprofile`` resource is created. + + .. code-block:: none + + $ kubectl get apparmorprofiles + + NAME AGE + test-profile 3d5h + +#. Verify if test-profile is loaded in enforce mode on a host. + + .. code-block:: none + + $ aa-status + + apparmor module is loaded. + 20 profiles are loaded. + 13 profiles are in enforce mode. + /usr/bin/man + /usr/lib/ipsec/charon + /usr/lib/ipsec/stroke + /usr/sbin/ntpd + cri-containerd.apparmor.d + docker-default + lsb_release + man_filter + man_groff + nvidia_modprobe + nvidia_modprobe//kmod + tcpdump + test-profile + 7 profiles are in complain mode. + /usr/bin/keystone-wsgi-public + /usr/sbin/sssd + /usr/sbin/sssd//null-/usr/libexec/sssd/sssd_be + /usr/sbin/sssd//null-/usr/libexec/sssd/sssd_nss + /usr/sbin/sssd//null-/usr/libexec/sssd/sssd_pam + + +Load a profile in complain mode across all hosts using SPO +---------------------------------------------------------- + +#. Apply the profile. + + .. code-block:: none + + $ vi apparmorprofile.yaml + --- + apiVersion: security-profiles-operator.x-k8s.io/v1alpha1 + kind: AppArmorProfile + metadata: + name: test-profile + annotations: + description: Block writing to any files in the disk. + spec: + policy: | + #include + profile test-profile flags=(attach_disconnected, complain) { + #include + file, + # Deny all file writes. + deny /** w, + } + $ kubectl apply -f apparmorprofile.yaml + +#. Verify if apparmorprofile resource is created. + + .. code-block:: none + + $ kubectl get apparmorprofiles + + NAME AGE + test-profile 3d5h + +#. Verify if test-profile is loaded in complain mode on a host. + + .. code-block:: none + + aa-status + apparmor module is loaded. + 20 profiles are loaded. + 12 profiles are in enforce mode. + /usr/bin/man + /usr/lib/ipsec/charon + /usr/lib/ipsec/stroke + /usr/sbin/ntpd + cri-containerd.apparmor.d + docker-default + lsb_release + man_filter + man_groff + nvidia_modprobe + nvidia_modprobe//kmod + tcpdump + 6 profiles are in complain mode. + /usr/bin/keystone-wsgi-public + /usr/sbin/sssd + /usr/sbin/sssd//null-/usr/libexec/sssd/sssd_be + /usr/sbin/sssd//null-/usr/libexec/sssd/sssd_nss + /usr/sbin/sssd//null-/usr/libexec/sssd/sssd_pam + test-profile + 0 processes have profiles defined. + 0 processes are in enforce mode. + 0 processes are in complain mode. + 0 processes are unconfined but have a profile defined. + + +Update a profile across all hosts using SPO +------------------------------------------- + +#. Update the policy section of the ``.yaml`` used to create the profile. + + .. code-block:: none + + $ vi apparmorprofile.yaml + --- + apiVersion: security-profiles-operator.x-k8s.io/v1alpha1 + kind: AppArmorProfile + metadata: + name: test-profile + annotations: + description: Block writing to any files in the disk. + spec: + policy: | + #include + profile test-profile flags=(attach_disconnected, complain) { + #include + file, + # Deny all file writes. + deny /** w, + network inet tcp, + network inet udp, + capability chown, + } + +#. Update the profile. + + .. code-block:: none + + $ kubectl apply -f apparmorprofile.yaml + +#. Verify if the test-profile is added. Check the test-profile content at + ``/etc/apparmor.d`` on a host. + + .. code-block:: none + + $ cat test-profile + #include + profile test-profile flags=(attach_disconnected, complain) { + #include + file, + # Deny all file writes. + deny /** w, + network inet tcp, + network inet udp, + capability chown, + } + +.. _delete-a-profile-across-all-hosts-using-spo: + +Delete a profile across all hosts using SPO +------------------------------------------- + +#. List the AppArmor profiles. + + .. code-block:: none + + $ kubectl get apparmorprofiles.security-profiles-operator.x-k8s.io + + NAME AGE + test-profile 4d1h + +#. Delete the AppArmor profiles using ``.yaml`` file as follows: + + .. code-block:: none + + $ kubectl delete -f apparmorprofile.yaml + + OR using imperative commands: + + .. code-block:: none + + $ kubectl delete apparmorprofiles.security-profiles-operator.x-k8s.io + +#. Verify if apparmorprofile resource is deleted. + + .. code-block:: none + + $ kubectl get apparmorprofiles.security-profiles-operator.x-k8s.io + No resources found in default namespace. + +#. Verify if test-profile is removed from a host using ``aa-status``. + + .. code-block:: none + + $ aa-status + apparmor module is loaded. + 20 profiles are loaded. + 13 profiles are in enforce mode. + /usr/bin/man + /usr/lib/ipsec/charon + /usr/lib/ipsec/stroke + /usr/sbin/ntpd + cri-containerd.apparmor.d + docker-default + lsb_release + man_filter + man_groff + nvidia_modprobe + nvidia_modprobe//kmod + tcpdump + 7 profiles are in complain mode. + /usr/bin/keystone-wsgi-public + /usr/sbin/sssd + /usr/sbin/sssd//null-/usr/libexec/sssd/sssd_be + /usr/sbin/sssd//null-/usr/libexec/sssd/sssd_nss + /usr/sbin/sssd//null-/usr/libexec/sssd/sssd_pam + + + diff --git a/doc/source/shared/abbrevs.txt b/doc/source/shared/abbrevs.txt index 78e864376..8a5c8e6b6 100755 --- a/doc/source/shared/abbrevs.txt +++ b/doc/source/shared/abbrevs.txt @@ -76,6 +76,7 @@ .. |LDAP| replace:: :abbr:`LDAP (Lightweight Directory Access Protocol)` .. |LDPC| replace:: :abbr:`LDPC (Low-Density Parity Check)` .. |LLDP| replace:: :abbr:`LLDP (Link Layer Discovery Protocol)` +.. |LSM| replace:: :abbr:`LSM (Linux Security Modules)` .. |LVG| replace:: :abbr:`LVG (Local Volume Groups)` .. |MAC| replace:: :abbr:`MAC (Media Access Control)` .. |MEC| replace:: :abbr:`MEC (Multi-access Edge Computing)` @@ -142,6 +143,7 @@ .. |SMT| replace:: :abbr:`SMT (Simultaneous Multithreading)` .. |SNAT| replace:: :abbr:`SNAT (Source Network Address Translation)` .. |SNMP| replace:: :abbr:`SNMP (Simple Network Management Protocol)` +.. |SPO| replace:: :abbr:`SPO (Security Profile Operator)` .. |SRIOV| replace:: :abbr:`SR-IOV (Single Root I/O Virtualization)` .. |SRIOVs| replace:: :abbr:`SR-IOVs (Single Root I/O Virtualizations)` .. |SSD| replace:: :abbr:`SSD (Solid State Drive)` diff --git a/doc/source/system_configuration/kubernetes/about-changing-external-registries-for-starlingx-installation.rst b/doc/source/system_configuration/kubernetes/about-changing-external-registries-for-starlingx-installation.rst index 637f35ca7..a99f8a3d2 100644 --- a/doc/source/system_configuration/kubernetes/about-changing-external-registries-for-starlingx-installation.rst +++ b/doc/source/system_configuration/kubernetes/about-changing-external-registries-for-starlingx-installation.rst @@ -38,21 +38,25 @@ This is an example of the output: .. code-block:: none - | 16485f1e-757c-46a9-a366-0820b0f2ab77 | docker | docker-registry | auth-secret | d76d3a01-7d28-4e17-a614-f10b7eb49438 | None | None | - | 4436a7ab-11bc-4adb-aa9a-d15fe7a5a337 | docker | docker-registry | type | docker | None | None | - | e9ac3877-bc1c-4bd0-8d4e-6ead5a09b07c | docker | docker-registry | url | old-registry.domain.com:5001/product-abc/starlingx/docker.io | None | None | - | 3f44da5a-020d-42af-a15c-bf54da1e4c94 | docker | elastic-registry | auth-secret | de5195da-a791-4d05-9bb2-0a106d65dd33 | None | None | - | afbc4d14-5359-4b54-9431-01fe83440cf6 | docker | elastic-registry | type | docker | None | None | - | 05644812-daee-43a0-89e3-45006a6807fd | docker | elastic-registry | url | old-registry.domain.com:5001/product-abc/starlingx/docker.elastic.co| None | None | - | 76c15302-62ec-44d8-8352-ae8e681dfb02 | docker | gcr-registry | auth-secret | 772f88cb-3355-4663-8a95-026409b629cb | None | None | - | 5d4004ed-c212-4cb0-b309-82225cc011a9 | docker | gcr-registry | type | docker | None | None | - | 18d8a51b-99b1-4caf-8e98-740dc3bdfd74 | docker | gcr-registry | url | old-registry.domain.com:5001/product-abc/starlingx/gcr.io | None | None | - | 64e8a11f-3be9-4086-992a-948a92f8441b | docker | k8s-registry | auth-secret | 4ba49153-fb12-4db6-9509-779ac4f1f2fa | None | None | - | eca50140-b082-4229-8ca3-562abd6e3693 | docker | k8s-registry | type | docker | None | None | - | 497a935c-c8fc-422e-88d3-e9cbd6d12a95 | docker | k8s-registry | url | old-registry.domain.com:5001/product-abc/starlingx/k8s.gcr.io | None | None | - | a84328a0-3219-4b54-b4fa-5903f25f70ea | docker | quay-registry | auth-secret | c293a43d-0e4b-4dec-a5f4-baffb65e07f0 | None | None | - | 96b6eb45-b101-4bcb-8168-3f9f79baaa7d | docker | quay-registry | type | docker | None | None | - | 0fe2e1b9-8005-4ff8-98c2-ba0ad66103b9 | docker | quay-registry | url | old-registry.domain.com:5001/product-abc/starlingx/quay.io | None | None | + | 16485f1e-757c-46a9-a366-0820b0f2ab77 | docker | docker-registry | auth-secret | d76d3a01-7d28-4e17-a614-f10b7eb49438 | None | None | + | 4436a7ab-11bc-4adb-aa9a-d15fe7a5a337 | docker | docker-registry | type | docker | None | None | + | e9ac3877-bc1c-4bd0-8d4e-6ead5a09b07c | docker | docker-registry | url | old-registry.domain.com:5001/product-abc/starlingx/docker.io | None | None | + | 3f44da5a-020d-42af-a15c-bf54da1e4c94 | docker | elastic-registry | auth-secret | de5195da-a791-4d05-9bb2-0a106d65dd33 | None | None | + | afbc4d14-5359-4b54-9431-01fe83440cf6 | docker | elastic-registry | type | docker | None | None | + | 05644812-daee-43a0-89e3-45006a6807fd | docker | elastic-registry | url | old-registry.domain.com:5001/product-abc/starlingx/docker.elastic.co| None | None | + | 76c15302-62ec-44d8-8352-ae8e681dfb02 | docker | gcr-registry | auth-secret | 772f88cb-3355-4663-8a95-026409b629cb | None | None | + | 5d4004ed-c212-4cb0-b309-82225cc011a9 | docker | gcr-registry | type | docker | None | None | + | 18d8a51b-99b1-4caf-8e98-740dc3bdfd74 | docker | gcr-registry | url | old-registry.domain.com:5001/product-abc/starlingx/gcr.io | None | None | + | 64e8a11f-3be9-4086-992a-948a92f8441b | docker | k8s-registry | auth-secret | 4ba49153-fb12-4db6-9509-779ac4f1f2fa | None | None | + | eca50140-b082-4229-8ca3-562abd6e3693 | docker | k8s-registry | type | docker | None | None | + | 497a935c-c8fc-422e-88d3-e9cbd6d12a95 | docker | k8s-registry | url | old-registry.domain.com:5001/product-abc/starlingx/k8s.gcr.io | None | None | + | a84328a0-3219-4b54-b4fa-5903f25f70ea | docker | quay-registry | auth-secret | c293a43d-0e4b-4dec-a5f4-baffb65e07f0 | None | None | + | 96b6eb45-b101-4bcb-8168-3f9f79baaa7d | docker | quay-registry | type | docker | None | None | + | 0fe2e1b9-8005-4ff8-98c2-ba0ad66103b9 | docker | quay-registry | url | old-registry.domain.com:5001/product-abc/starlingx/quay.io | None | None | + | d88d2562-2a58-43fb-ab42-d5e63c6bf500 | docker | registryk8s-registry | type | docker | None | None | + | fa8c3e00-b1b0-469b-8d73-5362f8d99725 | docker | registryk8s-registry | url | old-registry.domain.com:5001/product-abc/starlingx/registry.k8s.io | None | None | + | f3449be4-b8d5-43fd-8493-ede6429f411f | docker | registryk8s-registry | auth-secret | a48cfbac-849e-42cb-b012-b0b4f23bf2b9 | None | None | + The new registry uses **username** and **password** authentication. Its path is the same as the existing registry path. For example if ``docker.io`` path is diff --git a/doc/source/system_configuration/kubernetes/change-the-registry-url.rst b/doc/source/system_configuration/kubernetes/change-the-registry-url.rst index f7ee74bf5..9d3b01bb1 100644 --- a/doc/source/system_configuration/kubernetes/change-the-registry-url.rst +++ b/doc/source/system_configuration/kubernetes/change-the-registry-url.rst @@ -85,5 +85,18 @@ You will get the following output: | resource | None | +-------------+---------------------------------------------------------------------------+ + +-------------+---------------------------------------------------------------------------+ + | Property | Value | + +-------------+---------------------------------------------------------------------------+ + | uuid | ea52a3cd-5aae-425a-967e-5a2bc19a1398 | + | service | docker | + | section | registryk8s-registry | + | name | url | + | value | new-registry.domain.com:9001/product-abc/starlingx/registry.k8s.io | + | personality | None | + | resource | None | + +-------------+---------------------------------------------------------------------------+ + + To validate the registry, see :ref:`Display Updated Registries' URLs and Auth-Secrets `. \ No newline at end of file diff --git a/doc/source/system_configuration/kubernetes/create-the-registry-secrets.rst b/doc/source/system_configuration/kubernetes/create-the-registry-secrets.rst index b2e2f9b19..6457df2f3 100644 --- a/doc/source/system_configuration/kubernetes/create-the-registry-secrets.rst +++ b/doc/source/system_configuration/kubernetes/create-the-registry-secrets.rst @@ -163,5 +163,33 @@ You will get the following output: | resource | None | +-------------+--------------------------------------+ + +---------------+------------------------------------------------------------------------+ + | Field | Value | + +---------------+------------------------------------------------------------------------+ + | Secret href | http://controller:9311/v1/secrets/d88d2562-2a58-43fb-ab42-d5e63c6bf500 | + | Name | registryk8s-registry-secret | + | Created | None | + | Status | None | + | Content types | None | + | Algorithm | aes | + | Bit length | 256 | + | Secret type | opaque | + | Mode | cbc | + | Expiration | None | + +---------------+------------------------------------------------------------------------+ + + +-------------+--------------------------------------+ + | Property | Value | + +-------------+--------------------------------------+ + | uuid | fa8c3e00-b1b0-469b-8d73-5362f8d99725 | + | service | docker | + | section | registryk8s-registry | + | name | auth-secret | + | value | d88d2562-2a58-43fb-ab42-d5e63c6bf500 | + | personality | None | + | resource | None | + +-------------+--------------------------------------+ + + To update the registry secrets, go to :ref:`Update the Registries' Auth-Secrets `. \ No newline at end of file diff --git a/doc/source/system_configuration/kubernetes/validate-existing-registry-and-new-url.rst b/doc/source/system_configuration/kubernetes/validate-existing-registry-and-new-url.rst index 07ac15c1c..6924528ef 100644 --- a/doc/source/system_configuration/kubernetes/validate-existing-registry-and-new-url.rst +++ b/doc/source/system_configuration/kubernetes/validate-existing-registry-and-new-url.rst @@ -26,6 +26,8 @@ You will get the following output: elastic-registry URL is new-registry.domain.com:9001/product-abc/starlingx/docker.elastic.co gcr-registry URL is new-registry.domain.com:9001/product-abc/starlingx/gcr.io k8s-registry URL is new-registry.domain.com:9001/product-abc/starlingx/k8s.gcr.io + registryk8s-registry URL is new-registry.domain.com:9001/product-abc/starlingx/registry.k8s.io + If the existing registries used authentication, use the following command to display their auth-secrets: