
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
- Edit the /etc/httpd/conf/httpd.conffile and replace the ‘ScriptAlias‘ option with the following line:
ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
- In the same file, where the configuration of your website (or virtual host) is located, add the following lines:
<Directory "/var/www/cgi-bin"> AllowOverride None Options None Require all granted </Directory>
- Check the configuration file:
# apachectl configtest Syntax OK
- Restart the httpd service:
# systemctl restart httpd
- 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 <br \>"; print "..... by Ram N Sangwan";Assign the Permissions # chmod +x /var/www/cgi-bin/test.pl
- 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
- 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.
- 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
- 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
- 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()
- With this CGI script now available, first launch a simple CGI-capable web server:
$ python -m CGIHTTPServer 6020
- 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
- Now, launch the same CGI-capable web server, but with NNP enabled:
$ setpriv --no-new-privs python -m CGIHTTPServer 6020
- 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
- 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
0 responses on "CGI scripts and SELinux"