blob: a902ec675ce8e9da9ddef00d1caff61d467771c1 [file] [log] [blame]
Nathan Skrzypczaka2c95092021-10-08 14:05:58 +02001.. _selinux_doc:
2
3SELinux - VPP Custom SELinux Policy
4===================================
5
6Overview
7--------
8
9Security-enhanced Linux (SELinux) is a security feature in the Linux
10kernel. At a very high level, SELinux implements mandatory access
11controls (MAC), as opposed to discretionary access control (DAC)
12implemented in standard Linux. MAC defines how processes can interact
13with other system components (Files, Directories, Other Processes,
14Pipes, Sockets, Network Ports). Each system component is assigned a
15label, and then the SELinux Policy defines which labels and which
16actions on each label a process is able to perform. The VPP Custom
17SELinux Policy defines the actions VPP is allowed to perform on which
18labels.
19
20The VPP Custom SELinux Policy is intended to be installed on RPM based
21platforms (tested on CentOS 7 and RHEL 7). Though SELinux can run on
22Debian platforms, it typically is not and therefore is not currently
23being built for Debian.
24
25The VPP Custom SELinux Policy does not enable or disable SELinux, only
26allows VPP to run when SELinux is enabled. A fresh install of either
27Fedora, CentOS or RHEL will have SELinux enabled by default. To
28determine if SELinux is enabled on a given system and enable it if
29needed, run:
30
31::
32
33 $ getenforce
34 Permissive
35
36 $ sudo setenforce 1
37
38 $ getenforce
39 Enforcing
40
41To make the change persistent, modify the following file to set
42``SELINUX=enforcing``:
43
44::
45
46 $ sudo vi /etc/selinux/config
47 :
48 # This file controls the state of SELinux on the system.
49 # SELINUX= can take one of these three values:
50 # enforcing - SELinux security policy is enforced.
51 # permissive - SELinux prints warnings instead of enforcing.
52 # disabled - No SELinux policy is loaded.
53 SELINUX=enforcing
54 :
55
56Installation
57------------
58
59To install VPP, see the installation instructions on the VPP Wiki
60(https://wiki.fd.io/view/VPP/Installing_VPP_binaries_from_packages). The
61VPP Custom SELinux Policy is packaged in its own RPM starting in 18.04,
62``vpp-selinux-policy-<VERSION>-<RELEASE>.rpm``. It is packaged and
63installed along with the other VPP RPMs.
64
65Fresh Install of VPP
66~~~~~~~~~~~~~~~~~~~~
67
68If VPP has never been installed on a system, then starting in 18.04, the
69VPP Custom SELinux Policy will be installed with the other RPMs and all
70the system components managed by VPP will be labeled properly.
71
72Fix SELinux Labels for VPP
73~~~~~~~~~~~~~~~~~~~~~~~~~~
74
75In the case where the VPP Custom Policy is being installed for the first
76time, either because VPP has been upgraded or packages were removed and
77then reinstalled, several directories and files will not not be properly
78labeled. The labels on these files will need to be fixed for VPP to run
79properly with SELinux enabled. After the VPP Custom SELinux Policy is
80installed, run the following commands to fix the labels. If VPP is
81already running, make sure to restart VPP after the labels are fixed.
82This change is persistent for the life of the file. Once the VPP Custom
83Policy is installed on the system, subsequent files created by VPP will
84be labeled properly. This is only to fix files created by VPP prior to
85the VPP Custom Policy being installed.
86
87::
88
89 $ sudo restorecon -Rv /etc/vpp/
90 $ sudo restorecon -Rv /usr/lib/vpp_api_test_plugins/
91 $ sudo restorecon -Rv /usr/lib/vpp_plugins/
92 $ sudo restorecon -Rv /usr/share/vpp/
93 $ sudo restorecon -Rv /var/run/vpp/
94
95 $ sudo chcon -t vpp_tmp_t /tmp/vpp_*
96 $ sudo chcon -t vpp_var_run_t /var/run/.vpp_*
97
98**NOTE:** Because the VPP APIs allow custom filenames in certain
99scenarios, the above commands may not handle all files. Inspect your
100system and correct any files that are mislabeled. For example, to verify
101all VPP files in ``/tmp/`` are labeled properly, run:
102
103::
104
105 $ sudo ls -alZ /tmp/
106
107Any files not properly labeled with ``vpp_tmp_t``, run:
108
109::
110
111 $ sudo chcon -t vpp_tmp_t /tmp/<filename>
112
113VPP Files
114---------
115
116Recommended Default File Directories
117~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
118
119Documentation in the VPP Wiki (https://wiki.fd.io/view/VPP/) and doxygen
120generated documentation have examples with files located in certain
121directories. Some of the recommend file locations have been moved to
122satisfy SELinux. Most of the documentation has been updated, but links
123to older documentation still exist and there may have been instances
124that were missed. Use the file locations described below to allow
125SELinux to properly label the given files.
126
127File locations that have changed: \* VPP Debug CLI Script Files \* vHost
128Sockets \* VPP Log Files
129
130VPP Debug CLI Script Files
131^^^^^^^^^^^^^^^^^^^^^^^^^^
132
133The VPP Debug CLI, ``vppctl``, allows a sequence of CLI commands to be
134read from a file and executed. To avoid from having to grant VPP access
135to all of ``/tmp/`` and possibly ``/home/`` sub-directories, it is
136recommended that any VPP Debug CLI script files be placed in a common
137directory such as ``/usr/share/vpp/``.
138
139For example:
140
141::
142
143 $ cat /usr/share/vpp/scripts/gigup.txt
144 set interface state GigabitEthernet0/8/0 up
145 set interface state GigabitEthernet0/9/0 up
146
147To execute:
148
149::
150
151 $ vppctl exec /usr/share/vpp/scripts/gigup.txt
152
153Or
154
155::
156
157 $ vppctl
158 _______ _ _ _____ ___
159 __/ __/ _ \ (_)__ | | / / _ \/ _ \
160 _/ _// // / / / _ \ | |/ / ___/ ___/
161 /_/ /____(_)_/\___/ |___/_/ /_/
162
163 vpp# exec /usr/share/vpp/scripts/gigup.txt
164 vpp# quit
165
166If the file is not labeled properly, you will see something similar to:
167
168::
169
170 $ vppctl exec /home/<user>/dev/vpp/scripts/vppctl/gigup.txt
171 exec: failed to open `/home/<user>/dev/vpp/scripts/vppctl/gigup.txt': Permission denied
172
173 $ ls -alZ
174 drwxrwxr-x. <user> <user> unconfined_u:object_r:user_home_t:s0 .
175 drwxrwxr-x. <user> <user> unconfined_u:object_r:user_home_t:s0 ..
176 -rw-r--r--. <user> <user> unconfined_u:object_r:user_home_t:s0 gigup.txt
177
178Original Documentation
179''''''''''''''''''''''
180
181Some of the original documentation showed script files being executed
182out of ``/tmp/``. Convenience also may lead to script files being placed
183in ``/home/<user>/`` subdirectories. If a file is generated by the VPP
184process in ``/tmp/``, for example a trace file or pcap file, it will get
185properly labeled with the SELinux label ``vpp_tmp_t``. When a file is
186created, unless a rule is in place for the process that created it, the
187file will inherit the SELinux label of the parent directory. So if a
188user creates a file themselves in ``/tmp/``, it will get the SELinux
189label ``tmp_t``, which VPP does not have permission to access. Therefore
190it is recommended that script files are located as described above.
191
192vHost Sockets
193^^^^^^^^^^^^^
194
195vHost sockets are created from VPP perspective in either Server or
196Client mode. In Server mode, the socket name is provided to VPP and VPP
197creates the socket. In Client mode, the socket name is provided to VPP
198and the hypervisor creates the socket. In order for VPP and hypervisor
199to share the socket resource with SELinux enabled, a rule in the VPP
200Custom SELinux Policy has been added. This rules allows processes with
201the ``svirt_t`` label (the hypervisor) to access sockets with the
202``vpp_var_run_t`` label. As such, when SELinux is enabled, vHost sockets
203should be created in the directory ``/var/run/vpp/``.
204
205.. _original-documentation-1:
206
207Original Documentation
208''''''''''''''''''''''
209
210Some of the original documentation showed vHost sockets being created in
211the directory ``/tmp/``. To work properly with SELinux enabled, vHost
212sockets should be created as described above.
213
214VPP Log Files
215^^^^^^^^^^^^^
216
217The VPP log file location is set by updating the
218``/etc/vpp/startup.conf`` file:
219
220::
221
222 vi /etc/vpp/startup.conf
223 unix {
224 :
225 log /var/log/vpp/vpp.log
226 :
227 }
228
229By moving the log file to ``/var/log/vpp/``, it will get the label
230``vpp_log_t``, which indicates that the files are log files so they
231benefit from the associated rules (for example granting rights to
232logrotate so that it can manipulate them).
233
234.. _original-documentation-2:
235
236Original Documentation
237''''''''''''''''''''''
238
239The default ``startup.conf`` file creates the VPP log file in
240``/tmp/vpp.log``. By leaving the log file in ``/tmp/``, it will get the
241label ``vpp_tmp_t``. Moving it to ``/var/log/vpp/``, it will get the
242label ``vpp_log_t``.
243
244Use of Non-default File Directories
245~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
246
247VPP installs multiple files on the system. Some files have fixed
248directory and file names: - /etc/bash_completion.d/vppctl_completion -
249/etc/sysctl.d/80-vpp.conf - /usr/lib/systemd/system/vpp.service
250
251Others files have default directory and file names but the default can
252be overwritten: - /etc/vpp/startup.conf - Can be changed via the
253``/usr/lib/systemd/system/vpp.service`` file by changing the -c option
254on the VPP command line:
255
256::
257
258 ExecStart=/usr/bin/vpp -c /etc/vpp/startup.conf
259
260- /run/vpp/cli.sock
261
262 - Can be changed via the ``/etc/vpp/startup.conf`` file by changing
263 the cli-listen setting:
264
265::
266
267 unix {
268 :
269 cli-listen /run/vpp/cli.sock
270 :
271 }
272
273- /var/log/vpp/vpp.log
274
275 - Can be changed via the ``/etc/vpp/startup.conf`` file by changing
276 the log setting:
277
278::
279
280 unix {
281 :
282 log /var/log/vpp/vpp.log
283 :
284 }
285
286If the directory of any VPP installed files is changed from the default,
287ensure that the proper SELiunx label is applied. The SELinux label can
288be determined by passing the -Z option to many common Linux commands:
289
290::
291
292 ls -alZ /run/vpp/
293 drwxr-xr-x. root vpp system_u:object_r:vpp_var_run_t:s0 .
294 drwxr-xr-x. root root system_u:object_r:var_run_t:s0 ..
295 srwxrwxr-x. root vpp system_u:object_r:vpp_var_run_t:s0 cli.sock
296
297VPP SELinux Types
298~~~~~~~~~~~~~~~~~
299
300The following SELinux types are created by the VPP Custom SELinux
301Policy: - ``vpp_t`` - Applied to: - VPP process and spawned threads.
302
303- ``vpp_config_rw_t`` - Applied to:
304
305 - ``/etc/vpp/*``
306
307- ``vpp_tmp_t`` - Applied to:
308
309 - ``/tmp/*``
310
311- ``vpp_exec_t`` - Applied to:
312
313 - ``/usr/bin/*``
314
315- ``vpp_lib_t`` - Applied to:
316
317 - ``/usr/lib/vpp_api_test_plugins/*``
318 - ``/usr/lib/vpp_plugins/*``
319
320- ``vpp_unit_file_t`` - Applied to:
321
322 - ``/usr/lib/systemd/system/vpp.*``
323
324- ``vpp_log_t`` - Applied to:
325
326 - ``/var/log/vpp/*``
327
328- ``vpp_var_run_t`` - Applied to:
329
330 - ``/var/run/vpp/*``
331
332Debug SELinux Issues
333--------------------
334
335If SELinux issues are suspected, there are a few steps that can be taken
336to debug the issue. This section provides a few pointers on on those
337steps. Any SELinux JIRAs will need this information to properly address
338the issue.
339
340Additional SELinux Packages and Setup
341~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
342
343First, install the SELinux troubleshooting packages:
344
345::
346
347 $ sudo yum -y install setroubleshoot setroubleshoot-server setools-console
348 -- OR --
349 $ sudo dnf -y install setroubleshoot setroubleshoot-server setools-console
350
351To enable proper logging, restart auditd:
352
353::
354
355 $ sudo service auditd restart
356
357While debugging issues, it is best to set SELinux to ``Permissive``
358mode. In ``Permissive`` mode, SELinux will still detect and flag errors,
359but will allow processes to continue normal operation. This allows
360multiple errors to be collected at once as opposed to breaking on each
361individual error. To set SELinux to ``Permissive`` mode (until next
362reboot or it is set back), use:
363
364::
365
366 $ sudo setenforce 0
367
368 $ getenforce
369 Permissive
370
371After debugging, to set SELinux back to ``Enforcing`` mode, use:
372
373::
374
375 $ sudo setenforce 1
376
377 $ getenforce
378 Enforcing
379
380Debugging
381~~~~~~~~~
382
383Once the SELinux troubleshooting packages are installed, perform the
384actions that are suspected to be blocked by SELinux. Either ``tail`` the
385log during these actions or ``grep`` the log for additional SELinux
386logs:
387
388::
389
390 sudo tail -f /var/log/messages
391 -- OR --
392 sudo journalctl -f
393
394Below are some examples of SELinux logs that are generated:
395
396::
397
398 May 14 11:28:34 svr-22 setroubleshoot: SELinux is preventing /usr/bin/vpp from read access on the file hostCreate.txt. For complete SELinux messages run: sealert -l a418f869-f470-4c8a-b8e9-bdd41f2dd60b
399 May 14 11:28:34 svr-22 python: SELinux is preventing /usr/bin/vpp from read access on the file hostCreate.txt.#012#012***** Plugin catchall (100. confidence) suggests **************************#012#012If you believe that vpp should be allowed read access on the hostCreate.txt file by default.#012Then you should report this as a bug.#012You can generate a local policy module to allow this access.#012Do#012allow this access for now by executing:#012# ausearch -c 'vpp_main' --raw | audit2allow -M my-vppmain#012# semodule -i my-vppmain.pp#012
400 May 14 11:28:34 svr-22 setroubleshoot: SELinux is preventing /usr/bin/vpp from read access on the file hostCreate.txt. For complete SELinux messages run: sealert -l a418f869-f470-4c8a-b8e9-bdd41f2dd60b
401 May 14 11:28:34 svr-22 python: SELinux is preventing /usr/bin/vpp from read access on the file hostCreate.txt.#012#012***** Plugin catchall (100. confidence) suggests **************************#012#012If you believe that vpp should be allowed read access on the hostCreate.txt file by default.#012Then you should report this as a bug.#012You can generate a local policy module to allow this access.#012Do#012allow this access for now by executing:#012# ausearch -c 'vpp_main' --raw | audit2allow -M my-vppmain#012# semodule -i my-vppmain.pp#012
402 May 14 11:28:37 svr-22 setroubleshoot: SELinux is preventing vpp_main from map access on the packet_socket packet_socket. For complete SELinux messages run: sealert -l ab6667d9-3f14-4dbd-96a0-7a655f7b4eb1
403 May 14 11:28:37 svr-22 python: SELinux is preventing vpp_main from map access on the packet_socket packet_socket.#012#012***** Plugin catchall (100. confidence) suggests **************************#012#012If you believe that vpp_main should be allowed map access on the packet_socket packet_socket by default.#012Then you should report this as a bug.#012You can generate a local policy module to allow this access.#012Do#012allow this access for now by executing:#012# ausearch -c 'vpp_main' --raw | audit2allow -M my-vppmain#012# semodule -i my-vppmain.pp#012
404 May 14 11:28:51 svr-22 setroubleshoot: SELinux is preventing vpp_main from map access on the packet_socket packet_socket. For complete SELinux messages run: sealert -l ab6667d9-3f14-4dbd-96a0-7a655f7b4eb1
405 May 14 11:28:51 svr-22 python: SELinux is preventing vpp_main from map access on the packet_socket packet_socket.#012#012***** Plugin catchall (100. confidence) suggests **************************#012#012If you believe that vpp_main should be allowed map access on the packet_socket packet_socket by default.#012Then you should report this as a bug.#012You can generate a local policy module to allow this access.#012Do#012allow this access for now by executing:#012# ausearch -c 'vpp_main' --raw | audit2allow -M my-vppmain#012# semodule -i my-vppmain.pp#012
406
407From the logs above, there are two sets of commands that are recommended
408to be run. The first is to run the ``sealert`` command. The second is to
409run the ``ausearch | audit2allow`` commands and the ``semodule``
410command.
411
412sealert Command
413^^^^^^^^^^^^^^^
414
415This ``sealert`` command provides a more detailed output for the given
416issue detected.
417
418::
419
420 $ sealert -l a418f869-f470-4c8a-b8e9-bdd41f2dd60b
421 SELinux is preventing /usr/bin/vpp from 'read, write' accesses on the chr_file noiommu-0.
422
423 ***** Plugin device (91.4 confidence) suggests ****************************
424
425 If you want to allow vpp to have read write access on the noiommu-0 chr_file
426 Then you need to change the label on noiommu-0 to a type of a similar device.
427 Do
428 # semanage fcontext -a -t SIMILAR_TYPE 'noiommu-0'
429 # restorecon -v 'noiommu-0'
430
431 ***** Plugin catchall (9.59 confidence) suggests **************************
432
433 If you believe that vpp should be allowed read write access on the noiommu-0 chr_file by default.
434 Then you should report this as a bug.
435 You can generate a local policy module to allow this access.
436 Do
437 allow this access for now by executing:
438 # ausearch -c 'vpp' --raw | audit2allow -M my-vpp
439 # semodule -i my-vpp.pp
440
441
442 Additional Information:
443 Source Context system_u:system_r:vpp_t:s0
444 Target Context system_u:object_r:device_t:s0
445 Target Objects noiommu-0 [ chr_file ]
446 Source vpp
447 Source Path /usr/bin/vpp
448 Port <Unknown>
449 Host vpp_centos7_selinux
450 Source RPM Packages vpp-19.01.2-rc0~17_gcfd3086.x86_64
451 Target RPM Packages
452 Policy RPM selinux-policy-3.13.1-229.el7_6.12.noarch
453 Selinux Enabled True
454 Policy Type targeted
455 Enforcing Mode Permissive
456 Host Name vpp_centos7_selinux
457 Platform Linux vpp_centos7_selinux
458 3.10.0-957.12.1.el7.x86_64 #1 SMP Mon Apr 29
459 14:59:59 UTC 2019 x86_64 x86_64
460 Alert Count 1
461 First Seen 2019-05-13 18:10:50 EDT
462 Last Seen 2019-05-13 18:10:50 EDT
463 Local ID a418f869-f470-4c8a-b8e9-bdd41f2dd60b
464
465 Raw Audit Messages
466 type=AVC msg=audit(1557785450.964:257): avc: denied { read write } for pid=5273 comm="vpp" name="noiommu-0" dev="devtmpfs" ino=36022 scontext=system_u:system_r:vpp_t:s0 tcontext=system_u:object_r:device_t:s0 tclass=chr_file permissive=1
467
468
469 type=AVC msg=audit(1557785450.964:257): avc: denied { open } for pid=5273 comm="vpp" path="/dev/vfio/noiommu-0" dev="devtmpfs" ino=36022 scontext=system_u:system_r:vpp_t:s0 tcontext=system_u:object_r:device_t:s0 tclass=chr_file permissive=1
470
471
472 type=SYSCALL msg=audit(1557785450.964:257): arch=x86_64 syscall=open success=yes exit=ENOTBLK a0=7fb395ffd7f0 a1=2 a2=7fb395ffd803 a3=7fb395ffe2a0 items=0 ppid=1 pid=5273 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=993 sgid=0 fsgid=993 tty=(none) ses=4294967295 comm=vpp exe=/usr/bin/vpp subj=system_u:system_r:vpp_t:s0 key=(null)
473
474 Hash: vpp,vpp_t,device_t,chr_file,read,write
475
476In general, this command pumps out too much info and is only needed for
477additional debugging for tougher issues. Also note that once the process
478being tested is restarted, this command loses it’s context and will not
479provide any information:
480
481::
482
483 $ sealert -l a418f869-f470-4c8a-b8e9-bdd41f2dd60b
484 Error
485 query_alerts error (1003): id (a418f869-f470-4c8a-b8e9-bdd41f2dd60b) not found
486
487ausearch \| audit2allow and semodule Commands
488^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
489
490These set of commands are more useful for basic debugging. The
491``ausearch | audit2allow`` commands generate a set files. It may be
492worthwhile to run the commands in a temporary subdirectory:
493
494::
495
496 $ mkdir test-01/; cd test-01/
497
498 $ sudo ausearch -c 'vpp_main' --raw | audit2allow -M my-vppmain
499
500 $ ls
501 my-vpp.pp my-vpp.te
502
503 $ cat my-vpp.te
504 module my-vpp 1.0;
505
506 require {
507 type user_home_t;
508 type vpp_t;
509 class packet_socket map;
510 class file { open read };
511 }
512
513 #============= vpp_t ==============
514 allow vpp_t self:packet_socket map;
515 allow vpp_t user_home_t:file { open read };
516
517As shown above, the file ``my-vpp.te`` has been generated. This file
518shows possible changes to the SELinux policy that may fix the issue. If
519an SELinux policy was being created from scratch, this policy could be
520applied using the ``semodule -i my-vpp.pp`` command. HOWEVER, VPP
521already has a policy in place. So these changes need to be incorporated
522into the existing policy. The VPP SELinux policy is located in the
523following files:
524
525::
526
527 $ ls extras/selinux/
528 selinux_doc.md vpp-custom.fc vpp-custom.if vpp-custom.te
529
530In this example, ``map`` needs to be added to the ``packet_socket``
531class. If the ``vpp-custom.te`` is examined (prior to this fix), then
532one would see that the ``packet_socket`` class is already defined and
533just needs to be updated:
534
535::
536
537 $ vi extras/selinux/vpp-custom.te
538 :
539 allow vpp_t self:process { execmem execstack setsched signal }; # too benevolent
540 allow vpp_t self:packet_socket { bind create setopt ioctl }; <---
541 allow vpp_t self:tun_socket { create relabelto relabelfrom };
542 :
543
544Before blindly applying the changes proposed by the
545``ausearch | audit2allow`` commands, try to determine what is being
546allowed by the policy and determine if this is desired, or if the code
547can be reworked to no longer require the suggested permission. In the
548``my-vpp.te`` file from above, it is suggested to allow ``vpp_t``
549(i.e. the VPP process) access to all files in the home directory
550(``allow vpp_t user_home_t:file { open read };``). This was because a
551``vppctl exec`` command was executed calling a script located in the
552``/home/<user>/`` directory. Once this script was run from the
553``/usr/share/vpp/`` directory as described in a section above, these
554permissions were no longer needed.