<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: olaboyejo</title>
    <description>The latest articles on DEV Community by olaboyejo (@boyeolowoyeye).</description>
    <link>https://dev.to/boyeolowoyeye</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F679329%2Fe276c075-0df0-4855-bfd7-61aaf9a9e6d5.png</url>
      <title>DEV Community: olaboyejo</title>
      <link>https://dev.to/boyeolowoyeye</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/boyeolowoyeye"/>
    <language>en</language>
    <item>
      <title>Linux Capabilities Use Cases - systemd</title>
      <dc:creator>olaboyejo</dc:creator>
      <pubDate>Tue, 17 Aug 2021 11:22:16 +0000</pubDate>
      <link>https://dev.to/boyeolowoyeye/linux-capabilities-use-cases-systemd-2n8n</link>
      <guid>https://dev.to/boyeolowoyeye/linux-capabilities-use-cases-systemd-2n8n</guid>
      <description>&lt;h4&gt;
  
  
  Introduction
&lt;/h4&gt;

&lt;p&gt;The &lt;a href="https://dev.to/boyeolowoyeye/linux-capabilities-set-and-bits-f1o"&gt;last post&lt;/a&gt; was a discussion on capabilities sets and the bits that make up the sets. We also saw how we can examine the capabilities sets of threads and processes. In this post, we will be looking at the application of capabilities to processes managed by &lt;em&gt;systemd&lt;/em&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  systemd
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;systemd&lt;/em&gt; is the default system and services manager on most modern Linux distributions. When run as the first process on boot (&lt;em&gt;PID 1&lt;/em&gt;), It manages the startup, operation of userspace services. As the &lt;em&gt;init&lt;/em&gt; system, the &lt;em&gt;systemd&lt;/em&gt; process runs with an effective User ID of 0. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(base) boye@hp7940m1:~$ ps -fp 1
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 Aug16 ?        00:00:41 /sbin/init splash
(base) boye@hp7940m1:~$ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yxbWzmqj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ivffh9jyrmwes8tdlm0m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yxbWzmqj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ivffh9jyrmwes8tdlm0m.png" alt="Process Examination of systemd"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To explore the capabilities sets of the processes managed by &lt;em&gt;systemd&lt;/em&gt; and the configuration settings that change the default behaviour, we will be using a small python script for convenience. This script (&lt;em&gt;cap_display&lt;/em&gt;) is on &lt;a href="https://github.com/boyejoo/linux_capabilities"&gt;github&lt;/a&gt;. This repository has some of the other files we will be using for demonstration. The &lt;em&gt;README.md&lt;/em&gt; file has the descriptions and installation instructions for these files. &lt;/p&gt;

&lt;p&gt;The &lt;em&gt;cap_display&lt;/em&gt; script scrapes the &lt;em&gt;/usr/include/linux/capability.h&lt;/em&gt; file to create a mapping between capability names and their bit values. It also reads the hexadecimal representation of the capabilities set  for a &lt;strong&gt;PID&lt;/strong&gt; in  &lt;em&gt;/proc/&lt;/em&gt;&lt;strong&gt;PID&lt;/strong&gt;/status file and uses the mapping to print a human-friendly representation of the capabilities set.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(capabilities_show) (base) boye@hp7940m1:~/Documents/dev/capabilities_show$ cap_display --pid 1
Name:   systemd
Tgid:   1
Pid:    1
PPid:   0
Uid:    0       0       0       0
Gid:    0       0       0       0

