Linux Notes: SELinux (introduction for hackers-developers)

  1. The information presented here is intended for educational use by qualified computer technologists.
  2. The information presented here is provided free of charge, as-is, with no warranty of any kind.
Edit: 2020-08-06

Project 1 :: need one directory write-enabled for use by FTP

Introduction (how a simple project went sideways)

project #1 overview

This is how we have been doing backups in our datacenter for the past few years:

  • Early every morning, four smaller OpenVMS nodes (HPE rx2660) employ the DECnet protocol over a private 1 Gb/s Ethernet (net-3) to drop their backup save-sets onto a big disk found in our slightly larger OpenVMS node (HPE rx2800-i2)
    • the four smaller systems are used for development, qualification and user testing
    • the large system is our production platform
  •  A little later, we employ FTP to copy the save-sets over a private 1 Gb/s Ethernet (net-4) to a Windows-7 PC which has a 1 TB drive connected via a USB cable
    • these drives are NTFS formatted
    • We have 30 of these disks so a technician is responsible for replacing the drive every day then making sure it is transported to an off-site location
      • comment: you never know when a meteor will fall from the sky with your data center's name on it. Just ask the dinosaurs
		+-------------------------+	+--------------------------+
		| server : HP rx2800-i2   |	| server : HP DL385p-gen8  |
		| OS     : OpenVMS-8.4    |	| OS     : CentOS-7        |
		| client : MariaDB-5.5-60 |	| server : MariaDB-10.3.11 |
		| net-1  : TCP/IP         +-----+ net-1  : TCP/IP          |
 private  ------+ net-2  : TCP/IP         |	+--------------------------+
 intranet	| net-3  : DECnet         +---> hub to other OpenVMS systems (HP rx2660) 
		| net-4  : TCP/IP         +---> Windows-7 PC (backup host) 
		+-------------------------+

But things change:

  • On Jan of 2019, corporate security asked us to remove the Windows-7 PC and replace it with something else.
    • comment: "I think" they were worried that the OS was no longer supported by Microsoft but did not want to pay to upgrade to Windows-10. Budgets are stretched to the limit these days
  • We've got access to a lot of older HPE DL385-g7 servers so it was no big deal to grab one then install CentOS-7.5
  • I installed
    • VSFTPD (so we could do FTP without the encryption associated with SFTP) as well as...
    • NTFS-G3 (so Linux could mount the 1 TB drives connected by a USB cable)
  • The whole thing should have worked (and would have on a UNIX platform) but did not because of SELinux

Project-1 Details

Caveat: in the following commands you will need to do one of the following:

  1. preface each command with "sudo" (preferred)
        -or-
  2. "su to root" once before the whole lot (old-school)

initial steps (CentOS-7)

Command(s) Comments
yum install vsftpd
vi /etc/vsftpd.conf
install an ftp server
configure the settings file
firewall-cmd --permanent --zone public --add-service ftp
firewall-cmd --reload
prep the firewall
systemctl stop vsftpd.service
systemctl start vsftpd.service
systemctl enable vsftpd.service
make config changes take effect
auto-start this service during reboot
yum install epel-release
yum install ntfs-3g -y
install ntfs software

commands to see connected disks

Commands Comments
fdisk -l  
fdisk -l /dev/sd*  
ls -la /dev/disk/by-label/  
ls -la /dev/disk/by-label/BKUP* see all disks with a label beginning with BKUP

Overview of SELinux

