diff options
author | Billy McFall <bmcfall@redhat.com> | 2018-01-15 17:54:52 -0500 |
---|---|---|
committer | Damjan Marion <dmarion.lists@gmail.com> | 2018-01-30 13:26:20 +0000 |
commit | 28cf3b7da279c0755f6dc345c0973d1e3017e9ca (patch) | |
tree | ff82873f655f6b52e1673df75f3a12b19c106fde | |
parent | c0379aec241c78fe07074fa7e63a5009a4e7944a (diff) |
VPP-899: Run VPP under SELinux
Add an SELinux profile such that VPP can run under SELinux on RPM based
platforms. The SELinux Policy is currently only implemented for RPM
packages, specifically, Fedora, CentOS and RHEL. Doxygen User
Documentation has been included (selinux_doc.md). Once some discussion
on file locations has completed (see vpp-devlist), updates to the Debug
CLI documentation will also need to be updated.
Additional changes:
Patch Set 2:
- Rework selinux_doc.md such that each line is only 80 characters
instead of each sentence on a line. Made additonal minor chnages
to the text.
- Update vHost Debug CLI documentation to reflex new socket location.
Cleaned up some text from when I originally wrote it, to better
reflex proper use.
- Update exec Debug CLI documentation to be more inline with suggested
helptext, added text regarding recommended script file location.
- For Debian builds, create the /var/log/vpp/ directory. I don't use
Debian very much, so please pay extra attention to
build-data/platforms.mk and build-root/deb/debian/.gitignore.
- Per discussion on VPP call, changed the default log location to
/var/log/vpp/vpp.log.
- Changed the socket location for vHost in AutoConfig to
/var/run/vpp/.
Patch Set 3:
- Update selinux_doc.md based on comments.
Change-Id: I400520dc33f1ca51012d09ef8fe5a7b7b96c631e
Signed-off-by: Billy McFall <bmcfall@redhat.com>
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | build-data/platforms.mk | 4 | ||||
-rw-r--r-- | build-root/deb/debian/.gitignore | 1 | ||||
-rw-r--r-- | doxygen/siphon_templates/markdown/syscfg/index_header.md | 2 | ||||
-rw-r--r-- | doxygen/user_doc.md | 1 | ||||
-rw-r--r-- | extras/rpm/vpp.spec | 77 | ||||
-rw-r--r-- | extras/selinux/selinux_doc.md | 294 | ||||
-rw-r--r-- | extras/selinux/vpp-custom.fc | 22 | ||||
-rw-r--r-- | extras/selinux/vpp-custom.if | 2 | ||||
-rw-r--r-- | extras/selinux/vpp-custom.te | 139 | ||||
-rw-r--r-- | extras/vpp_config/data/startup.conf.template | 2 | ||||
-rw-r--r-- | extras/vpp_config/vpplib/AutoConfig.py | 4 | ||||
-rw-r--r-- | src/vlib/unix/cli.c | 24 | ||||
-rw-r--r-- | src/vnet/devices/virtio/vhost-user.c | 30 | ||||
-rw-r--r-- | src/vpp/conf/startup.conf | 2 |
15 files changed, 582 insertions, 23 deletions
@@ -85,6 +85,7 @@ RPM_DEPENDS += numactl-devel RPM_DEPENDS += check check-devel RPM_DEPENDS += boost boost-devel RPM_DEPENDS += subunit subunit-devel +RPM_DEPENDS += selinux-policy selinux-policy-devel ifeq ($(OS_ID)-$(OS_VERSION_ID),fedora-25) RPM_DEPENDS += openssl-devel diff --git a/build-data/platforms.mk b/build-data/platforms.mk index 45bd3a1b8a1..d555f2ab3eb 100644 --- a/build-data/platforms.mk +++ b/build-data/platforms.mk @@ -75,6 +75,10 @@ install-deb: $(patsubst %,%-find-source,$(ROOT_PACKAGES)) echo ../../src/scripts/vppctl-cmd-list /usr/share/vpp \ >> deb/debian/vpp.install ; \ \ + : add log directory ; \ + echo /var/log/vpp/ \ + >> deb/debian/vpp.dirs ; \ + \ : dev package needs a couple of additions ; \ echo ../$(INSTALL_PREFIX)$(ARCH)/vpp/bin/vppapigen /usr/bin \ >> deb/debian/vpp-dev.install ; \ diff --git a/build-root/deb/debian/.gitignore b/build-root/deb/debian/.gitignore index 7b1028d6ad4..489f8eb2c33 100644 --- a/build-root/deb/debian/.gitignore +++ b/build-root/deb/debian/.gitignore @@ -3,6 +3,7 @@ files *debhelper* *.substvars *.install +*.dirs vpp/ vpp-dev/ vpp-lib/ diff --git a/doxygen/siphon_templates/markdown/syscfg/index_header.md b/doxygen/siphon_templates/markdown/syscfg/index_header.md index 5d338a0472b..f5a9816b99c 100644 --- a/doxygen/siphon_templates/markdown/syscfg/index_header.md +++ b/doxygen/siphon_templates/markdown/syscfg/index_header.md @@ -87,7 +87,7 @@ to make the content easier to read. For example: ``` unix { nodaemon - log /tmp/vpp.log + log /var/log/vpp/vpp.log full-coredump cli-listen localhost:5002 } diff --git a/doxygen/user_doc.md b/doxygen/user_doc.md index 7ac81e109ce..4d6b22f6bff 100644 --- a/doxygen/user_doc.md +++ b/doxygen/user_doc.md @@ -13,6 +13,7 @@ Several modules provide operational, dataplane-user focused documentation. - @subpage dpdk_crypto_ipsec_doc - @subpage flowprobe_plugin_doc - @subpage qos_doc +- @subpage selinux_doc - @subpage span_doc - @subpage srv6_doc - @subpage srmpls_doc diff --git a/extras/rpm/vpp.spec b/extras/rpm/vpp.spec index 532b9a219d4..d3bc517c5b4 100644 --- a/extras/rpm/vpp.spec +++ b/extras/rpm/vpp.spec @@ -24,12 +24,30 @@ %{?systemd_requires} + +# SELinux Related definitions +%global selinuxtype targeted +%global moduletype services +%global modulenames vpp-custom + +# Usage: _format var format +# Expand 'modulenames' into various formats as needed +# Format must contain '$x' somewhere to do anything useful +%global _format() export %1=""; for x in %{modulenames}; do %1+=%2; %1+=" "; done; + +# Relabel files +%global relabel_files() \ # ADD files in *.fc file + +# Version of distribution SELinux policy package +%global selinux_policyver 3.13.1-128.6.fc22 + + Name: vpp Summary: Vector Packet Processing License: ASL 2.0 Version: %{_version} Release: %{_release} -Requires: vpp-lib = %{_version}-%{_release}, net-tools, pciutils, python +Requires: vpp-lib = %{_version}-%{_release}, vpp-selinux-policy = %{_version}-%{_release}, net-tools, pciutils, python BuildRequires: systemd, chrpath BuildRequires: check, check-devel BuildRequires: subunit, subunit-devel @@ -51,6 +69,7 @@ BuildRequires: apr-devel BuildRequires: numactl-devel BuildRequires: autoconf automake libtool byacc bison flex BuildRequires: boost boost-devel +BuildRequires: selinux-policy selinux-policy-devel Source: %{name}-%{_version}-%{_release}.tar.xz # Source: vpp-latest.tar.xz @@ -64,6 +83,7 @@ vpp_json_test - vector packet engine JSON test tool %package lib Summary: VPP libraries Group: System Environment/Libraries +Requires: vpp-selinux-policy = %{_version}-%{_release} %description lib This package contains the VPP shared libraries, including: @@ -119,6 +139,14 @@ Requires: vpp = %{_version}-%{_release}, vpp-lib = %{_version}-%{_release}, pyth %description api-python This package contains the python bindings for the vpp api +%package selinux-policy +Summary: VPP Security-Enhanced Linux (SELinux) policy +Group: System Environment/Base +Requires(post): selinux-policy-base >= %{selinux_policyver}, selinux-policy-targeted >= %{selinux_policyver}, policycoreutils, policycoreutils-python libselinux-utils + +%description selinux-policy +This package contains a tailored VPP SELinux policy + %prep # Unpack into dir with longer name as work around of debugedit bug in in rpm-build 4.13 rm -rf %{name}-%{_version} @@ -142,6 +170,7 @@ cd '%{_tmp_build_dir}' make -C build-root PLATFORM=vpp AESNI=n TAG=%{_vpp_tag} install-packages %endif cd %{_mu_build_dir}/../src/vpp-api/python && %py2_build +cd %{_mu_build_dir}/../extras/selinux && make -f %{_datadir}/selinux/devel/Makefile %install # @@ -207,6 +236,19 @@ done # Python bindings cd %{_mu_build_dir}/../src/vpp-api/python && %py2_install +# SELinux Policy +# Install SELinux interfaces +%_format INTERFACES %{_mu_build_dir}/../extras/selinux/$x.if +install -d %{buildroot}%{_datadir}/selinux/devel/include/%{moduletype} +install -p -m 644 $INTERFACES \ + %{buildroot}%{_datadir}/selinux/devel/include/%{moduletype} + +# Install policy modules +%_format MODULES %{_mu_build_dir}/../extras/selinux/$x.pp +install -d %{buildroot}%{_datadir}/selinux/packages +install -m 0644 $MODULES \ + %{buildroot}%{_datadir}/selinux/packages + # # devel # @@ -237,6 +279,10 @@ do %{buildroot}/usr/share/doc/vpp/examples/sample-plugin/$file ) done +# vppctl sockfile directory +mkdir -p -m755 %{buildroot}%{_localstatedir}/run/vpp +# vpp.log directory +mkdir -p -m755 %{buildroot}%{_localstatedir}/log/vpp # # vpp-plugins @@ -274,6 +320,15 @@ fi %preun %systemd_preun vpp.service +%post selinux-policy +%_format MODULES %{_datadir}/selinux/packages/$x.pp +%{_sbindir}/semodule -n -X 400 -s %{selinuxtype} -i $MODULES +if %{_sbindir}/selinuxenabled ; then + %{_sbindir}/load_policy + %relabel_files +fi + + %postun %systemd_postun if [ $1 -eq 0 ] ; then @@ -299,6 +354,15 @@ else echo "Upgrading package, dont' unbind interfaces" fi +%postun selinux-policy +if [ $1 -eq 0 ]; then + %{_sbindir}/semodule -n -r %{modulenames} + if %{_sbindir}/selinuxenabled ; then + %{_sbindir}/load_policy + %relabel_files + fi +fi + %files %defattr(-,bin,bin) %{_unitdir}/vpp.service @@ -309,6 +373,12 @@ fi %config(noreplace) /etc/vpp/startup.conf /usr/share/vpp/api/* +%defattr(-,root,vpp) +%{_localstatedir}/run/vpp* + +%defattr(-,root,root) +%{_localstatedir}/log/vpp* + %files lib %defattr(-,bin,bin) %exclude %{_libdir}/vpp_plugins @@ -330,6 +400,11 @@ fi %defattr(644,root,root) %{python2_sitelib}/vpp_papi* +%files selinux-policy +%defattr(-,root,root,0755) +%attr(0644,root,root) %{_datadir}/selinux/packages/*.pp +%attr(0644,root,root) %{_datadir}/selinux/devel/include/%{moduletype}/*.if + %files devel %defattr(-,bin,bin) /usr/bin/vppapigen diff --git a/extras/selinux/selinux_doc.md b/extras/selinux/selinux_doc.md new file mode 100644 index 00000000000..e71bd658286 --- /dev/null +++ b/extras/selinux/selinux_doc.md @@ -0,0 +1,294 @@ +# SELinux - VPP Custom SELinux Policy {#selinux_doc} + +## Overview + +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 + : +``` + +## Installation + +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. + +### Fresh Install of VPP + +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. + +### Fix SELinux Labels for VPP +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> +``` + +## VPP Files + +### Recommended Default File Directories + +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: +* VPP Debug CLI Script Files +* vHost Sockets +* VPP Log Files + +#### VPP Debug CLI Script Files + +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 +``` + +##### Original Documentation + +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 + +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/`. + +##### Original Documentation + +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. + +#### VPP Log Files + +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). + +##### Original Documentation + +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`. + +### Use of Non-default File Directories + +VPP installs multiple files on the system. +Some files have fixed directory and file names: +- /etc/bash_completion.d/vppctl_completion +- /etc/sysctl.d/80-vpp.conf +- /usr/lib/systemd/system/vpp.service + +Others files have default directory and file names but the default can be +overwritten: +- /etc/vpp/startup.conf + - Can be changed via the `/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 +``` + +- /run/vpp/cli.sock + - Can be changed via the `/etc/vpp/startup.conf` file by changing the + cli-listen setting: + +``` +unix { +: + cli-listen /run/vpp/cli.sock +: +} +``` + + +- /var/log/vpp/vpp.log + - Can be changed via the `/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 +``` + +### VPP SELinux Types ### + +The following SELinux types are created by the VPP Custom SELinux Policy: +- `vpp_t` - Applied to: + - VPP process and spawned threads. + +- `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/*` diff --git a/extras/selinux/vpp-custom.fc b/extras/selinux/vpp-custom.fc new file mode 100644 index 00000000000..5b9d277ebea --- /dev/null +++ b/extras/selinux/vpp-custom.fc @@ -0,0 +1,22 @@ +/etc/vpp(/.*)? gen_context(system_u:object_r:vpp_config_rw_t,s0) + +/usr/bin/elftool -- gen_context(system_u:object_r:vpp_exec_t,s0) +/usr/bin/jvpp_gen.py -- gen_context(system_u:object_r:vpp_exec_t,s0) +/usr/bin/svmdbtool -- gen_context(system_u:object_r:vpp_exec_t,s0) +/usr/bin/svmtool -- gen_context(system_u:object_r:vpp_exec_t,s0) +/usr/bin/vpp -- gen_context(system_u:object_r:vpp_exec_t,s0) +/usr/bin/vppapigen -- gen_context(system_u:object_r:vpp_exec_t,s0) +/usr/bin/vpp_api_test -- gen_context(system_u:object_r:vpp_exec_t,s0) +/usr/bin/vppctl -- gen_context(system_u:object_r:vpp_exec_t,s0) +/usr/bin/vpp_get_metrics -- gen_context(system_u:object_r:vpp_exec_t,s0) +/usr/bin/vpp_json_test -- gen_context(system_u:object_r:vpp_exec_t,s0) +/usr/bin/vpp_restart -- gen_context(system_u:object_r:vpp_exec_t,s0) + +/usr/lib/systemd/system/vpp.* -- gen_context(system_u:object_r:vpp_unit_file_t,s0) + +/usr/lib/vpp_plugins(/.*)? gen_context(system_u:object_r:vpp_lib_t,s0) +/usr/lib/vpp_api_test_plugins(/.*)? gen_context(system_u:object_r:vpp_lib_t,s0) + +/var/log/vpp(/.*)? gen_context(system_u:object_r:vpp_log_t,s0) + +/var/run/vpp(/.*)? gen_context(system_u:object_r:vpp_var_run_t,s0) diff --git a/extras/selinux/vpp-custom.if b/extras/selinux/vpp-custom.if new file mode 100644 index 00000000000..573da143cbb --- /dev/null +++ b/extras/selinux/vpp-custom.if @@ -0,0 +1,2 @@ +## + VPP service.
\ No newline at end of file diff --git a/extras/selinux/vpp-custom.te b/extras/selinux/vpp-custom.te new file mode 100644 index 00000000000..e0a1f64d018 --- /dev/null +++ b/extras/selinux/vpp-custom.te @@ -0,0 +1,139 @@ +policy_module(vpp-custom,1.0) + +######################################## +# +# Declarations +# + +gen_require(` + type hugetlbfs_t; + type svirt_t; + type svirt_image_t; + type systemd_sysctl_t; + class capability sys_admin; +') + +type vpp_t; +type vpp_exec_t; +init_daemon_domain(vpp_t, vpp_exec_t) + +type vpp_config_rw_t; +files_config_file(vpp_config_rw_t) + +type vpp_lib_t; # if there is vpp_var_lib_t, we don't need vpp_lib_t +files_type(vpp_lib_t) + +type vpp_log_t; +logging_log_file(vpp_log_t) + +type vpp_var_run_t; +files_type(vpp_var_run_t) + +type vpp_unit_file_t; +systemd_unit_file(vpp_unit_file_t) + +type vpp_tmpfs_t; +files_tmpfs_file(vpp_tmpfs_t) + +type vpp_tmp_t; +files_tmp_file(vpp_tmp_t) + +######################################## +# +# vpp local policy +# + +allow vpp_t self:capability { dac_override ipc_lock setgid sys_rawio net_raw sys_admin }; # too benefolent +dontaudit vpp_t self:capability2 block_suspend; +allow vpp_t self:process { execmem execstack setsched signal }; # too benefolent +allow vpp_t self:packet_socket { bind create setopt ioctl }; +allow vpp_t self:tun_socket { create relabelto relabelfrom }; +allow vpp_t self:udp_socket { create ioctl }; +allow vpp_t self:unix_dgram_socket { connect create ioctl }; +allow vpp_t self:unix_stream_socket { create_stream_socket_perms connectto }; + +manage_dirs_pattern(vpp_t, vpp_lib_t, vpp_lib_t) +manage_files_pattern(vpp_t, vpp_lib_t, vpp_lib_t) +allow vpp_t vpp_lib_t:file execute; +files_var_lib_filetrans(vpp_t, vpp_lib_t, {file dir}) + +manage_dirs_pattern(vpp_t, vpp_log_t, vpp_log_t) +manage_files_pattern(vpp_t, vpp_log_t, vpp_log_t) +logging_log_filetrans(vpp_t, vpp_log_t, {file dir}) + +manage_dirs_pattern(vpp_t, vpp_var_run_t, vpp_var_run_t) +manage_files_pattern(vpp_t, vpp_var_run_t, vpp_var_run_t) +manage_sock_files_pattern(vpp_t, vpp_var_run_t, vpp_var_run_t) +allow vpp_t vpp_var_run_t:dir mounton; +files_pid_filetrans(vpp_t, vpp_var_run_t, { dir sock_file file }) + +manage_dirs_pattern(vpp_t, vpp_tmp_t, vpp_tmp_t) +manage_files_pattern(vpp_t, vpp_tmp_t, vpp_tmp_t) +manage_sock_files_pattern(vpp_t, vpp_tmp_t, vpp_tmp_t) +allow vpp_t vpp_tmp_t:dir mounton; +files_tmp_filetrans(vpp_t, vpp_tmp_t, { dir sock_file file }) + +manage_dirs_pattern(vpp_t, vpp_tmpfs_t, vpp_tmpfs_t) +manage_files_pattern(vpp_t, vpp_tmpfs_t, vpp_tmpfs_t) +fs_tmpfs_filetrans(vpp_t, vpp_tmpfs_t, { dir file }) + +read_files_pattern(vpp_t, vpp_config_rw_t, vpp_config_rw_t) + +kernel_read_system_state(vpp_t) +kernel_read_network_state(vpp_t) +kernel_dgram_send(vpp_t) +kernel_request_load_module(vpp_t) + +auth_read_passwd(vpp_t) + +corenet_rw_tun_tap_dev(vpp_t) + +dev_rw_userio_dev(vpp_t) +dev_rw_sysfs(vpp_t) +dev_read_cpuid(vpp_t) +dev_rw_vfio_dev(vpp_t) + +domain_obj_id_change_exemption(vpp_t) + +fs_manage_hugetlbfs_dirs(vpp_t) +fs_manage_hugetlbfs_files(vpp_t) +allow vpp_t hugetlbfs_t:filesystem { getattr mount unmount }; +fs_getattr_tmpfs(vpp_t) + +logging_send_syslog_msg(vpp_t) + +miscfiles_read_generic_certs(vpp_t) + +userdom_list_user_home_content(vpp_t) + +optional_policy(` + virt_stream_connect_svirt(vpp_t) +') + +optional_policy(` + unconfined_attach_tun_iface(vpp_t) +') + + +######################################## +# +# svirt local policy for vpp +# + +allow svirt_t vpp_t:unix_stream_socket connectto; + +manage_dirs_pattern(svirt_t, vpp_var_run_t, vpp_var_run_t) +manage_files_pattern(svirt_t, vpp_var_run_t, vpp_var_run_t) +manage_sock_files_pattern(svirt_t, vpp_var_run_t, vpp_var_run_t) + +allow vpp_t svirt_image_t:file { read write }; + + +######################################## +# +# systemd_sysctl_t local policy for vpp +# + +read_files_pattern(systemd_sysctl_t, vpp_config_rw_t, vpp_config_rw_t) + + diff --git a/extras/vpp_config/data/startup.conf.template b/extras/vpp_config/data/startup.conf.template index 91b92c62aea..912bbc4b085 100644 --- a/extras/vpp_config/data/startup.conf.template +++ b/extras/vpp_config/data/startup.conf.template @@ -1,7 +1,7 @@ unix {{ {unix} - log /tmp/vpp.log + log /var/log/vpp/vpp.log full-coredump cli-listen /run/vpp/cli.sock }} diff --git a/extras/vpp_config/vpplib/AutoConfig.py b/extras/vpp_config/vpplib/AutoConfig.py index 36b6833e7a9..26603e8e380 100644 --- a/extras/vpp_config/vpplib/AutoConfig.py +++ b/extras/vpp_config/vpplib/AutoConfig.py @@ -1637,7 +1637,7 @@ class AutoConfig(object): question = "Would you like connect this interface {} to the VM [Y/n]? ".format(name) answer = self._ask_user_yn(question, 'y') if answer == 'y': - sockfilename = '/tmp/sock{}.sock'.format(inum) + sockfilename = '/var/run/vpp/sock{}.sock'.format(inum) if os.path.exists(sockfilename): os.remove(sockfilename) cmd = 'vppctl create vhost-user socket {} server'.format(sockfilename) @@ -1679,7 +1679,7 @@ class AutoConfig(object): for intf in ints_with_vints: vhoststr = 'comment { The following command creates the socket }\n' vhoststr += 'comment { and returns a virtual interface }\n' - vhoststr += 'comment {{ create vhost-user socket /tmp/sock{}.sock server }}\n'. \ + vhoststr += 'comment {{ create vhost-user socket /var/run/vpp/sock{}.sock server }}\n'. \ format(intf['bridge']) setintdnstr = 'set interface state {} down\n'.format(intf['name']) diff --git a/src/vlib/unix/cli.c b/src/vlib/unix/cli.c index 9f5862a036f..0cf4ed38fe3 100644 --- a/src/vlib/unix/cli.c +++ b/src/vlib/unix/cli.c @@ -3011,16 +3011,32 @@ done: } /*? - * Executes a sequence of CLI commands which are read from a file. - * - * If a command is unrecognised or otherwise invalid then the usual CLI + * Executes a sequence of CLI commands which are read from a file. If + * a command is unrecognised or otherwise invalid then the usual CLI * feedback will be generated, however execution of subsequent commands * from the file will continue. + * + * The VPP code is indifferent to the file location. However, if SELinux + * is enabled, then the file needs to have an SELinux label the VPP + * process is allowed to access. For example, if a file is created in + * '<em>/usr/share/vpp/</em>', it will be allowed. However, files manually + * created in '/tmp/' or '/home/<user>/' will not be accessible by the VPP + * process when SELinux is enabled. + * + * @cliexpar + * Sample file: + * @clistart + * <b><em>$ cat /usr/share/vpp/scripts/gigup.txt</em></b> + * set interface state GigabitEthernet0/8/0 up + * set interface state GigabitEthernet0/9/0 up + * @cliend + * Example of how to execute a set of CLI commands from a file: + * @cliexcmd{exec /usr/share/vpp/scripts/gigup.txt} ?*/ /* *INDENT-OFF* */ VLIB_CLI_COMMAND (cli_exec, static) = { .path = "exec", - .short_help = "Execute commands from file", + .short_help = "exec <filename>", .function = unix_cli_exec, .is_mp_safe = 1, }; diff --git a/src/vnet/devices/virtio/vhost-user.c b/src/vnet/devices/virtio/vhost-user.c index c7820406538..874a97dbd77 100644 --- a/src/vnet/devices/virtio/vhost-user.c +++ b/src/vnet/devices/virtio/vhost-user.c @@ -3355,16 +3355,23 @@ done: * * There are several parameters associated with a vHost interface: * - * - <b>socket <socket-filename></b> - Name of the linux socket used by QEMU/VM and - * VPP to manage the vHost interface. If socket does not already exist, VPP will - * create the socket. + * - <b>socket <socket-filename></b> - Name of the linux socket used by hypervisor + * and VPP to manage the vHost interface. If in '<em>server</em>' mode, VPP will + * create the socket if it does not already exist. If in '<em>client</em>' mode, + * hypervisor will create the socket if it does not already exist. The VPP code + * is indifferent to the file location. However, if SELinux is enabled, then the + * socket needs to be created in '<em>/var/run/vpp/</em>'. * - * - <b>server</b> - Optional flag to indicate that VPP should be the server for the - * linux socket. If not provided, VPP will be the client. + * - <b>server</b> - Optional flag to indicate that VPP should be the server for + * the linux socket. If not provided, VPP will be the client. In '<em>server</em>' + * mode, the VM can be reset without tearing down the vHost Interface. In + * '<em>client</em>' mode, VPP can be reset without bringing down the VM and + * tearing down the vHost Interface. * * - <b>feature-mask <hex></b> - Optional virtio/vhost feature set negotiated at - * startup. By default, all supported features will be advertised. Otherwise, - * provide the set of features desired. + * startup. <b>This is intended for degugging only.</b> It is recommended that this + * parameter not be used except by experienced users. By default, all supported + * features will be advertised. Otherwise, provide the set of features desired. * - 0x000008000 (15) - VIRTIO_NET_F_MRG_RXBUF * - 0x000020000 (17) - VIRTIO_NET_F_CTRL_VQ * - 0x000200000 (21) - VIRTIO_NET_F_GUEST_ANNOUNCE @@ -3382,17 +3389,14 @@ done: * in the name to be specified. If instance already exists, name will be used * anyway and multiple instances will have the same name. Use with caution. * - * - <b>mode [interrupt | polling]</b> - Optional parameter specifying - * the input thread polling policy. - * * @cliexpar * Example of how to create a vhost interface with VPP as the client and all features enabled: - * @cliexstart{create vhost-user socket /tmp/vhost1.sock} + * @cliexstart{create vhost-user socket /var/run/vpp/vhost1.sock} * VirtualEthernet0/0/0 * @cliexend * Example of how to create a vhost interface with VPP as the server and with just * multiple queues enabled: - * @cliexstart{create vhost-user socket /tmp/vhost2.sock server feature-mask 0x40400000} + * @cliexstart{create vhost-user socket /var/run/vpp/vhost2.sock server feature-mask 0x40400000} * VirtualEthernet0/0/1 * @cliexend * Once the vHost interface is created, enable the interface using: @@ -3451,7 +3455,7 @@ VLIB_CLI_COMMAND (vhost_user_delete_command, static) = { * VHOST_USER_PROTOCOL_F_MQ (0) * VHOST_USER_PROTOCOL_F_LOG_SHMFD (1) * - * socket filename /tmp/vhost1.sock type client errno "Success" + * socket filename /var/run/vpp/vhost1.sock type client errno "Success" * * rx placement: * thread 1 on vring 1 diff --git a/src/vpp/conf/startup.conf b/src/vpp/conf/startup.conf index b18c6743869..2a12ef9ec2a 100644 --- a/src/vpp/conf/startup.conf +++ b/src/vpp/conf/startup.conf @@ -1,7 +1,7 @@ unix { nodaemon - log /tmp/vpp.log + log /var/log/vpp/vpp.log full-coredump cli-listen /run/vpp/cli.sock gid vpp |