CapInh:  0000000000000000        None
CapPrm:  0000003fffffffff        cap_audit_read,cap_block_suspend,cap_wake_alarm,cap_syslog,cap_mac_admin,cap_mac_override,cap_setfcap,cap_audit_control,cap_audit_write,cap_lease,cap_mknod,cap_sys_tty_config,cap_sys_time,cap_sys_resource,cap_sys_nice,cap_sys_boot,cap_sys_admin,cap_sys_pacct,cap_sys_ptrace,cap_sys_chroot,cap_sys_rawio,cap_sys_module,cap_ipc_owner,cap_ipc_lock,cap_net_raw,cap_net_admin,cap_net_broadcast,cap_net_bind_service,cap_linux_immutable,cap_setpcap,cap_setuid,cap_setgid,cap_kill,cap_fsetid,cap_fowner,cap_dac_read_search,cap_dac_override,cap_chown
CapEff:  0000003fffffffff        cap_audit_read,cap_block_suspend,cap_wake_alarm,cap_syslog,cap_mac_admin,cap_mac_override,cap_setfcap,cap_audit_control,cap_audit_write,cap_lease,cap_mknod,cap_sys_tty_config,cap_sys_time,cap_sys_resource,cap_sys_nice,cap_sys_boot,cap_sys_admin,cap_sys_pacct,cap_sys_ptrace,cap_sys_chroot,cap_sys_rawio,cap_sys_module,cap_ipc_owner,cap_ipc_lock,cap_net_raw,cap_net_admin,cap_net_broadcast,cap_net_bind_service,cap_linux_immutable,cap_setpcap,cap_setuid,cap_setgid,cap_kill,cap_fsetid,cap_fowner,cap_dac_read_search,cap_dac_override,cap_chown
CapBnd:  0000003fffffffff        cap_audit_read,cap_block_suspend,cap_wake_alarm,cap_syslog,cap_mac_admin,cap_mac_override,cap_setfcap,cap_audit_control,cap_audit_write,cap_lease,cap_mknod,cap_sys_tty_config,cap_sys_time,cap_sys_resource,cap_sys_nice,cap_sys_boot,cap_sys_admin,cap_sys_pacct,cap_sys_ptrace,cap_sys_chroot,cap_sys_rawio,cap_sys_module,cap_ipc_owner,cap_ipc_lock,cap_net_raw,cap_net_admin,cap_net_broadcast,cap_net_bind_service,cap_linux_immutable,cap_setpcap,cap_setuid,cap_setgid,cap_kill,cap_fsetid,cap_fowner,cap_dac_read_search,cap_dac_override,cap_chown
CapAmb:  0000000000000000        None
(capabilities_show) (base) boye@hp7940m1:~/Documents/dev/capabilities_show$ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CAq3YUKc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8udp4z4mv9d70z9yvpwx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CAq3YUKc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8udp4z4mv9d70z9yvpwx.png" alt="Alt Text"&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;Above is an examination of PID 1 using the script. Here we can see the UID and GID =0 and the effective, permitted and bounded capabilities sets for the process. The have all their bits set. This is expected for a process with the EUID=0. &lt;/p&gt;

&lt;p&gt;We will be looking at three configuration options in &lt;em&gt;systemd&lt;/em&gt; unit files that can influence the capabilities set for services managed by &lt;em&gt;systemd&lt;/em&gt;. These are the &lt;em&gt;User&lt;/em&gt;, &lt;em&gt;AmbientCapabilities&lt;/em&gt; and &lt;em&gt;CapabilityBoundingSet&lt;/em&gt; options.&lt;/p&gt;

&lt;h4&gt;
  
  
  Default behaviour for processes managed by &lt;em&gt;systemd&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;We will be exploring the behaviour of processes managed by &lt;em&gt;systemd&lt;/em&gt; from the perspective of a dummy service unit that tells the current time. This service is a go application (&lt;em&gt;DayTimeServer&lt;/em&gt;) which you can find in the post series &lt;a href="https://github.com/boyejoo/linux_capabilities"&gt;repository&lt;/a&gt;. The code is adapted from one of the examples in this &lt;a href="https://www.springer.com/de/book/9781484226919"&gt;book&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We run our cutting edge service by running the executable and specifying a TCP port number as shown below;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(base) boye@hp7940m1:~/go/bin$ ./DayTimeServer 1021
Fatal Error: listen tcp :1021: bind: permission denied
(base) boye@hp7940m1:~/go/bin$ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z5WPd9nN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9m4lrn584iv2fx1zbc74.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z5WPd9nN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9m4lrn584iv2fx1zbc74.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No surprises at the failure above because an unprivileged user cannot use the port numbers under 1024. The service is started below with TCP port 1029.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(base) boye@hp7940m1:~/go/bin$ ./DayTimeServer 1029
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zqDEULNF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xt9582wrxlo1wvqy9d4q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zqDEULNF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xt9582wrxlo1wvqy9d4q.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(base) boye@hp7940m1:~/go/bin$ nc localhost 1029
2021-08-17 21:29:47.570860654 +1200 NZST m=+50.203298522
(base) boye@hp7940m1:~/go/bin$  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gh76P9f8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dey0jkmm7hq4ryrgq04f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gh76P9f8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dey0jkmm7hq4ryrgq04f.png" alt="Alt Text"&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;We get the date and time using the &lt;em&gt;nc&lt;/em&gt; utility to probe the server.&lt;/p&gt;

