Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
SELinux Cookbook
SELinux Cookbook

SELinux Cookbook: Over 70 hands-on recipes to develop fully functional policies to confine your applications and users using SELinux

eBook
€20.98 €29.99
Paperback
€36.99
Subscription
Free Trial
Renews at €18.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Table of content icon View table of contents Preview book icon Preview Book

SELinux Cookbook

Chapter 1. The SELinux Development Environment

This chapter covers the setup of the SELinux policy development environment. We will cover the following topics in this chapter:

  • Creating the development environment
  • Building a simple SELinux module
  • Calling refpolicy interfaces
  • Creating our own interface
  • Using the refpolicy naming convention
  • Distributing SELinux policy modules

Introduction

Similar to any other software development, having a well-functioning development environment is essential to successfully create and manage SELinux policies. Such an environment should not only support version control, but also be able to quickly search through the sources or show definitions.

With SELinux, this means that the policy module sources (which are all readable text files) should be stored in a structured manner, the upstream project that provides SELinux policies should be readily accessible, and the necessary functions or scripts to query and search through the policies should be available.

Adventurous users might want to take a look at the SELinux Policy IDE (SLIDE) as offered by Tresys Technology (http://oss.tresys.com/projects/slide). In this book, we do not focus on this IDE; instead, we use whatever file editor the user wants (such as VIM, Emacs, or Kate) and enhance the environment through the necessary shell functions and commands.

Before we cover the setup of the development environment, let's do a quick recapitulation of what SELinux is.

About SELinux

The Security Enhanced Linux (SELinux) project is the result of projects initiated and supported by the US National Security Agency (NSA) and came to life in December 2000. It is the implementation of a security system architecture with a flexible, policy-driven configuration approach. This architecture is called the Flux Advanced Security Kernel (Flask), and its related resources are still an important read for everyone involved with SELinux.

Most papers are linked through the Flask website at http://www.cs.utah.edu/flux/fluke/html/flask.html. The following are some examples of these papers:

  • The paper called The Inevitability of Failure: The Flawed Assumption of Security in Modern Computing Environments is still a very topical paper on why mandatory access controls are needed in operating systems
  • The NSA publication, Implementing SELinux as a Linux Security Module, available at http://www.nsa.gov/research/_files/publications/implementing_selinux.pdf, goes deeper into how SELinux is implemented

Nowadays, SELinux can be best seen as an additional layer of security services on top of the existing Linux operating system. It is part of the mainstream Linux kernel and uses the Linux Security Modules (LSM) interfaces to hook into the interaction between processes (user space) and resources. It manages various access services (such as the reading of files, getting directory attributes, binding to domain sockets, connecting to TCP sockets, and gaining additional capabilities) through a powerful approach called type enforcement.

The following diagram displays the high-level functional position of the SELinux subsystem. Whenever a subject (in the drawing, this is the Application) wants to perform an action against a resource, this action is first checked by the Discretionary Access Control mechanism that the Linux kernel provides. After the action is checked and allowed by the DAC mechanism, the LSM implementation (against which SELinux is registered) calls the hooks that the SELinux subsystem has provided. SELinux then checks the policy (through the cache, and if the access is not registered in the cache yet, it checks in the entire policy) and returns whether the access should be allowed or not.

About SELinux

SELinux is a Mandatory Access Control system in which the governed activities on the system are defined in rules that are documented through a policy. This policy is applicable to all processes of the system and enforced through the SELinux subsystem, which is part of the Linux kernel. Anything that is not allowed by the policy will not be allowed at all—security is not left at the discretion of the user or correctness of the application. Unlike Linux DAC restrictions, enforcement itself (the SELinux code) is separate from the rules (the SELinux policy). The rules document what should be considered as acceptable behavior on the system. Actions that do not fit the policy will be denied by the SELinux subsystem.

In SELinux, a set of access control mechanisms are supported. The most visible one is its type enforcement in which privileges of a subject (be it the kernel or a Linux process) towards an object (such as a file, device, system capability, or security control) are granted based on the current security context of that subject. This security context is most often represented through a readable string such as staff_u:staff_r:staff_t:s0:c0,c3. This string represents the SELinux user (staff_u), SELinux role (staff_r), SELinux type/domain (staff_t), and optionally, the SELinux sensitivity level or security clearance, which provides both the sensitivity (s0) as well as assigned categories (c0,c3).

Alongside type enforcement, SELinux has several other features as well. For instance, it provides a role-based access control system by assigning valid domains (which are SELinux types assigned to running processes) to roles. If a role is not granted a particular domain, then that role cannot execute tasks or applications associated with that domain. SELinux also supports user-based access controls, thus limiting information flow and governing data sharing between SELinux users.

Another stronghold within SELinux is its support for sensitivities (which SELinux displays as integers, but these integers can very well be interpreted as public, internal, confidential, and so on) as well as access categories. Through the constraints that SELinux can impose in its policy, systems can be made to largely abide by the Bell-LaPadula model (https://en.wikipedia.org/wiki/Bell-LaPadula_model). This model supports information flow restrictions such as no read up (lower sensitivities cannot read information from higher sensitivities) and no write down (higher sensitivities cannot leak information to lower sensitivities).

The role of the SELinux policy

The SELinux policy itself is a representation of what the security administrator (the role that is usually mentioned as being the owner of what is and isn't allowed on a system) finds acceptable, expected, and normalized behavior:

  • Acceptable: Application and user behavior will be acceptable because it will be allowed on the system by the policy
  • Expected: Application and user behavior will be expected as the policy usually doesn't (or shouldn't) contain access vectors (a permission assigned to a subject towards a particular object) that are not applicable to the system, even if it would be acceptable on other systems in the environment
  • Normalized: Application and user behavior will be normalized not in the sense of database normalization, but as in normality—something that is consistent with the most common behavior of the process

As a policy represents these behaviors, correct tuning and development of the policy is extremely important. This is why the SELinux Cookbook will focus on policy development and policy principles.

A policy that is too restrictive will cause applications to malfunction, often in ways that its users will find unexpected. It will not be surprising to the security administrator of course, as he knows that the policy dictates what is allowed, and he is (or at least should be) perfectly aware of what the policy says.

However, a policy that is too broad will not result in such behavior. On the contrary, everything will work as expected. Sadly, when nonstandard or abnormal behavior is triggered, the (too) broadly defined policy might still allow this nonstandard or abnormal behavior to happen. When this abnormal behavior is an exploited vulnerability, then SELinux—as powerful as it can be—has nothing to deter the exploit, as the policy itself has granted the access. Another example of this principle would be a network firewall, whose policy can be too open as well.

Through the packaged approach that policies provide (SELinux policies are like loadable kernel modules, but then for the SELinux subsystem), administrators can push the policies to one or more systems, usually through the package management system or centralized configuration management system of choice. Unlike Linux DAC controls, which need to be applied on the files themselves, SELinux policies are much easier to handle and are even versionable—a trait much appreciated by administrators in larger environments.

The example

Throughout this book, we will often come across settings that are optional or whose value is heavily dependent on the choices made by the system administrator. In order to not repeat documenting and explaining when a setting or value is configurable, we will use the following configuration settings:

  • The SELinux type (which is configured in /etc/selinux/config) will be MCS in this book. It uses an MLS-enabled, single-sensitivity policy definition. This means that contexts will always have a sensitivity level or security clearance assigned when displayed, and the location of the SELinux policy configuration will always be shown in /etc/selinux/mcs/. Make sure to substitute this path with your own if the policy store on your environment is named differently. For instance, a Red Hat or Fedora installation defaults to /etc/selinux/targeted/.
  • Operations will be documented as they run through restricted users, which are aptly named user (for an unprivileged end user assigned the user_r role), staff (for a user that might perform administrative tasks and is assigned the staff_r and sysadm_r roles), and root (which is mapped to the sysadm_r role). Distributions might have users associated with the unconfined_r role. Whenever a step can be skipped for unconfined users, it will be explicitly mentioned.

Creating the development environment

We will now create a development environment in which the SELinux policies and upstream project code as well as the functions we use to easily query the SELinux policies will be stored. This environment will have the following three top-level locations:

  • local/: This location contains the SELinux rules that are local to the system and not part of a cooperatively developed repository (that is, where other developers work)
  • centralized/: This location contains checkouts of the various repositories used in the development environment
  • bin/: This location contains the supporting script(s) we will use to query the policy sources as well as troubleshoot the SELinux issues

In this exercise, we will also populate the centralized/ location with a checkout: the SELinux policy tree that is used by the current system.

Getting ready

Look for a good location where the development environment should be stored. This usually is a location in the user's home directory, such as /home/staff/dev/selinux/. Whenever this book references a location with respect to the development environment, it will use the ${DEVROOT} variable to refer to this location.

Another piece of information that we need is the location of the repository that hosts the SELinux policies of the current system. This location is distribution specific, so consult the distribution site for more information. At the time of writing this book, the policies for Gentoo Linux and Fedora can be found at the following locations:

Whenever version control is used, we will use git in this book. Other version control systems exist as well, but this too is outside the scope of this book.

How to do it…

To create the development environment used in this book, perform the following steps:

  1. Create the necessary directories:
    ~$ cd ${DEVROOT}
    ~$ mkdir local centralized bin
    
  2. Create a checkout of the distributions' SELinux policy tree (which, in this example, is based on the Gentoo Linux repository):
    ~$ cd ${DEVROOT}/centralized
    ~$ git clone git://git.overlays.gentoo.org/proj/hardened-refpolicy.git
    
  3. Create a git repository for the policies that we will develop throughout this book:
    ~$ cd ${DEVROOT}/local
    ~$ git init
    
  4. Add the functions.sh script, which is available through the download pack of this book, to the ${DEVROOT}/bin/ location.
  5. Edit the .profile, .bashrc, or other shell configuration files that are sourced when our Linux user logs on to the system, and add in the following code:
    # Substitute /home/staff/dev/selinux with your DEVROOT
    DEVROOT=/home/staff/dev/selinux
    # Substitute the next location with your distributions' policy checkout
    POLICY_LOCATION=${DEVROOT}/centralized/hardened-refpolicy/
    source ${DEVROOT}/bin/functions.sh
  6. Log out and log in again, and verify that the environment is working by requesting the definition of the files_read_etc_files interface:
    ~$ seshowif files_read_etc_files
    interface(`files_read_etc_files',`
      gen_require(`
        type etc_t;
      ')
    
      allow $1 etc_t:dir list_dir_perms;
      read_files_pattern($1, etc_t, etc_t)
      read_lnk_files_pattern($1, etc_t, etc_t)
    ')
    

How it works…

The setup of the development environment helps us deal with policy development for further recipes. The checkout of the distributions' SELinux policy tree is to query the existing policy rules while developing new policies. SELinux does not require to have the policy sources available on a system (only the compiled binary SELinux policy modules and parts of the SELinux policy rules, which can be used by other policy modules). As a result, default installations usually do not have the policy rules available on the system.

By having the checkout at our disposal, we can review the existing SELinux policy files and happily use examples from it for our own use. A major user of this checkout is the functions.sh script, which uses the ${POLICY_LOCATION} variable to know where the checkout is hosted. This script provides several functions that we'll use throughout this book; they will also help in querying the sources.

By sourcing this functions.sh script during log on, these functions are readily available in the user's shell. One of these functions is the seshowif function, which displays the rules of a particular interface. The example given shows the definition of the files_read_etc_files interface, which we used to validate that our setup is working correctly.

The functions.sh script can also work with the interface files that are available through /usr/share/selinux/devel/ (on Fedora/Red Hat systems), making the checkout of the policy repository optional if the user does not need access to the complete policy rules. The policy location defined then is as follows:

export POLICY_LOCATION=/usr/share/selinux/devel/

There's more...

Next to the distributions' SELinux policy tree, one can also use the reference policy SELinux tree. This is the upstream project that most, if not all, Linux distributions use as the source of their policies. It has to be said though that the reference policy often lags behind on the policy repositories of the individual distributions, as it has stricter acceptance criteria for policy enhancements.

It also doesn't hurt to check out the SELinux policy repositories of other distributions. Often, Linux distributions first do SELinux policy updates on their own repository before pushing their changes to the reference policy (which is called upstreaming in the free software development community). By looking at other distributions' repositories, developers can easily see if the necessary changes have been made in the past already (and are thus more likely to be correct).

See also

For more information about the topics covered in this recipe, refer to the following resources:

Building a simple SELinux module

Now that we have a development environment, it is time to create our first SELinux policy module. As its purpose does not matter at this point, we will focus on a privilege that is by default not allowed (and rightfully so) yet easy to verify, as we want to make sure that our policy development approach works. The privilege we are going to grant is to allow the system logger to write to a logfile labeled named_conf_t (the type used for the configuration of the BIND DNS server—known as named).

Note

Building SELinux policy modules is to extend the existing policy with more rules that allow certain accesses. It is not possible to create a policy module that reduces the allowed privileges for a domain. If this is needed, the policy module needs to recreate and substitute the existing policy (and thus, a distribution-provided policy will need to be removed from the system).

Getting ready

Before we get started, we first need to make sure that we can test the outcome of the change. A simple method would be to change the context of the /var/log/messages file (or another general logfile that the system logger is configured to use) and send messages through the system logger using the logger command:

~$ logger "Just a simple log event"
~$ tail /var/log/messages

Verify that the message has indeed been delivered by looking at the last lines shown through the tail command. Then, change the context and try again. The event should not be shown, and a denial should be logged by the audit daemon:

~# chcon -t named_conf_t /var/log/messages
~$ logger "Another simple log event"
~$ tail /var/log/messages
~# ausearch -m avc -ts recent

With this in place, we can now create our first simple SELinux module.

How to do it…

Building a new SELinux policy is a matter of going through the following steps:

  1. Create a file called mylogging.te inside ${DEVROOT}/local with the following content:
    policy_module(mylogging, 0.1)
    gen_require(`
      type syslogd_t;
      type named_conf_t;
     ')
    # Allow writing to named_conf_t files
    allow syslogd_t named_conf_t:file { getattr append lock ioctl open write };
  2. Copy or link the Makefile file available in /usr/share/selinux/devel/ or /usr/share/selinux/mcs/include/ (the exact location is distribution specific) to the current directory:
    ~$ ln –s /usr/share/selinux/devel/Makefile
    
  3. Build the SELinux policy module through this Makefile. The target is to name the (target) policy module with the .pp suffix:
    ~$ make mylogging.pp
    
  4. Switch to the root user, and if we are logged on through an unprivileged SELinux domain/role, switch to the sysadm_r or secadm_r role (this is not needed if the current user domain is already sysadm_t or unconfined_t):
    ~$ sudo –r sysadm_r –t sysadm_t -s
    
  5. Now, load the SELinux policy module (which will immediately activate the newly defined SELinux policy):
    ~# semodule –i mylogging.pp
    
  6. Verify that the newly defined SELinux policy is active by generating a new log event and by looking at the logfile to see if it has indeed been registered.
  7. Commit the newly created files to the repository:
    ~$ cd ${DEVROOT}/local
    ~$ git add mylogging.te Makefile
    ~$ git commit –m 'Adding mylogging.te which allows the system logger to write to the named configuration file type named_conf_t'
    

    When verified, reset the context of the logfile using restorecon /var/log/messages and remove the policy module from the subsystem using semodule -r mylogging. After all, we do not want this rule to stay active.

How it works…

There are three important, new aspects of SELinux policy development that we got in touch with in this recipe:

  • A policy source file called mylogging.te was created
  • A generated, binary policy module called mylogging.pp was built
  • The binary policy file, mylogging.pp, is added to the active policy store on the system

At the end, we committed the file to our local repository. Using version control on policy files is recommended in order to track changes across time. A good hint would be to tag new releases of the policies—if users ever report issues with the policy, you can then ask them for the SELinux policy module version (through semodule –l) and use the tags in the repository to easily find rules for that particular policy module.

In the remainder of this book, we will no longer use git add/commit so that we can focus on the SELinux recipes.

The policy source file

In the recipe, we created a policy source file called mylogging.te, which contains the raw SELinux policy rules. The name, mylogging, is not chosen at random; it is a common best practice to name custom modules starting with my and followed by the name of the SELinux policy module whose content we are enhancing (in our case, the logging module that provides the SELinux policy for everything that is system-logging related). The .te suffix is not just a convention (referring to the type enforcement part of SELinux); the build system requires the .te suffix.

The policy module rules start with the policy_module(…) call, which tells the build system that the file will become a loadable SELinux policy module with the given name and version. This name and version will be displayed by the semodule command if we ask it to list all the currently loaded SELinux policy modules:

~# semodule –l
aide  1.8.0
alsa  1.13.0

mylogging  0.1

The best practice is to keep all rules for a single domain within a policy module. If rules for multiple unrelated domains are needed, it is recommended that you create multiple modules, as this isolates the policy rules and makes modifications more manageable.

In this simple example, we did not follow this best practice (yet). Instead, we told the SELinux subsystem that the policy is going to be enhanced with an access vector for syslogd_t. The access vector here is to allow this domain a set of permissions against files that are labeled as named_conf_t.

The binary policy module

When we called the Makefile file, the underlying scripts built a loadable binary SELinux policy module. Such files have the .pp suffix and are ready to be loaded into the policy store. The Makefile file called might not be installed by default; some distributions require specific development packages to be installed (such as selinux-policy-devel in Fedora).

There is no nice way of retrieving the sources of a policy if we are only given the .pp file. Sure, there are commands such as semodule_unpackage and sedismod available, but these will only give a low-level view of the rules, not the original .te code. So, make sure to have backups, and as we saw in the example, use a versioning system to control changes across time.

Loading a policy into the policy store

To load the newly created policy into the policy store, we called the semodule command. This application is responsible for managing the policy store (which is the set of all SELinux policy modules together with the base policy module) and linking or unlinking the modules together into a final policy.

This final policy (which can be found at /etc/selinux/mcs/policy) is then loaded into the SELinux subsystem itself and enforced.

There's more...

Throughout this book, the build system used is based on the reference policy build system. This is a collection of M4 macros and affiliated scripts that make the development of SELinux policies easier. This is, however, not the only way of creating SELinux policies.

When visiting online resources, you might come across SELinux policy modules whose structure looks like the following:

module somename 1.0;
require {
  type some_type_t;
  type another_type_t;
}
allow some_type_t another_type_t:dir { read search };

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

These are policy files that do not use the reference policy build system. To build such files, we first create an intermediate module file with checkmodule, after which we package the module file towards a loadable binary SELinux policy with semodule_package:

~$ checkmodule -M –m –o somename.mod somename.te
~$ semodule_package –m somename.mod –o somename.pp

To keep things simple, we will stick to the reference policy build system.

See also

Many topics and areas have been touched upon in this recipe. More information can be found at the following resources:

Calling refpolicy interfaces

Writing up SELinux policies entirely using the standard language constructs offered by SELinux is doable, but it is prone to error and not manageable in the long term. To support a more simple language construct, the reference policy project uses a set of M4 macros that are expanded with the underlying SELinux policy statements when the policy is built.

The API that policy developers can use can be consulted online, but most systems also have this information available onsite at /usr/share/doc/selinux-*/. Finding proper interfaces requires some practice though, which is why one of the functions that we installed earlier (as part of the development environment) simplifies this for us.

In this recipe, we are going to edit the mylogging.te file we generated earlier with the right reference policy macro.

How to do it…

To use reference policy interfaces in an SELinux policy module, the following approach can be taken:

  1. Use the sefinddef function to find permission groups or patterns to write to files:
    ~$ sefinddef 'file.*write'
    define(`write_files_pattern',`
      allow $1 $3:file write_file_perms;
    
    define(`write_file_perms',`{ getattr write append lock ioctl open }')
    
    
  2. Use the seshowdef function to show the full nature of the write_files_pattern definition:
    ~$ seshowdef write_files_pattern
    define(`write_files_pattern',`
      allow $1 $2:dir search_dir_perms;
      allow $1 $3:file write_file_perms;
    ')
    
  3. Use the sefindif function to find the interface that will allow writing to named_conf_t:
    ~$ sefindif 'write_files_pattern.*named_conf_t'
    contrib/bind.if: interface(`bind_write_config',`
    contrib/bind.if:   write_files_pattern($1, named_conf_t, named_conf_t)
    
  4. Now, update the mylogging.te file to use this function. The file should now look like the following:
    policy_module(mylogging, 0.2)
    gen_require(`
      type syslogd_t;
    ')
    bind_write_config(syslogd_t)

    Note

    Note the use of the backtick (`) and single quote ('). Whenever definitions are used, they need to start with a backtick and end with a single quote.

  5. Rebuild and reload the policy module, and then rerun the tests we did earlier to verify that this still allows us to write to the named_conf_t labeled file.

How it works…

One of the principles behind the build system of the reference policy is that an SELinux policy module should not directly mention SELinux types that are not related to that module. Whenever a policy module needs to define rules against a type that is defined by a different module, interfaces defined by that different module should be used instead.

In our example, we need the interface used by the BIND SELinux policy (which handles the BIND-named daemon policy rules); this interface allows us to write to the BIND DNS server configuration file type (named_conf_t). We can check the online API, the API documentation in /usr/share/doc/selinux-*, or just guess the interface name. However, in order to be certain that the interface does what we need, we need to query the interface definitions themselves.

That is where the sefinddef, seshowdef, sefindif, and seshowif functions come into play. These functions are not part of any SELinux user space—they are provided through the functions.sh file we installed earlier and are simple awk/grep/sed combinations against the SELinux policy files.

With sefinddef (the SELinux find definition), we can search through the support macros (not related to a particular SELinux policy module) for any definition that matches the expression given to it. In this recipe, we gave file.*write as the expression to look for. The seshowdef (SELinux show definition) function shows us the entire definition of the given pattern.

The sefindif (SELinux find interface) function then allows us to find an interface that the SELinux policy provides. In this recipe, we used it to search for the interface that allows a domain to write to the BIND DNS server configuration files. There is also a seshowif (SELinux show interface) function that shows us the entire interface definition like the following:

~$ seshowif bind_write_config
interface(`bind_write_config',`
  gen_require(`
    type named_conf_t;
  ')
  write_files_pattern($1, named_conf_t, named_conf_t)
  allow $1 named_conf_t:file setattr_file_perms;
')

This example interface nicely shows how interfaces are handled by the SELinux reference policy build system. Whenever such an interface is called, one or more arguments are given to the interface. In our case, we passed on syslogd_t as the first (and only) argument.

The build system then substitutes every $1 occurrence in the interface with the first argument, effectively expanding the call to the following code:

write_files_pattern(syslogd_t, named_conf_t, named_conf_t)
allow syslogd_t named_conf_t:file setattr_file_perms;

The call to write_files_pattern is then expanded with the definition we saw earlier.

For the policy developer, this is all handled transparently. The sources of the SELinux policy file stay well-formatted and only call the interfaces. It is at build time that the expansion of the various interfaces is done. This allows developers to have nicely segregated, compartmentalized policy definitions.

See also

Creating our own interface

Being able to call interfaces is nice, but when we develop SELinux policies, we will run into situations where we need to create our own interface for the SELinux module we are developing. This is done through a file with an .if extension.

In this recipe, we are going to extend the mylogging policy with an interface that allows other domains to execute the system log daemon binary (but without running this binary with the privileges of the system logger itself; this would be called a domain transition in SELinux).

How to do it…

  1. If our current context is an unprivileged user domain (as unconfined domains are highly privileged and can do almost everything), we can try executing the system logger daemon (syslog-ng or rsyslog) directly and have it fail as follows:
    ~$ /usr/sbin/syslog-ng --help
    bash: /usr/sbin/syslog-ng: Permission denied
    
  2. Now, create the mylogging.if file (in the same location where mylogging.te is) with the following content, granting all permissions needed to execute the binary:
    ## <summary>Local adaptation to the system logging SELinux policy</summary>
     
    ##########################################
    ## <summary>
    ##    Execute the system logging daemon in the caller domain
    ## </summary>
    ## <desc>
    ##   <p>
    ##     This does not include a transition.
    ##   </p>
    ## </desc>
    ## <param name="domain">
    ##    <summary>
    ##      Domain allowed access.
    ##    </summary>
    ## </param>
    #
    interface(`logging_exec_syslog',`
      gen_require(`
        type syslogd_exec_t;
      ')
      can_exec($1, syslogd_exec_t)
    ')
  3. Create a new SELinux policy module for the user domain; this policy should be able to execute the system logger directly. For instance, for the sysadm_t domain, we would create a mysysadm.te file with the following content:
    policy_module(mysysadm, 0.1)
    gen_require(`
      type sysadm_t;
    ')
    logging_exec_syslog(sysadm_t)
  4. Build the mysysadm policy module and load it. Then, test to see if the daemon binary can now be executed directly:
    ~$ /usr/sbin/syslog-ng --help
    

How it works…

Let's first look at how the build system knows where the interface definitions are. Then, we'll cover the in-line comment system used in the example.

The location of the interface definitions

Whenever an SELinux policy module is built, the build system sources all interface files it finds at the following locations:

  • /usr/share/selinux/mcs/include/* or /usr/share/selinux/devel/include/* (depending on the Linux distribution)
  • The current working directory

The first location is where the interface files of all the SELinux modules provided by the Linux distribution are stored. The files are inside subdirectories named after particular categories (the reference policy calls these layers, but this is only used to make some structure amongst the definitions, nothing else) such as contrib/, system/, and roles/.

For local development of SELinux policies, this location is usually not writable. If we develop our own policy modules, then this would mean that none of the locally managed SELinux policy files can use interfaces of the other local interface files. The Makefile file, therefore, also sources all interface files it finds in the current working directory.

The in-line documentation

Inside the interface file created, we notice a few XML-like structures as comments. These comments are prefixed by a double hash sign (##) and are used by the reference policy build system to generate the API documentation (which can be found at /usr/share/doc/selinux-*).

For local policies, this in-line documentation is not used and, thus, not mandatory. However, writing the documentation even for local policies helps us in documenting the rules better. Also, if we ever want to push our changes upstream, this in-line documentation will be requested anyway.

The comment system uses the following constructs:

  • Right before an interface definition, we encounter a <summary> element, which provides a one-sentence description of the interface
  • Additional information can then be provided through a <desc> element under which the HTML code can be placed for documenting the interface further
  • Every parameter to an interface is documented through a <param> entity, which again contains a <summary> line

See also

Using the refpolicy naming convention

The interface names used to simplify policy development can be freely chosen. However, the reference policy itself uses a naming convention to try and structure the names used so that the SELinux policy developers can easily find the interfaces they need—if they exist—and give an unambiguous name to an interface they want to create.

The naming convention for the reference policy is available online at http://oss.tresys.com/projects/refpolicy/wiki/InterfaceNaming.

Getting ready

In this recipe, we'll do a pen-and-paper exercise to see how the naming convention works. In the example, we will create interface names for three situations:

  • To read all logfiles
  • To connect to the HTTP port over TCP
  • To not audit getting the attributes of user home directories

How to do it…

  1. First we need to figure out the file types that are involved in the situations:
    • Generic logfiles are var_log_t (as can be seen by querying the label of /var/log/itself):
      ~$ ls -dZ /var/log
      drwxr-xr-x. root root system_u:object_r:var_log_t:s0 /var/log
      
    • When we deal with all logfiles, we can safely assume this is handled by an SELinux attribute. Let's look at the attributes for the generic var_log_t type:
      ~$ seinfo –tvar_log_t –x
        var_log_t
          file_type
          non_security_file_type
          mountpoint
          non_auth_file_type
          logfile
      
    • The logfile attribute looks like an interesting hit. We can now grep through the policy sources to figure out which SELinux policy modules handle the logfile attribute, or use sefindif (assuming that there are interfaces defined that handle this attribute):
      ~$ sefindif 'attribute logfile'
      system/logging.if: interface(`logging_log_file',`
      
      
    • For the logfiles example, the module we need is called logging as can be seen from the sefindif output. Similarly, we will find that for the HTTP port, the module is corenet, and home directories are userdom.
  2. Next, we check whether there is a modifier. The first two situations have no specific modifier (all the actions are regular verbs). The last example has one: do not audit. In the SELinux policy language, this is known as a dontaudit statement.
  3. Now, let's look at the verbs involved. This is mostly based on experience, but the situations show that there is a huge correlation between the verbs and the eventually chosen refpolicy name (which usually uses SELinux permission names):
    • In the first situation, this is read
    • The second one has connect over TCP, which is translated into tcp_connect
    • The last situation has getting the attributes, so it is translated as getattr
  4. Finally, let's look at the object that is being referenced:
    • In the first situation, this is all logfiles, which we will name all_logs
    • In the second situation, this is HTTP port, so we will name http_port
    • The third situation has user home directories, so we will name user_home_dirs
  5. Combining this gives us the following interface names:
    • Read all logfiles: logging_read_all_logs
    • Connect to the HTTP port over TCP: corenet_tcp_connect_http_port
    • Do not audit getting the attributes of user home directories: userdom_dontaudit_getattr_user_home_dirs

How it works…

The naming convention that the reference policy uses is not mandated in a technical manner. Just like with coding styles, naming conventions are made so that collaboration is easier (everyone uses the same naming convention) and searching through the large set of interfaces can be directed more efficiently.

Using the proper naming convention is a matter of exercise. If uncertain, ask around in #selinux on irc://irc.freenode.net or on the reference policy mailing list.

There's more...

Take some time to look through the interface files available at /usr/share/selinux/devel/include/. Next, for the more standard permission-based interface names, there are also interface names used for templates and type assignation.

For instance, there is a template called apache_content_template. Through it, additional SELinux types and permissions (used for web applications) are created in one go. Similarly, there is an interface called apache_cgi_domain that marks a particular type as being a domain that can be invoked through a web servers' CGI support.

Besides the naming convention, the reference policy also has a style guide available at http://oss.tresys.com/projects/refpolicy/wiki/StyleGuide. Like the naming convention, this is purely a human aspect for improved collaboration—there is no consequence of violating the coding style beyond the changes that might not be accepted in the upstream repositories.

Distributing SELinux policy modules

We finish this chapter by explaining how SELinux policy modules can be distributed across multiple systems.

How to do it…

To distribute SELinux policies, complete the following steps:

  1. Take into account the different system configurations to which the SELinux policies need to be distributed:
    • If multiple systems have different SELinux policy releases to be active, then build the SELinux policy module against each of these implementations. This is heavily distribution specific. For instance, on Gentoo, this is the version of the sec-policy/selinux-base package. On Red Hat and derived distributions, this is the version of the selinux-policy package.
    • If multiple SELinux policy types are active (such as mcs, targeted, and strict) and there are both MLS-enabled as well as MLS-disabled policies, then the SELinux policy module will need to be built against both an MLS-enabled policy as well as an MLS-disabled policy. The output of sestatus will tell us whether MLS is enabled on an active policy or not:
      ~$ sestatus | grep MLS
      Policy MLS status:    enabled
      
  2. Package the resulting .pp files and distribute them to the various systems. It is a common best practice to place the .pp files inside /usr/share/selinux/mcs/ (this is for an SELinux policy store named mcs, you can adjust it where needed).
  3. On each system, make sure that the .pp file is loaded through semodule –I policyfile.pp.

How it works…

SELinux policy modules (the files ending with .pp) contain everything SELinux needs to activate the policy. By distributing these files across many systems (and loading it through the semodule command), these systems receive the wanted updates against their current SELinux policy.

Once loaded (and this only needs to happen once, as a loaded module is retained even after the system reboots), one does not really need the .pp files anymore (loaded modules are copied inside /etc/selinux). However, it is recommended that you keep the policies there so that administrators can reload policies as needed; this might help in troubleshooting the SELinux policy and system permission issues.

There are a few caveats to take into account though:

  • Changes in interfaces
  • Kernel version changes
  • MLS-enabled or MLS-disabled policies

Changes in interfaces

The .pp files contain all rules that SELinux needs to enforce the additional policy rules. This includes the (expanded) rules that were part of the interface definition files (the .if files) of the module itself as well as the interfaces referred to by the policy module.

When an update against an interface occurs, then all SELinux policy modules that might be affected by the change need to be rebuilt. As there is no simple way to know if a module needs to be rebuilt or not, it is recommended that you rebuild all policy modules every time a change has occurred to at least one interface.

Distributions will handle the rebuilding of the policies and the distribution of the rebuilt policies themselves, but for custom policy modules, we need to do this ourselves.

Kernel version changes

New kernel releases might include updates against the SELinux subsystem. When these updates provide additional features, the binary representation of a policy might be updated. This is then reflected in the binary version of the policy that the kernel supports.

Binary versions are backward compatible, so a system that supports a maximum version of 28 (SELinux's binary versions are integers that are incremented with every change) will also support loading policy modules of a lower binary version:

~# sestatus
SELinux status:      enabled
SELinuxfs mount:      /sys/fs/selinux
SELinux root directory:    /etc/selinux
Loaded policy name:    mcs
Current mode:      enforcing
Mode from config file:    enforcing
Policy MLS status:      enabled
Policy deny_unknown status:  denied
Max kernel policy version:  28

Note

When the binary version of an SELinux policy module is higher than the maximum kernel policy version, this SELinux policy module will not load on the target system. A higher version means that the policy uses features that are only available in kernels that support this version, so the administrator will need to update the kernels on those systems to support the higher version or update the SELinux policy module to not use these features so that a rebuild creates a lower-versioned binary SELinux policy module.

MLS or not

SELinux policy modules might contain sensitivity-related information. When a policy module is built, information is added to reflect whether it is built against an MLS-enabled system or not.

Therefore, if we have hosts that have diverse policy usages (some policy stores are MLS-enabled and some are MLS-disabled), then the SELinux policy module will need to be built against both and distributed separately.

Usually, this is done by providing SELinux policy modules for each particular SELinux policy type (be it mcs, strict, or targeted).

Left arrow icon Right arrow icon

Description

If you are a Linux system administrator or a Linux-based service administrator and want to fine-tune SELinux to implement a supported, mature, and proven access control system, then this book is for you. Basic experience with SELinux enabled distributions is expected.
Estimated delivery fee Deliver to Denmark

Premium delivery 7 - 10 business days

€17.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Sep 23, 2014
Length: 240 pages
Edition : 1st
Language : English
ISBN-13 : 9781783989669
Vendor :
Red Hat
Tools :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Estimated delivery fee Deliver to Denmark

Premium delivery 7 - 10 business days

€17.95
(Includes tracking information)

Product Details

Publication date : Sep 23, 2014
Length: 240 pages
Edition : 1st
Language : English
ISBN-13 : 9781783989669
Vendor :
Red Hat
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
€18.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
€189.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts
€264.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total 113.97
SELinux System Administration
€26.99
SELinux System Administration
€49.99
SELinux Cookbook
€36.99
Total 113.97 Stars icon

Table of Contents

11 Chapters
1. The SELinux Development Environment Chevron down icon Chevron up icon
2. Dealing with File Labels Chevron down icon Chevron up icon
3. Confining Web Applications Chevron down icon Chevron up icon
4. Creating a Desktop Application Policy Chevron down icon Chevron up icon
5. Creating a Server Policy Chevron down icon Chevron up icon
6. Setting Up Separate Roles Chevron down icon Chevron up icon
7. Choosing the Confinement Level Chevron down icon Chevron up icon
8. Debugging SELinux Chevron down icon Chevron up icon
9. Aligning SELinux with DAC Chevron down icon Chevron up icon
10. Handling SELinux-aware Applications Chevron down icon Chevron up icon
Index Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.3
(7 Ratings)
5 star 42.9%
4 star 42.9%
3 star 14.3%
2 star 0%
1 star 0%
Filter icon Filter
Top Reviews

Filter reviews by




Kindle Customer Mar 16, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
I have been using Fedora Linux for years now. And the first thing that I've always done is disable SELinux. Thanks to this book, I am now running Fedora "properly" with SELinux in full enforcement mode with no problems. The book explained what was going on and how to address the various problems that I had been having. Excellent!
Amazon Verified review Amazon
Steven A. Falco Jan 18, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
For a long time I avoided SELinux. It was too complicated and too poorly documented; so I just disabled it on my computers. Yet, I was always uncomfortable that I was leaving my systems open to being hacked. Along comes the "SELinux Cookbook", and I finally have enough info to use SELinux effectively. The book covers a number of topics: First, it helps set up some tools for building SELinux modules as well as examining the default configuration provided by the Operating System. It then goes on to provide techniques for securing Web servers, applications, and entire server systems. It has an excellent chapter on debugging SELinux problems that helped me determine if SELinux was actually at fault. (In some cases, other subsystems like firewalls might be at fault - you need to determine that before wasting time looking in the wrong place for a problem).One thing I particularly like about this book is that it clearly states the "why" behind the various examples. Too often, a book will say "do this" and leave me wondering "why? " That is not the case here - the author always explains how to do something , and then follows up with a justification for the given solution. In many of the examples, there is additional information describing limitations within SELinux. That is a big help; there is no point to trying to make the tools do something they cannot do.Altogether I am happy to have found this book. Any time I can learn something new, it is a good day. :-)
Amazon Verified review Amazon
ML Feb 18, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
What it is SE Linux ?, the main meaning of SE Linux is (extracted from Wikipedia) : “ is a Linux kernel security module that provides a mechanism for supporting access control security policies. SELinux is a set of kernel modifications and user-space tools that have been added to various Linux distributions. Its architecture strives to separate enforcement of security decisions from the security policy itself and streamlines the volume of software charged with security policy enforcement.”So it is clear that SE Linux is not a linux distribution but it is a kernel module that provides mechanism over access of linux security policies. Now Packt Publishing is offering a new cookbook based on SE Linux for those experienced Linux system administrators and security administrators who wants to improve their knowledge or how to add more security for their linux systems and server.However the book is written based on Gentoo Linux (which is not really important, because this book is independent of linux distritbutions). The book focus on the structure and the reusable policy inside SE Linux and you will be able to create your first set of SE Linux module policy that will be integrated with the existing SELinux policies.The main topics of the book are (this are the chapters of the book):Get knowledge SE Linux Development Environment.Working with File Labels.Connifing Web Applications.Creating Server Policies.Setting up Separate Roles.Choosing theConnifing Levels.Debugging SELinux.Alligning SELinux with DAC.Handling SELinux-Aware Applications.One important point of view, you should have experience in Linux system administration, SELinux policy development and integration that requires good knowledge of the components how to confine and protect. You should have experience with Git version control system as an end user and also basic knowledge of how SELinux works on a system.A real practical book for those who wants to have deep experience on SE Linux system and how to add more secure policies in your linux servers!.
Amazon Verified review Amazon
CNC guy Feb 09, 2015
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
This is a great place to start if you don't know anything about SELinux. I must confess that although I have used Linux since the days when you had to boot it from a floppy disk, I have very little experience with SELinux, however. SELinux has always been kind of mysterious for me. No more after reading this book.
Amazon Verified review Amazon
Matteo Jan 21, 2015
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
This book provides a simple(relative to SElinux) rulebook to create and evaluate SElinux rulesets so that you can harden or evaluate your linux server security. If you never touched SElinux before, chances are that you will find that book complex beyond reason, keep some references/documentation within reach and, more importantly, try "breaking stuff" with some test VMs so you will understand what you are typing/executing(don't do it on a production server as borked SElinux rules can and will bring it down hard :)).
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela