Files permissions on the Apache server is tightly linked with two configuration parameters in the Apache server configuration file (httpd.conf). These are the User and Group configuration parameters that set the (User ID) UID and (Group ID) GID of the httpd binary. In the default configuration file (default /etc/httpd/conf/httpd.conf in RedHat Linux) we have following:
#
# If you wish httpd to run as a different user or group, you must run
# httpd as root initially and it will switch.
#
# User/Group: The name (or #number) of the user/group to run httpd as.
# . On SCO (ODT 3) use "User nouser" and "Group nogroup".
# . On HPUX you may not be able to use shared memory as nobody, and the
# suggested workaround is to create a user www and use that user.
# NOTE that some kernels refuse to setgid(Group) or semctl(IPC_SET)
# when the value of (unsigned)Group is above 60000;
# don't use Group #-1 on these systems!
#
User apache
Group apache
# If you wish httpd to run as a different user or group, you must run
# httpd as root initially and it will switch.
#
# User/Group: The name (or #number) of the user/group to run httpd as.
# . On SCO (ODT 3) use "User nouser" and "Group nogroup".
# . On HPUX you may not be able to use shared memory as nobody, and the
# suggested workaround is to create a user www and use that user.
# NOTE that some kernels refuse to setgid(Group) or semctl(IPC_SET)
# when the value of (unsigned)Group is above 60000;
# don't use Group #-1 on these systems!
#
User apache
Group apache
In the above configuration, the User and Group are set to 'apache'. The httpd binary should start as root, since only a root user can change the user and group in runtime. httpd binary as user 'root' binds to port 80 (443 for https), or to an alternative port defined in the configuration file. Then, it creates child processes with the User and Group as defined in the configuration file. Running the service httpd, and listing the httpd processes we have:
[root@localhost ~]# ps -ef | grep httpd
root 22680 1 0 11:19 ? 00:00:00 /usr/sbin/httpd
apache 22682 22680 0 11:19 ? 00:00:00 /usr/sbin/httpd
apache 22683 22680 0 11:19 ? 00:00:00 /usr/sbin/httpd
apache 22684 22680 0 11:19 ? 00:00:00 /usr/sbin/httpd
apache 22685 22680 0 11:19 ? 00:00:00 /usr/sbin/httpd
apache 22686 22680 0 11:19 ? 00:00:00 /usr/sbin/httpd
apache 22687 22680 0 11:19 ? 00:00:00 /usr/sbin/httpd
apache 22688 22680 0 11:19 ? 00:00:00 /usr/sbin/httpd
apache 22689 22680 0 11:19 ? 00:00:00 /usr/sbin/httpd
root 22680 1 0 11:19 ? 00:00:00 /usr/sbin/httpd
apache 22682 22680 0 11:19 ? 00:00:00 /usr/sbin/httpd
apache 22683 22680 0 11:19 ? 00:00:00 /usr/sbin/httpd
apache 22684 22680 0 11:19 ? 00:00:00 /usr/sbin/httpd
apache 22685 22680 0 11:19 ? 00:00:00 /usr/sbin/httpd
apache 22686 22680 0 11:19 ? 00:00:00 /usr/sbin/httpd
apache 22687 22680 0 11:19 ? 00:00:00 /usr/sbin/httpd
apache 22688 22680 0 11:19 ? 00:00:00 /usr/sbin/httpd
apache 22689 22680 0 11:19 ? 00:00:00 /usr/sbin/httpd
and we have the following open tcp port:
[root@localhost ~]# netstat -na -tcp | grep httpd
tcp 0 0 :::80 :::* LISTEN 22680/httpd
tcp 0 0 :::443 :::* LISTEN 22680/httpd
tcp 0 0 :::80 :::* LISTEN 22680/httpd
tcp 0 0 :::443 :::* LISTEN 22680/httpd
The above shows a httpd daemon process with pid 22680 running as root, and a number of child httpd processes running owned by the 'apache' user. This is common practice in the Apache configuration, since we do not want the child processes to have the same privileges as root. Apache documentation states that the configured user and group ('apache' in the above example), should not own any content on the server.
Let us check that a script run by the httpd daemon has 'apache' user id. The following perl script is used, and placed /var/www/cgi-bin folder (default configuration):
#!/usr/bin/perl
my $whoiami=`whoami`;
print "\n$whoiami";
exit
my $whoiami=`whoami`;
print "\n$whoiami";
exit
Running this script from the web browser gives:
apache
The above means that the process that run this script on the Apache server is owned by 'apache'. This is in concordance with the configuration file we have.
Looking at the file permission of the Perl script file, we have:
cgi-scripts file permissions
Looking at the file permission of the Perl script file, we have:
[root@localhost cgi-bin]# ls -l -rwxr-xr-x 1 root root 124 Oct 31 11:50 test.pl
This shows that the file is owned by root, and is part of the root group. The owner has read-write-execute privileges. The group and all users have read-execute privileges. Usually, we want server users to be able to modify script files without having 'root' privileges. Also, we need to disable read and execute privileges of the all users. We achieve this by using groups. Lets assume we want the user 'Alice' to be able to edit this file. For this purpose, we create a group 'webcontent' and add user 'Alice' to this group as follows:
[root@localhost]# groupadd webcontent
We need to add the 'apache' user to the 'webcontent' group as well, because the user 'apache' needs to be able to run this script
[root@localhost]# usermod -G web-content alice
[root@localhost]# usermod -G web-content apache
[root@localhost]# usermod -G web-content apache
Now we need to set the correct permissions to the script file:
[root@localhost cgi-bin]# chmod 750 test.pl
If for any reason the script does not run, check Apache server error log file. If you notice something like the following:
[Fri Nov 01 10:24:11 2013] [error] [client xxx.xxx.xxx.xxx] (13)Permission denied: exec of '/var/www/cgi-bin/test.pl' failed
then the file permissions are set wrong for the given script. Review the steps above and set your file permission correctly.
References
Apache Tutorial: Dynamic Content with CGI
No comments:
Post a Comment