&lt;h5&gt;
  
  
  Unprivileged Port
&lt;/h5&gt;

&lt;p&gt;We now run the server as a &lt;em&gt;systemd&lt;/em&gt; managed service using the unit file configuration below.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(base) boye@hp7940m1:/etc/systemd/system$ cat daytimeServer.service 
Description=Cutting Edge DayTime Announcement Service

[Service]
Type=simple
ExecStart=/home/boye/go/bin/DayTimeServer 3000

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V0VrwSR6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d0dikaad4fzdklufei3j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V0VrwSR6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d0dikaad4fzdklufei3j.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see the process is running on TCP port 3000.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3irT4VFe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f98lwe1ai5cvelkes196.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3irT4VFe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f98lwe1ai5cvelkes196.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The capabilities set, just like that of &lt;em&gt;systemd&lt;/em&gt;, has all the effective capability set bits enabled.&lt;/p&gt;

&lt;h5&gt;
  
  
  Privileged Port
&lt;/h5&gt;

&lt;p&gt;We will now attempt to run same service with a same privileged port 1021&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(base) boye@hp7940m1:/etc/systemd/system$ cat daytimeServer.service 
Description=Cutting Edge DayTime Announcement Service

[Service]
Type=simple
ExecStart=/home/boye/go/bin/DayTimeServer 1021

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AK5gPhYd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0hjysyux8ih0eocft38c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AK5gPhYd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0hjysyux8ih0eocft38c.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JZzlp74U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w5c80msxmc8gmx9zw45r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JZzlp74U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w5c80msxmc8gmx9zw45r.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that it runs successfully and an examination of the process ID shows that it has all the effective capabilities bits set.&lt;/p&gt;

&lt;p&gt;In summary, the processes managed by &lt;em&gt;systemd&lt;/em&gt; run with all the privileges enabled by default.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;systemd&lt;/em&gt; unit file with &lt;em&gt;User&lt;/em&gt; option
&lt;/h4&gt;

&lt;p&gt;We will now run the same binary service but we will be setting the user to a non-privileged user. Below is the &lt;em&gt;systemd&lt;/em&gt; service unit file.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(base) boye@hp7940m1:/etc/systemd/system$ cat daytimeServer_user.service 
Description=Cutting Edge DayTime Announcement Service

[Service]
Type=simple
ExecStart=/home/boye/go/bin/DayTimeServer 3001
User=boye

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Xjkk2WlD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ofor3hct829qbjc470c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xjkk2WlD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ofor3hct829qbjc470c.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dhpi7sl7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kh3pfd37hxsm08086asf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dhpi7sl7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kh3pfd37hxsm08086asf.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see from the output above that the process has no effective capability bits set.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;systemd&lt;/em&gt; unit file with &lt;em&gt;AmbientCapabilities&lt;/em&gt; option
&lt;/h4&gt;

&lt;p&gt;Now the boss just informed us that our biggest competitor in the daytime service app business just raised the bar. They allow their service to be run on privileged ports. Using the Ambient capabilities option in the service unit file, we can add this feature to our service.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(base) boye@hp7940m1:/etc/systemd/system$ cat daytimeServer_user_net_bind.service 
Description=Cutting Edge DayTime Announcement Service

[Service]
Type=simple
ExecStart=/home/boye/go/bin/DayTimeServer 105
User=boye
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the unit file above, we are attempting to run the service on TCP port 105 and we are setting the &lt;em&gt;CAP_NET_BIND_SERVICE&lt;/em&gt; bit in the ambient capabilities set. That capability empowers an unprivileged user to bind to network ports below 1024.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZpY8hJkJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rqckgc273hjuzj7l1b4b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZpY8hJkJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rqckgc273hjuzj7l1b4b.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---2osLeVQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mr605zkex910a7v23i67.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---2osLeVQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mr605zkex910a7v23i67.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see from the  output above that even though the process is owned by a regular user, using the &lt;em&gt;AmbientCapabilities&lt;/em&gt; option allows the process to bind to a privileged port number. The &lt;em&gt;cap_display&lt;/em&gt; output for the process ID shows that the &lt;em&gt;cap_net_bind_service&lt;/em&gt; bit in the effective capabilities set has been enabled.&lt;/p&gt;

