Fedora Modularity Introduction
Traditional Fedora systems have relied on individual application packages/RPMs and package groups for the installation and management of software on the system. While this model is well understood by both developers and administrators, it doesn’t fit well with many of Fedora’s long term goals, or the technical and usability goals of a solution based OS distribution. The proposed Modularity design intends to correct this by moving the focus from individual application packages to solution based modules which provide integrated and tested bundles (modules) that can be quickly installed on a system.
Initially these modules will rely on RPM packages to deliver the included packages, but the design of the module platform is such that modules can be composed from any number of application package formats, including containers. Modules can be used to deliver almost any data to the system, including a nested stack of other modules.
Another goal of the Modularity effort is to decompose the monolithic Fedora distribution into a collection of modules, each with different support lifetimes. For example, application modules can be maintained such that there is an older, stable version of the application available at the same time as the most recent version of the application. With traditional OS distributions administrators have had to make stability vs functionality decisions at the OS level, with Modularity these decisions can be made at the module level, allowing administrators more opportunities to successfully balance support and development needs.
The Modularity effort presents a number of opportunities for us to rethink how we deliver SELinux policy in Fedora, but with those opportunities comes challenges. The shift towards a modular OS offers us the chance to provide a default SELinux policy install that matches the installed applications, potentially improving usability and reducing the runtime policy size (better performance, smaller memory footprint, etc.). However, modularizing our SELinux policy delivery introduces new concerns around dependency management, object labeling, and support that will need to be addressed.
SELinux Modularity Introduction
The current Fedora approach to delivering SELinux policy is to deliver the entire distribution provided policy in a single RPM package. This approach worked well when SELinux was first introduced, undergoing rapid and substantial changes to the policy, and it fit within the existing Fedora RPM model of installing and managing the system. However, as the legacy Fedora model starts to shift towards a less monolithic approach, both with containers and the Fedora Modularity effort, so should the SELinux policy to better adapt to how systems are composed and managed; we are calling this effort “SELinux Modularity”.
The idea behind SELinux Modularity (SM) is to decompose our SELinux policy package such that the SELinux policy associated with a Fedora Modularity (FM) module is shipped as part of the FM module. While this represents a significant shift in how we deploy the core SELinux policy, it isn’t vastly different from what partners, ISVs, and other third-party SELinux policy providers do today. The current third-party application/policy model shares a number key points with the core ideas behind the SELinux Modularity design.
Synchronize SELinux Policy and Application Release
SELinux policy is tightly bound to the application, due both to changes in the design/implementation as well as to the intended usage. Deploying SELinux policy with the application allows the policy to be developed and tested alongside the application, instead of the current disjointed, and reactive, SELinux policy development process.
Distribute SELinux Policy Development and Support Burden
In order to continue to advance SELinux policy development it is important to find ways to distribute the development and support of application policies. Unfortunately, the current SELinux development and deployment models make this difficult. The recent improvements to the SELinux policy module store (priorities) should help remove some of the technical barriers around managing third-party SELinux policies, and I expect that the SELinux Modularity effort will continue to build upon these improvements through better tooling, documentation, and a well defined deployment mechanism for SELinux policies.
SELinux Modularity Impact
Decomposing the delivery of the SELinux policy has the potential to impact a large number of people and teams.
For those users who are satisfied with the default SELinux policy and configuration, there will likely be little impact; they may notice more SELinux activity during FM module management operations, but the impact should be negligible.
Users who customize their SELinux configuration either through third-party policy modules or a custom semanage based configuration (e.g. SELinux booleans, custom file labels, etc.) may experience a noticeable impact depending on their exact configuration, but it should be easily resolved (e.g. missing booleans due to the fact that they are no longer relevant).
Regardless of a customer’s level of SELinux customization, they will see benefits from the SELinux Modularity effort. The SELinux policy quality is expected to improve as the policy moves closer to the application modules, the SELinux impact on system resources should be less as the system will only install/load SELinux policy for the software installed on the system, and SELinux troubleshooting/customization should be improved as a side effect of the improved developer/QE tools and documentation.
Independent Software Vendors and Partners
ISVs that currently ship SELinux policy with their applications do so with little guidance from the distribution, and in many cases develop their own methods for managing their SELinux policy. The ISV experience should improve significantly with the SELinux Modularity effort as the entire system will be delivered as modules, with each module potentially delivering its own SELinux policy module. The same tools and guidance that we develop for our own use in developing, testing, and delivering SELinux policy in FM modules can be used by ISVs for their own products.
Fedora Engineering and Quality Teams
The current SELinux policy packaging and distribution model makes it difficult for teams to keep SELinux policy synchronized with their applications. Moving the SELinux policy closer to the application should encourage and enable application developers, and packagers, to be more proactive when it comes to testing and verification of the associated SELinux policy. Engineering teams will no longer have to worry about hitting SELinux policy problems late in the release cycle; teams can continuously test each change against the SELinux policy that will ship with their updated application. While it is difficult to predict all problem areas at the early design stages, it is reasonable to assume that there will be a transition period where problems are encountered. These issues will likely vary as each application/module, and each team, could present different challenges. However, due to the nature of the modularity effort, the transition can be done incrementally with a limited number of FM modules at any given time to limit the impact.
Fedora SELinux Core Team
The SELinux core team will be impacted the most as the SELinux Modularity effort is a significant change from how SELinux policy is delivered today. The creation of new tools and documentation will also present a challenge, but the Fedora SELinux Independent Policy effort should help reduce the amount of new work required. While this project will be difficult, as we near the end of the effort there should be a number of advantages for the SELinux core team: higher policy quality and reduced support burden as other teams engage in proactive testing, easier long term policy maintenance as policy can be branched and managed per-application/module, and higher ISV/third-party involvement as policy development/packaging becomes easier.
Upstream SELinux Community
As the Fedora Modularity effort is limited to Fedora and not the broader Linux community, many of the SELinux Modularity benefits will not be visible outside of Fedora based distributions. However, as Fedora is often considered the “Gold Standard” for SELinux in general purpose Linux distributions, a better SELinux experience on Fedora reflects well on the SELinux project as a whole.
Regardless of how Fedora deploys SELinux policy, the work on improving the individual SELinux policy modules, userspace tools, and kernel support will still remain useful upstream and our commitment to a strong upstream SELinux community will remain unchanged.
SELinux Modularity High Level Architecture
Decomposing the SELinux policy from a monolithic deliverable to a modular, extensible policy delivered as part of the Fedora Modularity modules is largely a packaging effort in the initial versions. While there are likely to be changes to policy development (policy structure, development processes, etc.) in order to take advantage of some of the benefits of the Fedora/SELinux Modularity effort, the development changes should be optional in the early stages and I would suggest keeping them to a minimum as we transition to a module based deployment model.
As part of the greater Fedora Modularity effort, the SELinux Modularity design relies heavily on the Fedora Modularity design. The design below describes the SELinux Modularity architecture and attempts to address concerns around hardware virtualization (KVM) and kernel virtualization (containers).
Fedora Modularity Solution Modules
The FM application modules provide the wide range of functionality and applications that users expect from Fedora. Just as we don’t provide SELinux policy for every application today, I don’t expect we will want to provide SELinux policy for every FM module. Only those security critical or high risk applications should be targeted for SELinux policy development, although this could change if community involvement in SELinux policy development increases. Those FM modules which contain applications that do have SELinux policy should include that policy, and only that policy, within the module itself. Unless the FM module is focused on SELinux policy development, troubleshooting, or management, the FM module should not need to include any SELinux components other than SELinux policy.
Persistent Object Labeling
FM modules which contain SELinux policy should also have special provisions to ensure persistent filesystem objects are relabeled when the FM module is installed, removed, and upgraded. With the majority of FM modules delivering applications via RPM packages in the near term, integration with RPM packages is critical. Support for additional package formats should be relatively straightforward as long as they support installation, removal, and upgrade hooks; the exact implementation will be specific to package format, but the ideas used in the RPM solution should be easily adapted to any new package format provided these hooks are available.
The current, monolithic SELinux policy RPM provides specfile macros for relabeling files on SELinux policy module installation and removal, with policy module upgrades treated as a combination remove/install operation. The SELinux policy module RPMs that ship as part of a FM module should make use of these macros to manage file labels across SELinux policy module operations. It is expected that the Fedora Independent Policy project will help provide additional documentation and guidance on persistent object labeling in third-party RPM packages.
SELinux Policy Dependencies
SELinux policy dependency tracking and resolution is one of the larger problems faced by the SELinux Modularity effort. Successfully tracking and resolving SELinux policy dependencies requires the identification of interfaces provided by the SELinux policy module (e.g. types), registering those interfaces with a dependency resolver, and the identification of all interfaces used by a SELinux policy module. There is also a separate SELinux policy design issue regarding how to structure policy and properly manage the interfaces across multiple FM modules with potentially different support lifetimes.
Solving SELinux Policy Dependencies Initially
In an effort to speed the implementation of the SELinux Modularity design and simplify most of the policy dependency tracking we plan to track dependencies at the policy module level. Creating versioned RPM packages for each of the SELinux policy modules, outside of the platform, we can leverage the existing RPM and DNF dependency tracking and resolution mechanisms. Resolving dependencies at such a coarse level also allows us to defer any SELinux policy redesigns that may be necessary to support dependency tracking at the more granular interface level.
The individual SELinux policy module packages should adopt a naming convention that makes it easy to identify the RPM package as a SELinux policy module. Versioning of the policy module packages should be independent of the associated application and FM module. The policy module’s RPM package version should follow the Semantic Versioning guidelines.
In addition to the packaging described above, some additional conventions should be followed to ensure sanity within the larger Fedora Modularity effort. SELinux policy dependencies must be limited to other FM modules in the same module stack, or the platform module; no other SELinux policy dependencies are allowed. In the case of SELinux policy modules common to multiple FM modules, a FM module stack utilizing SELinux policy-only FM modules should be used to provide the common policy.
Future Possibilities for SELinux Policy Dependency Tracking
Future design should be driven based on our experience supporting the initial design described above, but the possibility for dependency tracking at the SELinux policy interface level should be strongly considered. There is at least one SELinux policy effort currently underway that is intended to provide a well defined, versioned interface between policy modules. Unfortunately, this effort is likely to require additional SELinux policy development and is not something we can seriously consider for the initial SELinux Modularity implementation.
SELinux Policy Priority
We should remain consistent with our current priority guidance, although minor changes will be necessary. SELinux policy shipped via normal FM modules should be installed in the policy store with a higher priority than those installed via the base policy. The SELinux policy priority should obey the following order, listed in increasing priority: base, distribution provided FM modules, ISV/custom FM modules. Just as with the current priority levels, the recommended priority values should have sufficient spacing between them to allow for new priority levels to be inserted between the levels proposed here (e.g. set the predefined priority levels as multiples of 100).
SELinux Policy Conflicts
Since the SELinux policy shares a single global namespace there is always a risk of conflict across different SELinux policy modules. Currently this risk is mitigated by shipping the entire SELinux policy in a single package, but careless third party SELinux policy developers can still be affected. Conflicts between the Fedora provided SELinux policy modules can be managed via versioning and improved dependency checks which take into account SELinux policy interfaces (Reference Policy based modules), SELinux policy types (Reference Policy and CIL based modules), and the default file labeling information (Reference Policy and CIL based modules). Unfortunately, it is unlikely that we will ever be able to completely remove the risk of conflict for third-party SELinux policy modules as doing so would require a database of all the third-party/ISV SELinux policies. While we can’t remove the risk of third-party conflicts, the SELinux Modularity effort does not inherently make this any more of a problem than it is today, and experience has demonstrated this isn’t a significant concern. In fact, the documentation, tooling, and guidance developed in support of the SELinux Modularity and similar efforts (see the “SELinux Independent Policy” project) should help third-party developers avoid such conflicts through careful policy design and type namespacing.
SELinux Base Policy Considerations
FM modules which contain SELinux policy must include pre-compiled SELinux policy modules suitable for loading with semodule or similar tools. While the FM platform module will only provide a targeted/minimal SELinux base policy, and we only require FM modules to support the targeted/minimal base policy, we will support alternate base policies (see “Alternate SELinux Base Policies”), and therefore the FM solution modules must have provisions for installing multiple different SELinux policies, each to a different policy store. In order to prevent problems when changing base policies, if a FM module provides SELinux policy for multiple SELinux base policies, all of the SELinux policies must be installed regardless of if the base policy exists. If a FM module includes SELinux policy for a base policy that is not installed on the system, the policy module should be stored in a local cache and installed into the appropriate policy store if and when the alternate base policy is installed; this behavior could be disabled via configuration option if desired. The FM modules must also explicitly specify the SELinux policy store when installing SELinux policy modules to help prevent errors due to base policy mismatches. The FM modules may display a notification if the SELinux policy store does not exist on the system.
SELinux Policy Ownership
Responsibility for the development and support of the SELinux policies in the general FM solution modules will likely vary depending on the owner of the FM module and agreements between the module owner and the SELinux team. It is reasonable to expect that the Fedora SELinux team will own the SELinux policy in the early stages of the Fedora/SELinux Modularity effort, however, I expect that ownership will slowly transfer to the FM module owners/developers over time. It is possible, and perhaps expected, that the Fedora SELinux team will retain ownership of SELinux policy in a number of core FM modules; the exact division of labor can be determined at a later date.
Transferring SELinux policy ownership should only be done after the prospective owner has consulted with both the current owner and the core SELinux team in the case of Fedora provided policies. The prospective owner should be able to demonstrate sufficient skill with the existing policy such that all parties are confident in the prospective owners ability to successfully develop, test, and support the SELinux policy.
Fedora Modularity SELinux Policy Modules
In addition to the FM platform and solution modules, we may need to introduce FM modules which contain only SELinux policy. These new SELinux policy-only FM modules will help us resolve dependencies (see the dependency requirements in “Fedora Modularity Solution Modules”) and limit SELinux policy duplication across FM modules.
The SELinux policy-only FM modules are intended to be used as part of a larger FM module stack as they do not provide any visible functionality beyond additional SELinux policy. The FM SELinux policy-only modules help avoid the problem where a single SELinux policy module is required by multiple FM modules. While it is possible to solve such problems through the use of multiple, duplicated SELinux policy modules with different domain/type prefixes, this would result in an explosion of types (increased memory usage at runtime) and likely a support problem as the duplicated SELinux policies begin to diverge.
The SELinux policy-only FM modules should follow all of the normal FM module rules, including the SELinux policy dependency requirements.
The SELinux policy-only FM modules concept is dependent on the ability of multiple FM module stacks to contain the same module and recognize the existence of the shared FM module when it is already installed (potentially as part of another module stack).
Alternate SELinux Base Policies
We currently support different policy types, targeted/minimal and MLS, on Fedora and this requirement will continue into the future. Different SELinux base policies remain supported, just as they are today.
Fedora Modularity Special Considerations
The sections below describe some Fedora Modularity use cases that require special consideration, either due to their unusual nature or significance to the Fedora project.
Installation profiles are a way to customize the packages installed by the module at install time based on the desired configuration and usage. At the time of writing, the associated SELinux policy package(s) should be installed as part of the "default" profile. The “default” profile is the profile used when the administrator does not specify any of the other profiles provided by the module; all FM modules must include a “default” profile. Optionally, we suggest the creation of a new "container" installation profile which can be used when installing the SELinux policy package is not desired, e.g. installing a Fedora Module inside a container.
SELinux MLS Policy
Installation profiles have been considered as a potential way of installing the SELinux MLS policy, but this is likely a poor choice as it would interfere with administrators existing profile choices. The installation of the SELinux MLS policy, and modules, is described elsewhere in this document.
Container Based Modules
Fedora Modularity modules have the ability to encapsulate arbitrary package formats and while the majority of the FM modules are expected to be built on RPM packages in the near future, container based FM modules are expected to grow in number and importance.
Orchestrated containers are containers that are managed by a service external to the Fedora Modularity tools, Kubernetes is one example of a container orchestration system. Due to the fact that orchestrated containers run largely outside the control of the Fedora Modularity framework, it should be expected that the orchestration system would manage it’s own SELinux policy and configuration.
Should any SELinux policy and/or configuration be required to enable SELinux controls for the specific container orchestration system, these framework specific pieces could be delivered using a FM module if necessary.
Standalone containers are containers which are managed solely by the Fedora Modularity infrastructure. The container images are installed using FM modules and the containers are executed by a supported container engine (e.g. Docker, rkt) via systemd. At present the standalone containers are run with a SELinux domain specified in their associated systemd unit file, allowing the access privileges to be customized to the specific container. The unit file is shipped and installed as part of the FM module.
Due to the wide range of application security requirements, it is reasonable to expect that some standalone containers will rely on a standard, generic container domain while others will provide their own container specific SELinux policy. The work required to support standalone containers that provide their own policy should be very similar to RPM based FM modules which provide their own policy.
SELinux protection for VM guests using MCS and sVirt will remain the same as it is today, although the delivery of the related SELinux policy will change to reflect the Fedora/SELinux Modularity changes. It is not clear at this point if the virtualization SELinux policies will be included as part of the FM platform module or in dedicated virtualization and container modules, but this uncertainty should have little impact in the early stages of development.
FM modules which install individual VM guests should not provide their own SELinux policy modules for the host system, they should leverage the SELinux policy delivered with the VM or container infrastructure.
Frequently Asked Questions
Q: A single application has multiple FM modules, each representing a different version of the application; will they all provide their own SELinux policy module?
A: There are multiple options depending on the design of the SELinux policy associated with the application. If the SELinux policy varies greatly across different versions of the application, it may make sense for each FM module to provide its own SELinux policy module; although in this case it will be very important to ensure that the SELinux types and interfaces are namespaced not only with the application name, but also the application version, to prevent any collisions (e.g. “nginx18_exec_t” instead of “nginx_exec_t”). If the SELinux policy is similar across the different application versions, it may make sense to create a single common SELinux policy that is delivered as a SELinux policy-only FM module as part of a greater FM module stack including the application, the SELinux policy, and any other dependencies.
Q: How can third-party SELinux policy developers be sure their SELinux policy is compatible both with the existing platform SELinux policy as well as other third-party SELinux policies?
A: An important part of the SELinux Modularity effort is the creation of tooling, documentation, and guidance intended to help SELinux policy developers create quality policy modules. Tooling will be created to scan SELinux policy modules to help identify SELinux policy dependencies, and documentation will be created which clearly establishes what dependencies the platform SELinux policy provides. Guidance and best practices will also be created to help educate SELinux policy developers on how to develop SELinux policy which avoids conflicts with other SELinux policies and leverages the Fedora provided policy as much as possible. Finally, most, if not all, of the work going into the Fedora SELinux Independent Policy effort will remain useful here.