Important Contexts

  • The

    httpd_sys_script_exec_t

    type should be used for CGI scripts, allowing the web server to execute the scripts.
  • The

    httpd_sys_script_rw_t, httpd_sys_script_ra_t

    , and

    httpd_sys_script_t

    types are used for files that are only handled by the CGI scripts. These can be read/write, append-only, or read-only.

 

Sequence 1. Enabling a CGI Script in SELinux

  1. Edit the 

    /etc/httpd/conf/httpd.conf

    file and replace the ‘

    ScriptAlias

    ‘ option with the following line:
 

ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"

  1. In the same file, where the configuration of your website (or virtual host) is located, add the following lines:
 

   AllowOverride None

   Options None

   Require all granted

 

  1. Check the configuration file:
 

# apachectl configtest

Syntax OK

  1. Restart the httpd service:
 

# systemctl restart httpd

  1. Create your text Script
 

/var/www/cgi-bin/test.pl.

#!/usr/bin/perl

print "Content-type: text/html\n\n";

print "Testing the Perl Secipt GCI  Script
";

print "..... by Ram N Sangwan";Assign the Permissions

# chmod +x /var/www/cgi-bin/test.pl

  1. By default

    /var/www/cgi-bin

    directory has context
 

“httpd_sys_script_exec_t”. # ls -laZ /var/www/cgi-bin/

# ls -laZ /var/www/cgi-bin/test.pl

  1. Try

    http://server.example.com/cgi-bin/test.pl

    you will receive an error with a message saying you don’t have permission to access the file on the server.
  2. Lets make it work
 

# semanage fcontext -a -t httpd_sys_script_exec_t “/var/www/cgi-bin(/.*)?"

# restorecon -R /var/www/cgi-bin/

# ls -laZ /var/www/cgi-bin/

# ls -laZ /var/www/cgi-bin/test.pl

  1. Just in case you require
 

# getsebool -a | grep httpd_enable_cgi

  httpd_enable_cgi --> on

# setsebool httpd_enable_cgi off

# getsebool -a | grep httpd_enable_cgi

  httpd_enable_cgi --> off

 

Sequence 2. Working with Python based CGI Script

[the_ad id="2469"]

  1. Create the following simple Python-based CGI script in a regular user's home directory:
 

$ mkdir ~/cgi-bin

$ vi ~/cgi-bin/test.py

#!/usr/bin/env python

import sys, time

import subprocess

import cgi, cgitb

cgitb.enable()

print 'Content-Type: text/html;charset=utf-8\n'

PIPE = subprocess.PIPE

STDOUT = subprocess.STDOUT

pd = subprocess.Popen(['ping','-c','1','localhost'], stdout=PIPE, stderr=STDOUT)

while True:

output = pd.stdout.read(1)

if output == '' and pd.poll() != None:

   break

if output != '':

   sys.stdout.write(output)

   sys.stdout.flush()

  1. With this CGI script now available, first launch a simple CGI-capable web server:
 

$ python -m CGIHTTPServer 6020

  1. In a different session, connect to the web server and call the test.py CGI script:
 

$ curl http://localhost:6020/cgi-bin/test.py PING localhost (127.0.0.1) 56(84) bytes of data 64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.002 ms -- localhost ping statistics -- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.002/0.002/0.002/0.000 ms

  1. Now, launch the same CGI-capable web server, but with NNP enabled:
 

$ setpriv --no-new-privs python -m CGIHTTPServer 6020

  1. Again, connect to the web server and call the test.py CGI script:
 

$ curl http://localhost:6020/cgi-bin/test.py ping: icmp open socket: Permission denied

  1. Because Linux's NNP is enabled, the ping command is not able to obtain the higher privileges needed to open the socket.

Sometimes, the SELinux policy doesn't even allow an application to be executed without transitioning. In that case, an execute_no_trans denial will show up:

 

type=AVC msg=audit(1150125191.592:740): avc:  denied     { execute_no_trans } for pid=2793 comm="pipe"   name="PostFix.mail.SpamAssassin.spamfilter.sh" dev=md9 ino=56842   scontext=system_u:system_r:postfix_pipe_t:s0   tcontext=system_u:object_r:ql_spamassassin_client_exec_t:s0    tclass=file permissive=0