Believe it or not, SELinux was developed by America's NSA (National Security Agency) and combines two approaches to security. (read on)

  • DAC (discretionary access control) is implemented in most systems by file protection bits as well as assigning owner and group information. All three can be seen as red in this display:
    #---------------------------------------------------------------------------------------
    #	inspect a file
    #	note: DAC information is shown in red
    #---------------------------------------------------------------------------------------
    [root@localhost ~]# ls -la /icsis
    total 8
    drwxr-xr-x.  3 root root   16 Jan 25 11:11 .
    dr-xr-xr-x. 18 root root 4096 Jan 25 11:30 ..
    drwxrwxrwx.  1 root root 4096 Sep 20 17:02 win
    [root@localhost ~]#
    #---------------------------------------------------------------------------------------
    #	inspect a process
    #	note: owner in red
    #---------------------------------------------------------------------------------------
    [root@localhost ~]# ps -ef | grep vsftp
    root      6051     1  0 Jan25 ?        00:00:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
  • MAC (mandatory access control) is additionally implemented in Linux systems via a product named SELinux (Security Enhanced Linux) shown in red:
    #---------------------------------------------------------------------------------------
    #	inspect a file (append "Z" to also see SELinux data)
    #	notes:
    #	1) MAC information is shown in red
    #	2) breakout:
    #		system_u is a user context
    #		object_r is a role context
    #		root_t   is a type context
    #		s0       is a level
    #	3) notice that the second line has a context type of "fusefs_t"
    #---------------------------------------------------------------------------------------
    [root@localhost ~]# ls -laZ /icsis
    drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 .
    dr-xr-xr-x. root root system_u:object_r:root_t:s0      ..
    drwxrwxrwx. root root system_u:object_r:fusefs_t:s0    win
    #---------------------------------------------------------------------------------------
    #	inspect a process (append "Z" to also see SELinux data)
    #	note: MAC information is shown in red
    #---------------------------------------------------------------------------------------
    [root@localhost ~]# ps -efZ | grep vsftp
    system_u:system_r:ftpd_t:s0-s0:c0.c1023 root 6051  1  0 Jan25 ?        00:00:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
    unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 root 7398 7225  0 08:39 pts/0 00:00:00 grep --color=auto vsftp
    [root@localhost ~]# 
  • With SELinux enabled and in Enforcing mode, the Linux system first checks the DAC rules then also checks the MAC policy rules so you are now getting two levels of protection.
  • Why is MAC important? Consider one hypothetical example where the webserver executable /usr/sbin/httpd was started with root privileges. A misconfigured server (either by accident or hack) now can access any file on the system as root. SELinux policies prevent this by default.
    • Note that the webserver could still be hacked. But any damage will be contained to the webserver portion of the server. Likewise, a virus or worm will be contained to this section of the server. Your system folders and files will remain unaffected.
  • Some Linux-based software products (Drupal is one example) will instruct the user to either "disable SELinx" or "permanently place SELinux into Permissive mode". Never do this. Why? SELinux was developed by the NSA (National Security Agency) for their own servers then put into the public domain so you would be disabling a very powerful second level security safety net developed by government spooks. I suggest you take the time to educate yourself about this product if you support Linux servers as part of your professional life.
  • To learn more:

Now for a little hacking

part 1: getting new manual pages

You will not learn SELinux in one day. In fact, there are large tomes available on Amazon dedicated to this single topic; but you might be able to learn just enough about this to get yourself over the hump provided you are willing to do a little hacking. So try these two commands:

Commands Comments Additional Info
man ftpd_selinux view SELinux info specific to ftpd All FTPd programs are required to follow these rules
man httpd_selinux view SELinux info specific to httpd All HTTPd programs are required to follow these rules

If neither one of these commands worked but you would like them to, then follow these steps

Commands Comments
yum install selinux-policy-devel  
sepolicy manpage -a -p /usr/local/man/man8 generate new manpages
mandb integrate the new manpages into your index

At this point commands like "man ftpd_selinux" should work properly. Be sure to read the whole thing taking special note of any predefined sebooleans (these are topic-specific boolean variables stored in SELinux)

part2: see what's already found in my SELinux implementation

Commands Comments
semanage boolean -l list all booleans
semanage boolean -l | grep ftp list booleans specific to ftp and sftp

part3: let's make a few changes (this works but is not recommended)