&lt;p&gt;The ambient capabilities set is used to transfer privileges from the parent process (&lt;em&gt;systemd&lt;/em&gt;, PID 1) to the service process.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;systemd&lt;/em&gt; unit file with &lt;em&gt;CapabilityBoundingSet&lt;/em&gt; option
&lt;/h4&gt;

&lt;p&gt;The final option we will be exploring in this post is particularly useful for situations where we don't want to change the user for the process but we want the process to be limited to just the required privileges. The &lt;em&gt;CapabilityBoundingSet&lt;/em&gt; option in the service unit file serves as a limiting set of what can be transferred from the parent to the child process. &lt;/p&gt;

&lt;p&gt;We will look at the effects by using the service unit file below which effectively disables all the bits in the bounding capabilities set.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(base) boye@hp7940m1:/etc/systemd/system$ cat daytimeServer_limited.service 
Description=Cutting Edge DayTime Announcement Service

[Service]
Type=simple
ExecStart=/home/boye/go/bin/DayTimeServer 3002
CapabilityBoundingSet=

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--THwexcZP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ixbh8dhrz8n69gt9li4r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--THwexcZP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ixbh8dhrz8n69gt9li4r.png" alt="Alt Text"&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vCtSI-Gn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ru87b1tmikntfsgsg5cp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vCtSI-Gn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ru87b1tmikntfsgsg5cp.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the &lt;em&gt;cap_display&lt;/em&gt; output we can see that in spite of the process running as a privileged user, it has no effective permissions set. Attempting to use a privileged port will meet with failure as shown below.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(base) boye@hp7940m1:/etc/systemd/system$ cat daytimeServer_limited_privilege_port_attempt.service 
Description=Cutting Edge DayTime Announcement Service

[Service]
Type=simple
ExecStart=/home/boye/go/bin/DayTimeServer 108
CapabilityBoundingSet=

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ioFZ_TW_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4w9ox1bt8t11iqv3v3pz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ioFZ_TW_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4w9ox1bt8t11iqv3v3pz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have just seen three options to modify the default behaviour that confers all privileges to all processes started and managed by &lt;em&gt;systemd&lt;/em&gt;. The &lt;em&gt;CapabilityBoundingSet&lt;/em&gt; option in the unit files can be used to decrease the capabilities that can be passed to a child process running as root  and the &lt;em&gt;AmbientCapabilities&lt;/em&gt; option is useful for giving specific privilege(s) to child processes that belongs to an unprivileged user. &lt;/p&gt;

&lt;p&gt;The next post will explore the docker use case.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>security</category>
    </item>
    <item>
      <title>Linux Capabilities Set and Bits</title>
      <dc:creator>olaboyejo</dc:creator>
      <pubDate>Sun, 15 Aug 2021 08:02:54 +0000</pubDate>
      <link>https://dev.to/boyeolowoyeye/linux-capabilities-set-and-bits-f1o</link>
      <guid>https://dev.to/boyeolowoyeye/linux-capabilities-set-and-bits-f1o</guid>
      <description>&lt;h4&gt;
  
  
  Introduction
&lt;/h4&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/boyeolowoyeye/linux-capabilities-overview-5dgb"&gt;previous post&lt;/a&gt;, the concept of Linux capabilities was introduced. In this post, I will be exploring the capability sets and capability bits in a bit more detail. This is a prelude to future posts that will examine the practical use cases of capabilities in &lt;a href="https://dev.to/boyeolowoyeye/linux-capabilities-use-cases-systemd-2n8n"&gt;&lt;em&gt;systemd&lt;/em&gt;&lt;/a&gt;, &lt;em&gt;dockerd&lt;/em&gt; and &lt;em&gt;fork/execve&lt;/em&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Capabilities Sets
&lt;/h4&gt;

&lt;p&gt;Capabilities are properties of threads (or processes). They have thread-level granularity. Applications also have a concept of capabilities and this will be explored separately in more depth when we investigate the &lt;em&gt;execve&lt;/em&gt; use cases. A thread has the following capability sets; &lt;/p&gt;

&lt;h5&gt;
  
  
  Effective Capability Set
&lt;/h5&gt;

&lt;p&gt;This is the set of privileged activities that the kernel performs permission checks on before a thread can accomplish a task.&lt;/p&gt;

&lt;h5&gt;
  
  
  Inheritable Capability Set
&lt;/h5&gt;

