How does AppArmor handle Linux-kernel mount namespaces? - linux

I've searched through wiki of AppArmor's wiki as well as tried Internet searches for "apparmor mount namespace" (or similar). However, I always draw a blank as how AppArmor deals with them, which is especially odd considering that OCI containers could not exist without mount namespaces. Does AppArmor take mount namespaces into any account at all, or does it simply check for the filename passed to some syscall?
If a process inside a container switches mount namespaces does AppArmor take notice at all, or is it simply mount namespace-agnostic in that it doesn't care? For instance, if a container process switches into the initial mount namespace, can I write AppArmor MAC rules to prevent such a process from accessing senstive host files, while the same files inside its own container are allowed for access?

can I write AppArmor MAC rules to prevent such a process from
accessing senstive host files.
Just don't give container access to sensitive host filesystem part. That means don't mount them into container. This is out of scope of AppArmor to take care of if you do.

I would say that AppArmor is partially linux kernel mount namespace aware.
I think the attach_disconnected flag in apparmor is an indication that apparmor knows if you are in the main OS mount namespace or a separate mount namespace.
The attach_disconnected flag is briefly described at this link (despite the warning at the top of the page claiming to be a draft):
https://gitlab.com/apparmor/apparmor/-/wikis/AppArmor_Core_Policy_Reference
The following reference, from a ubuntu apparmor discussion, provides useful and related information although not directly answering your question.
https://lists.ubuntu.com/archives/apparmor/2018-July/011722.html
The following references, from a usenix presentation, provides a proposal to add security namespaces to the Linux kernel for use by frameworks such as apparmor. This does not directly show how / if apparmor currently uses kernel mount namespaces for decision making, but it's related enough to be of interest.
https://www.usenix.org/sites/default/files/conference/protected-files/security18_slides_sun.pdf
https://www.usenix.org/conference/usenixsecurity18/presentation/sun
I don't know if my response here is complete enough to be considered a full answer to your questions, however I don't have enough reputation points to put this into a comment. I also found it difficult to know when the AppArmor documentation meant "apparmor policy namespace" vs "linux kernel mount namespace", when the word "namespace" was specified alone.

Related

LXC : Is it from linuxcontainers.org or part of Linux kernel?

I want to know about LXC and came across this site: https://linuxcontainers.org/lxc/introduction/; in this site, it talks about LXC, LXD, among others.
I am a bit confused, I am under the impression that LXC is a Linux kernel feature, so it should be present in Kernel itself. However, looking at the above site viz: https://linuxcontainers.org/lxc/introduction/, is this same when we say LXC (the kernel feature)? Or is LXC provided to the Linux kernel by https://linuxcontainers.org/lxc/introduction/?
How can I understand this subtle difference?
Most of the core features needed to operate Linux in containers are built into the kernel -- namespaces, control groups, virtual roots, etc. However, to assemble a usable container platform from these features requires a considerable amount of infrastructure. We need to manage container storage, create network links between containers, control per-container resource usage, etc. User-space programs can, and are, used to provide this infrastructure, and the tooling that goes with it.
I have written a series of articles on building a container from scratch that explains some of these issues:
http://kevinboone.me/containerfromscratch.html
It's possible in principle to build and connect containers using nothing but the features built into the kernel, and a bunch of shell scripts. Tools like LXC, Docker, and Podman all use the same kernel features (so far as I know), but they manipulate these features in different ways.

Mounting cgroups for Resource Management in Docker