Commands Comments
mkdir /icsis/win
chmod 777 /icsis/win
this will be my mount point (where my USB-DISK will be connected)
note: only need to do this once
setsebool ftpd_use_fusefs 1 since my USB-DISK is being attached by fusefs (see blue text below)
this change will allow all FTPd programs to access directories attached to path /icsis/win
#---------------------------------------------------------------------------------------
#	inspect a file 
#	tack on "Z" to also see SELinux data
#	note: MAC stuff in red and blue
#---------------------------------------------------------------------------------------
[root@localhost ~]# ls -laZ /icsis
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 .
dr-xr-xr-x. root root system_u:object_r:root_t:s0      ..
drwxrwxrwx. root root system_u:object_r:fusefs_t:s0    win
#---------------------------------------------------------------------------------------

part4: an alternate approach (recommended)

Commands Comments
ls -la /dev/disk/by-label/BKUP* take notice where CentOS auto-mounted my USB-DISK
probably will be /dev/sdb1 depending upon how many other drives are present
umount /dev/sdb1 dismount my USB-DISK from where ever it is right now
mount -t /dev/sdb1 /icsis/win mount it in a place where OpenVMS expects it
semanage fcontext -a -t public_content_rw_t "/icsis/win(/.*)?" tell SELinux that this location is sanctioned for read+write
restorecon -F -R -v /icsis/win necessary voodoo (copies info from SELinux back to the file system)
setsebool -P ftpd_anon_write 1 an optional "hall pass"

At this point the attached USB-DISK can be written to via FTP

Project #2 :: need one directory write-enabled for use by Apache/HTTPd

  • I was working a Python demo (named: save_file.py) which shows how to present "a file browser" then implements an "upload". Now I should mention that everything is set up properly as far as UNIX-Linux file protections are concerned but SELinux was "helping" to keep my system secure so did not allow it.
  • my python script is trying to write to this folder: /var/www/tmp
  • here's how things looked originally (note: to view SELinux info we append an uppercase "Z" onto the switches of the "ls" command)
    [root@kawc4n www]# pwd
    /var/www
    [root@kawc4n www]# ls -laZ
    drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 .
    drwxr-xr-x. root root system_u:object_r:var_t:s0       ..
    drwxrwxrwx. root root system_u:object_r:httpd_sys_script_exec_t:s0 cgi-bin
    drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_rw_content_t:s0 click_log
    drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_content_t:s0 css
    drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_content_t:s0 documents
    -rwxrwxrwx. root root unconfined_u:object_r:httpd_sys_content_t:s0 favicon.ico
    drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_content_t:s0 fonts
    drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_content_t:s0 fragments
    drwxrwxrwx. root root system_u:object_r:httpd_sys_content_t:s0 html
    drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_content_t:s0 images
    drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_content_t:s0 js
    drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_content_t:s0 mam
    drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_content_t:s0 tmp
    [root@kawc4n www]# 
  • here are my SELinux commands along with the changes
    [root@kawc4n www]# pwd
    /var/www
    [root@kawc4n www]# semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/tmp(/.*)?"
    [root@kawc4n www]# restorecon -R -v /var/www/tmp
    [root@kawc4n www]# ls -laZ
    drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 .
    drwxr-xr-x. root root system_u:object_r:var_t:s0       ..
    drwxrwxrwx. root root system_u:object_r:httpd_sys_script_exec_t:s0 cgi-bin
    drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_rw_content_t:s0 click_log
    drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_content_t:s0 css
    drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_content_t:s0 documents
    -rwxrwxrwx. root root unconfined_u:object_r:httpd_sys_content_t:s0 favicon.ico
    drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_content_t:s0 fonts
    drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_content_t:s0 fragments
    drwxrwxrwx. root root system_u:object_r:httpd_sys_content_t:s0 html
    drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_content_t:s0 images
    drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_content_t:s0 js
    drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_content_t:s0 mam
    drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_rw_content_t:s0 tmp
    [root@kawc4n www]# 
  • Now my python script works properly (yay!)

Project #3 which is really a FUBAR

  • If you are using rsync (or tar) to do live backups then you had better add switches to also copy meta-data which also includes SELinux information.
  • with rsync you need to use either "-X" or "--xattrs"
  • see this example: linux_notes: rsync

External Links


 Back to Home
Neil Rieck
Waterloo, Ontario, Canada.