&lt;p&gt;The capabilities in this set are transferable between parent and child processes after an &lt;em&gt;execve&lt;/em&gt; system call for privileged programs. This will be discussed in more detail in a future post dealing with &lt;em&gt;fork/clone&lt;/em&gt; and &lt;em&gt;execve&lt;/em&gt; system calls&lt;/p&gt;

&lt;h5&gt;
  
  
  Permitted Capability Set
&lt;/h5&gt;

&lt;p&gt;The permitted set serves as a limiting superset for the effective set. The capabilities that are not set in the permitted set cannot be enabled in the effective set except;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The the program file capability set contains the capability in its permitted set.&lt;/li&gt;
&lt;li&gt;The program it (the thread) is executing is with the set-user-ID-root.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It also limits the capabilities that can be inherited if the &lt;em&gt;CAP_SETPCAP&lt;/em&gt; capability is not present in a thread's effective capability set.&lt;/p&gt;

&lt;h5&gt;
  
  
  Ambient Capability Set
&lt;/h5&gt;

&lt;p&gt;This capability set is useful when a non privileged thread needs its privileges preserved during an &lt;em&gt;execve&lt;/em&gt; system call. The ambient capability set allows the transfer of capabilities during the &lt;em&gt;execve&lt;/em&gt; systems call. They are preserved across a process that is unprivileged.&lt;/p&gt;

&lt;h5&gt;
  
  
  Bounded Capability Set
&lt;/h5&gt;

&lt;p&gt;This capability set is a limiting superset for capabilities that can be added to the inheritable during an &lt;em&gt;execve&lt;/em&gt; syscall. It is also a limiting factor for permitted set because its AND'ed to the permitted set during &lt;em&gt;execve&lt;/em&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Thread/Process Capability Sets
&lt;/h4&gt;

&lt;p&gt;The capability sets attached to a thread or a process can be read from the &lt;em&gt;/proc/&lt;/em&gt;&lt;strong&gt;pid&lt;/strong&gt;&lt;em&gt;/status&lt;/em&gt; file where &lt;strong&gt;pid&lt;/strong&gt; is process or task ID. For example to see the capabilities the current process is using, we can run the command below;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat /proc/$$/status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;strong&gt;$$&lt;/strong&gt; is a special bash parameter representing the current process so the command below will print the current process ID.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo $$ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The file &lt;em&gt;/proc/&lt;/em&gt;&lt;strong&gt;pid&lt;/strong&gt;&lt;em&gt;/status&lt;/em&gt; contains a lot more information about the process ID under observation. The screen-dump below is a grep of just the capabilities section of the output of my current shell process.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;boye@hp7940m1:~/Documents/dev/capabilities_show$ echo $$
13575
boye@hp7940m1:~/Documents/dev/capabilities_show$ grep Cap /proc/13575/status
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
boye@hp7940m1:~/Documents/dev/capabilities_show$ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The capabilities sets introduced earlier can be seen in the output above. They are in hexadecimal form with each character representing a nibble(four bits). The individual capabilities are bit positions in the 64 bit output for each capability set. Setting the bit(1) in the position enables the respective capability, while clearing it (0), disables the capability for the capability set. &lt;/p&gt;

&lt;p&gt;The arrangement of the capabilities in the 64 bit data structure is defined in the header file &lt;em&gt;/usr/include/linux/capability.h&lt;/em&gt;. The content of this file is determined by the kernel version so you will find that different kernel versions can have varying levels of support for capabilities. The bit positions are numbered from 0 to the latest supported by the kernel. To check the latest capability supported on a system;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat /proc/sys/kernel/cap_last_cap 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The output from my system is shown below. It does not have the &lt;em&gt;CAP_BPF&lt;/em&gt; and &lt;em&gt;CAP_PERFMON&lt;/em&gt; capabilities introduced in Kernel version 5.8.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;boye@hp7940m1:~/Documents/dev/capabilities_show$ uname -a
Linux hp7940m1 5.4.0-80-generic #90-Ubuntu SMP Fri Jul 9 22:49:44 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
boye@hp7940m1:~/Documents/dev/capabilities_show$ cat /proc/sys/kernel/cap_last_cap 
37
boye@hp7940m1:~/Documents/dev/capabilities_show$ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;em&gt;cap_last_cap&lt;/em&gt; file output of 37 means that the kernel has support for positions 0 - 37 which means that 38 capabilities are supported. This can be seen in the capability bounding set for the current shell process.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CapBnd: 0000003fffffffff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;An examination of the values shown there are nine f(1111 in binary) characters and one 3(11 in binary) character. That gives 36(9X4) + 2 ones which means there are 38 bit positions set which is all the capabilities supported on the system. &lt;/p&gt;

