Security-enhanced Linux (SELinux) is a security feature in the Linux kernel. At a very high level, SELinux implements mandatory access controls (MAC), as opposed to discretionary access control (DAC) implemented in standard Linux. MAC defines how processes can interact with other system components (Files, Directories, Other Processes, Pipes, Sockets, Network Ports). Each system component is assigned a label, and then the SELinux Policy defines which labels and which actions on each label a process is able to perform. The VPP Custom SELinux Policy defines the actions VPP is allowed to perform on which labels.
The VPP Custom SELinux Policy is intended to be installed on RPM based platforms (tested on CentOS 7 and RHEL 7). Though SELinux can run on Debian platforms, it typically is not and therefore is not currently being built for Debian.
The VPP Custom SELinux Policy does not enable or disable SELinux, only allows VPP to run when SELinux is enabled. A fresh install of either Fedora, CentOS or RHEL will have SELinux enabled by default. To determine if SELinux is enabled on a given system and enable it if needed, run:
$ getenforce Permissive $ sudo setenforce 1 $ getenforce Enforcing
To make the change persistent, modify the following file to set SELINUX=enforcing
:
$ sudo vi /etc/selinux/config : # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=enforcing :
To install VPP, see the installation instructions on the VPP Wiki (https://wiki.fd.io/view/VPP/Installing_VPP_binaries_from_packages). The VPP Custom SELinux Policy is packaged in its own RPM starting in 18.04, vpp-selinux-policy-<VERSION>-<RELEASE>.rpm
. It is packaged and installed along with the other VPP RPMs.
If VPP has never been installed on a system, then starting in 18.04, the VPP Custom SELinux Policy will be installed with the other RPMs and all the system components managed by VPP will be labeled properly.
In the case where the VPP Custom Policy is being installed for the first time, either because VPP has been upgraded or packages were removed and then reinstalled, several directories and files will not not be properly labeled. The labels on these files will need to be fixed for VPP to run properly with SELinux enabled. After the VPP Custom SELinux Policy is installed, run the following commands to fix the labels. If VPP is already running, make sure to restart VPP after the labels are fixed. This change is persistent for the life of the file. Once the VPP Custom Policy is installed on the system, subsequent files created by VPP will be labeled properly. This is only to fix files created by VPP prior to the VPP Custom Policy being installed.
$ sudo restorecon -Rv /etc/vpp/ $ sudo restorecon -Rv /usr/lib/vpp_api_test_plugins/ $ sudo restorecon -Rv /usr/lib/vpp_plugins/ $ sudo restorecon -Rv /usr/share/vpp/ $ sudo restorecon -Rv /var/run/vpp/ $ sudo chcon -t vpp_tmp_t /tmp/vpp_* $ sudo chcon -t vpp_var_run_t /var/run/.vpp_*
NOTE: Because the VPP APIs allow custom filenames in certain scenarios, the above commands may not handle all files. Inspect your system and correct any files that are mislabeled. For example, to verify all VPP files in /tmp/
are labeled properly, run:
$ sudo ls -alZ /tmp/
Any files not properly labeled with vpp_tmp_t
, run:
$ sudo chcon -t vpp_tmp_t /tmp/<filename>
Documentation in the VPP Wiki (https://wiki.fd.io/view/VPP/) and doxygen generated documentation have examples with files located in certain directories. Some of the recommend file locations have been moved to satisfy SELinux. Most of the documentation has been updated, but links to older documentation still exist and there may have been instances that were missed. Use the file locations described below to allow SELinux to properly label the given files.
File locations that have changed:
The VPP Debug CLI, vppctl
, allows a sequence of CLI commands to be read from a file and executed. To avoid from having to grant VPP access to all of /tmp/
and possibly /home/
sub-directories, it is recommended that any VPP Debug CLI script files be placed in a common directory such as /usr/share/vpp/
.
For example:
$ cat /usr/share/vpp/scripts/gigup.txt set interface state GigabitEthernet0/8/0 up set interface state GigabitEthernet0/9/0 up
To execute:
$ vppctl exec /usr/share/vpp/scripts/gigup.txt
Or
$ vppctl _______ _ _ _____ ___ __/ __/ _ \ (_)__ | | / / _ \/ _ \ _/ _// // / / / _ \ | |/ / ___/ ___/ /_/ /____(_)_/\___/ |___/_/ /_/ vpp# exec /usr/share/vpp/scripts/gigup.txt vpp# quit
If the file is not labeled properly, you will see something similar to:
$ vppctl exec /home/<user>/dev/vpp/scripts/vppctl/gigup.txt exec: failed to open `/home/<user>/dev/vpp/scripts/vppctl/gigup.txt': Permission denied $ ls -alZ drwxrwxr-x. <user> <user> unconfined_u:object_r:user_home_t:s0 . drwxrwxr-x. <user> <user> unconfined_u:object_r:user_home_t:s0 .. -rw-r--r--. <user> <user> unconfined_u:object_r:user_home_t:s0 gigup.txt
Some of the original documentation showed script files being executed out of /tmp/
. Convenience also may lead to script files being placed in /home/<user>/
subdirectories. If a file is generated by the VPP process in /tmp/
, for example a trace file or pcap file, it will get properly labeled with the SELinux label vpp_tmp_t
. When a file is created, unless a rule is in place for the process that created it, the file will inherit the SELinux label of the parent directory. So if a user creates a file themselves in /tmp/
, it will get the SELinux label tmp_t
, which VPP does not have permission to access. Therefore it is recommended that script files are located as described above.
vHost sockets are created from VPP perspective in either Server or Client mode. In Server mode, the socket name is provided to VPP and VPP creates the socket. In Client mode, the socket name is provided to VPP and the hypervisor creates the socket. In order for VPP and hypervisor to share the socket resource with SELinux enabled, a rule in the VPP Custom SELinux Policy has been added. This rules allows processes with the svirt_t
label (the hypervisor) to access sockets with the vpp_var_run_t
label. As such, when SELinux is enabled, vHost sockets should be created in the directory /var/run/vpp/
.
Some of the original documentation showed vHost sockets being created in the directory /tmp/
. To work properly with SELinux enabled, vHost sockets should be created as described above.
The VPP log file location is set by updating the /etc/vpp/startup.conf
file:
vi /etc/vpp/startup.conf unix { : log /var/log/vpp/vpp.log : }
By moving the log file to /var/log/vpp/
, it will get the label vpp_log_t
, which indicates that the files are log files so they benefit from the associated rules (for example granting rights to logrotate so that it can manipulate them).
The default startup.conf
file creates the VPP log file in /tmp/vpp.log
. By leaving the log file in /tmp/
, it will get the label vpp_tmp_t
. Moving it to /var/log/vpp/
, it will get the label vpp_log_t
.
VPP installs multiple files on the system. Some files have fixed directory and file names:
Others files have default directory and file names but the default can be overwritten:
/usr/lib/systemd/system/vpp.service
file by changing the -c option on the VPP command line:ExecStart=/usr/bin/vpp -c /etc/vpp/startup.conf
/etc/vpp/startup.conf
file by changing the cli-listen setting:unix { : cli-listen /run/vpp/cli.sock : }
/etc/vpp/startup.conf
file by changing the log setting:unix { : log /var/log/vpp/vpp.log : }
If the directory of any VPP installed files is changed from the default, ensure that the proper SELiunx label is applied. The SELinux label can be determined by passing the -Z option to many common Linux commands:
ls -alZ /run/vpp/ drwxr-xr-x. root vpp system_u:object_r:vpp_var_run_t:s0 . drwxr-xr-x. root root system_u:object_r:var_run_t:s0 .. srwxrwxr-x. root vpp system_u:object_r:vpp_var_run_t:s0 cli.sock
The following SELinux types are created by the VPP Custom SELinux Policy:
vpp_t
- Applied to:
vpp_config_rw_t
- Applied to:
/etc/vpp/*
vpp_tmp_t
- Applied to:
/tmp/*
vpp_exec_t
- Applied to:
/usr/bin/*
vpp_lib_t
- Applied to:
/usr/lib/vpp_api_test_plugins/*
/usr/lib/vpp_plugins/*
vpp_unit_file_t
- Applied to:
/usr/lib/systemd/system/vpp.*
vpp_log_t
- Applied to:
/var/log/vpp/*
vpp_var_run_t
- Applied to:
/var/run/vpp/*