This is in reference to https://docs.docker.com/config/containers/resource_constraints/#limit-a-containers-access-to-memory. I have already created working containers, running Docker version 18.05.0-ce on a Raspberry Pi (64-bit) using Raspbian Jessie Lite (essentially GUI-less Debian Jessie).
The documentation claims that you can just pass memory/cpu flags on the docker run command. But when I try something like docker run -it --name test --memory=512m container_os, it says:
WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap
I get a similar message about not having cpuset mounted if I pass a cpu-based flag, such as --cpuset-cpus. This obviously means that I don't have these different cgroups mounted for Docker to manage resources correctly, right?
Now referring to https://docs.docker.com/config/containers/runmetrics/#control-groups, I read the section about cgroups, but it wasn't super helpful to my understanding of the situation. So rather than just trying random kernel commands, does anyone with experience have a step-by-step explanation of how to do this the right way?
After quite a bit of research, I figured this out, in-case anyone else out there has this same problem.
In reference to https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt, which is extremely helpful on understanding cgroups, a kernel with all of the proper support should have most of the cgroups for docker mounted by default. If not, there's a command to do so:
From section 2.1 - Basic Usage
"To mount a cgroup hierarchy with all available subsystems, type:
mount -t cgroup xxx /sys/fs/cgroup
The "xxx" is not interpreted by the cgroup code, but will appear in
/proc/mounts so may be any useful identifying string that you like.
Note: Some subsystems do not work without some user input first. For instance,
if cpusets are enabled the user will have to populate the cpus and mems files
for each new cgroup created before that group can be used."
For this particular case, however, trying to mount an individual cgroup, such as cpuset, results in an error saying that the "cpuset special device does not exist". This is because the devs of Raspbian Jessie 8 didn't configure the kernel to support the cgroups that Docker uses for resource management by default. This can easily be determined by typing the docker info command, and seeing this at the bottom of the output:
WARNING: No swap limit support
WARNING: No cpu cfs quota support
WARNING: No cpu cfs period support
WARNING: No cpuset support
These are all of the cgroups that are needed for Docker to manage memory and CPU resources for containers. Testing to see if your kernel supports something like cpuset is easy. If the file /proc/filesystems has an entry that says nodev cpuset, then that means your kernel has cpuset support, but if you're reading this then it probably means it's just not configured in your kernel. That would call for a kernel reconfiguration and rebuild however, which is not so easy.
With the right kernel configurations, it just works automatically like it seems from the Docker Docs.

Linux sandbox with C, secure?

I'm developing a generic honeypot for TCP services as part of my BA thesis.
I'm currently using Chroot, Linux Namespaces, Secure Computing and Capabilities to provide some sort of a Sandbox.
My question is: Are there any points I have to be aware of? Since I have to mount /proc in the sandbox, I'm curious if it will affect the overall security of the host system.
(User namespaces are not an option btw.)
/* EDIT */
To be more clear: I'm using capabilities(7) and libseccomp to restrict the access to features such as syscalls for root and non-root users.
But what about files in /proc e.g. /proc/sys/* ? Should I blacklist files/directories with an empty bind-mount like firejail does?
As commented by Yann Droneaud, reading the src of systemd-nspawn helped a lot.
I found the following /proc subdirs which should be bind mounted read-only/inaccessible:
/* Make these files inaccessible to container payloads: they potentially leak information about kernel
* internals or the host's execution environment to the container */
PROC_INACCESSIBLE("/proc/kallsyms"),
PROC_INACCESSIBLE("/proc/kcore"),
PROC_INACCESSIBLE("/proc/keys"),
PROC_INACCESSIBLE("/proc/sysrq-trigger"),
PROC_INACCESSIBLE("/proc/timer_list"),
/* Make these directories read-only to container payloads: they show hardware information, and in some
* cases contain tunables the container really shouldn't have access to. */
PROC_READ_ONLY("/proc/acpi"),
PROC_READ_ONLY("/proc/apm"),
PROC_READ_ONLY("/proc/asound"),
PROC_READ_ONLY("/proc/bus"),
PROC_READ_ONLY("/proc/fs"),
PROC_READ_ONLY("/proc/irq"),
PROC_READ_ONLY("/proc/scsi"),

Kernel configurations for lxc

I am configuring Linux kernel 3.10.31ltsi and want to add the needed support for LXC, as far as I understood, cgroups and namespaces shall be available for LXC, but what are the configurations in menuconfig that need to be included?
You should use a script called "lxc-checkconfig" (which is part of LXC) to check whether your kernel supports or not all required settings; see
https://linuxcontainers.org/lxc/manpages/man1/lxc-checkconfig.1.html
As a side note, I think that LXC uses by default all namespaces; this means that you should set
CONFIG_UTS_NS, CONFIG_IPC_NS, CONFIG_USER_NS, CONFIG_PID_NS,
CONFIG_NET_NS, and the mount namesapces (forgot it's config entry).
Regarding cgroups - not sure, probably the memory, cpu and I/O cgroups controllers are mandatory, and maybe some more; use the lxc-checkconfig script.

Securty options in embeded linux?

I am working on an embedded Linux platform. In our platform there is only root user. Now we want to bring in security options like
1. Low Privileged user.
2. Allowing to run only executables from a particular location(only read permission).
3. Use Linux Containers
We have managed to add a low privileged user using the /etc/passwd file. But I have no idea how to do the rest. Is there any better options to implement security in the linux system. Any documentation or links are much appreciated.
Option two is achieved by the noexec flag on mounting. The slight challenge is figuring out exactly what to mount where; you'd want to mount / as noexec to get safety by default, but you need /sbin/mount to be executable. But you can probably make / read-only and mount all the writeable filesystems as noexec.

Resources