&lt;p&gt;To see a human readable translation of the hexadecimal representation, you can use the &lt;em&gt;capsh&lt;/em&gt; utility.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;boye@hp7940m1:~/Documents/dev/capabilities_show$ capsh --decode=0x0000003fffffffff
0x0000003fffffffff=cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read
boye@hp7940m1:~/Documents/dev/capabilities_show$    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The output above shows the capabilities enabled in the capability bounding set  for the current shell process. &lt;/p&gt;

&lt;p&gt;With the foregoing, we have enough background to see the practical applications of capabilities. We will start that examination with &lt;em&gt;systemd&lt;/em&gt; in the &lt;a href="https://dev.to/boyeolowoyeye/linux-capabilities-use-cases-systemd-2n8n"&gt;next post&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>security</category>
      <category>systems</category>
    </item>
    <item>
      <title>Linux Capabilities Overview</title>
      <dc:creator>olaboyejo</dc:creator>
      <pubDate>Thu, 12 Aug 2021 10:56:34 +0000</pubDate>
      <link>https://dev.to/boyeolowoyeye/linux-capabilities-overview-5dgb</link>
      <guid>https://dev.to/boyeolowoyeye/linux-capabilities-overview-5dgb</guid>
      <description>&lt;h4&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;In this series, we will be looking at Linux capabilities and how we can use them to run create more secure computing environments. In this particular post, we will go through an introduction of Linux capabilities and how their use compares with the traditional privilege model.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Traditional Model&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Before Linux kernel 2.2, the Linux privilege model typically made a binary decision as a first instance to decide if a process has the required privileges to run a program. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8yolw94q6o7fknivp39y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8yolw94q6o7fknivp39y.png" alt="Linux Traditional Privilege Model"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the Effective User ID (EUID) of the process was 0. This means the effective user is root or a superuser. This user bypassed all other forms of checks and the process ris allowed to run the application. If the EUID is not 0, the process is subjected to other checks such as an examination of the&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;privileges held by the EUID of the process.&lt;/li&gt;
&lt;li&gt;privileges held by the Effective Group ID (EGID) &lt;/li&gt;
&lt;li&gt;privileges held by the supplementary groups the user intending to run the process belongs to. &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Enter Linux Capabilities&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Capabilities are a fine-grained approach to privileges and access control permissions. This is at variance to the all-or-nothing approach of the traditional model where a process needs to run as a super user of some form in other to perform its function. The privileged activities on a system are divided into distinct units with each capability holding a subset of activities. &lt;/p&gt;

&lt;p&gt;With this model, a process just needs the exact capability it requires to perform the activity it needs. For instance a process that needs to change the system time merely requires the &lt;em&gt;CAP_SYS_TIME&lt;/em&gt; capability. It is not required to run as a root user. This scheme allows the security principle of least privilege and also ensures that a compromise of the process carries a lower exposure surface compared to the traditional model. &lt;/p&gt;

&lt;p&gt;It is also worth nothing that the capabilities definitions are not set in stone. It is an area where fine-tuning is constantly ongoing to enforce the principle of least privilege - &lt;em&gt;enabling a process to be granted just the required privilege it requires to perform its tasks and no more&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;CAP_SYS_ADMIN&lt;/em&gt; is one such capability that has undergone a number of refinements to reduce the privileges it held. This is to make sure it isn't used as a defacto superuser capability. If you built a service or ran a container that made use of the &lt;em&gt;CAP_SYS_ADMIN&lt;/em&gt; capability prior to kernel 5.8. You will find that if the process was meant to perform Berkeley Packet Filters (BPF) or performance monitoring tasks, those tasks won't succeed in kernel 5.8. This is because &lt;em&gt;CAP_BPF&lt;/em&gt; and &lt;em&gt;CAP_PERFMON&lt;/em&gt; have been created to take  the BPF and performance monitoring functions respectively away from &lt;em&gt;CAP_SYS_ADMIN&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The capabilities supported on a system and the privileges that accompany them can be checked by viewing the Linux manual pages.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;man 7 capabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the next post in the series, we will be looking at the practical applications of capabilities. &lt;/p&gt;

</description>
      <category>linux</category>
      <category>security</category>
    </item>
  </channel>
</rss>
