Install apache: yum -y install httpd httpd-manual links
The httpd-manual is a great resource for information, but isn’t needed. The links package is needed for the server-status utilities.
First, let’s create our virtual hosts. We’ll need to create our DocumentRoot directories.
[root@server1 ~]# mkdir /var/www/{server1.example.com,vhost.server1.example.com}
[root@server1 ~]# ls /var/www/
cgi-bin error html icons manual server1.example.com vhost.server1.example.com
Next, you’ll need to edit the /etc/httpd/conf/httpd.conf
[root@server1 ~]# cd /etc/httpd/conf
[root@server1 conf]# vim httpd.conf
[root@server1 conf]# tail httpd.conf
#
NameVirtualHost *:80
DocumentRoot /var/www/server1.example.com
ServerName server1.example.com
DocumentRoot /var/www/vhost.server1.example.com
ServerName vhost.server1.example.com
When you enable virtual hosts in apache, the default website in /var/www/html will not work. You will have to add another virtual host if you want to serve content from that directory. In this configuration, apache will intercept the http headers and look at the destination url and direct traffic based upon that information.
Now that the httpd.conf has been modified, we’ll need to restart apache.
[root@server1 ~]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: [ OK ]
[root@server1 ~]# httpd -S
VirtualHost configuration:
wildcard NameVirtualHosts and _default_ servers:
_default_:8443 server1.example.com (/etc/httpd/conf.d/nss.conf:84)
*:80 is a NameVirtualHost
default server server1.example.com (/etc/httpd/conf/httpd.conf:1011)
port 80 namevhost server1.example.com (/etc/httpd/conf/httpd.conf:1011)
port 80 namevhost vhost.server1.example.com (/etc/httpd/conf/httpd.conf:1015)
Syntax OK
[root@server1 ~]# apachectl status
Not Found
The requested URL /server-status was not found on this server.
----------------------------------------------------------------------
Apache/2.2.15 (CentOS) Server at localhost Port 80
You’ll notice that you can use the ‘httpd -S’ command to show the virtual hosts residing on the server. Let’s create some content to view in the virtual hosts.
[root@server1 ~]# echo "server1.example.com" > /var/www/server1.example.com/index.htm
[root@server1 ~]# echo "vhost.server1.example.com" > /var/www/vhost.server1.example.com/index.htm
Now, let’s try to view the content.
[root@server1 ~]# ping -c 1 server1.example.com
PING server1.example.com (192.168.1.1) 56(84) bytes of data.
64 bytes from server1.example.com (192.168.1.1): icmp_seq=1 ttl=64 time=0.042 ms
--- server1.example.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.042/0.042/0.042/0.000 ms
[root@server1 ~]# ping -c 1 vhost.server1.example.com
PING server1.example.com (192.168.1.1) 56(84) bytes of data.
64 bytes from server1.example.com (192.168.1.1): icmp_seq=1 ttl=64 time=0.028 ms
--- server1.example.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.028/0.028/0.028/0.000 ms
[root@server1 ~]# curl -I server1.example.com
HTTP/1.1 403 Forbidden
Date: Sun, 28 Oct 2012 02:54:16 GMT
Server: Apache/2.2.15 (CentOS)
Accept-Ranges: bytes
Content-Length: 5039
Connection: close
Content-Type: text/html; charset=UTF-8
[root@server1 ~]# curl -I vhost.server1.example.com
HTTP/1.1 403 Forbidden
Date: Sun, 28 Oct 2012 02:54:24 GMT
Server: Apache/2.2.15 (CentOS)
Accept-Ranges: bytes
Content-Length: 5039
Connection: close
Content-Type: text/html; charset=UTF-8
A quick peak at the error_log shows why we can’t view the page(s).
[root@server1 ~]# tail -f /var/log/httpd/error_log
[Sat Oct 27 21:48:58 2012] [notice] SELinux policy enabled; httpd running as context unconfined_u:system_r:httpd_t:s0
[Sat Oct 27 21:48:58 2012] [notice] suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)
[Sat Oct 27 21:48:58 2012] [notice] Digest: generating secret for digest authentication ...
[Sat Oct 27 21:48:58 2012] [notice] Digest: done
[Sat Oct 27 21:48:59 2012] [notice] Apache/2.2.15 (Unix) DAV/2 mod_nss/2.2.15 NSS/3.13.1.0 Basic ECC configured -- resuming normal operations
[Sat Oct 27 21:49:06 2012] [error] [client 127.0.0.1] File does not exist: /var/www/server1.example.com/server-status
[Sat Oct 27 21:54:16 2012] [error] [client 192.168.1.1] Directory index forbidden by Options directive: /var/www/server1.example.com/
[Sat Oct 27 21:54:24 2012] [error] [client 192.168.1.1] Directory index forbidden by Options directive: /var/www/vhost.server1.example.com/
[Sat Oct 27 21:54:56 2012] [error] [client 192.168.1.1] Directory index forbidden by Options directive: /var/www/server1.example.com/
[Sat Oct 27 21:55:06 2012] [error] [client 192.168.1.1] Directory index forbidden by Options directive: /var/www/vhost.server1.example.com/
Notice, that I labeled the index files index.htm. Be default, index.html and index.html.var are the default index pages AND apache, by default, doesn’t print a directory listing as a default index page if a index.html or index.html.var page doesn’t exist. So, to fix this, I had to add index.htm to the “DirectoryIndex” directive in the httpd.conf
#
# DirectoryIndex: sets the file that Apache will serve if a directory
# is requested.
#
# The index.html.var file (a type-map) is used to deliver content-
# negotiated documents. The MultiViews Option can be used for the
# same purpose, but it is much slower.
#
DirectoryIndex index.html index.html.var index.htm
Now, let’s try this again.
[root@server1 ~]# vim /etc/httpd/conf/httpd.conf
[root@server1 ~]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: [ OK ]
[root@server1 ~]#
[root@server1 ~]#
[root@server1 ~]# curl -I server1.example.com
HTTP/1.1 200 OK
Date: Sun, 28 Oct 2012 03:05:43 GMT
Server: Apache/2.2.15 (CentOS)
Last-Modified: Sun, 28 Oct 2012 02:52:13 GMT
ETag: "4d12-14-4cd15a3d274c1"
Accept-Ranges: bytes
Content-Length: 20
Connection: close
Content-Type: text/html; charset=UTF-8
[root@server1 ~]# curl -I vhost.server1.example.com
HTTP/1.1 200 OK
Date: Sun, 28 Oct 2012 03:05:54 GMT
Server: Apache/2.2.15 (CentOS)
Last-Modified: Sun, 28 Oct 2012 02:52:26 GMT
ETag: "4d32-1a-4cd15a49dd342"
Accept-Ranges: bytes
Content-Length: 26
Connection: close
Content-Type: text/html; charset=UTF-8
[root@server1 ~]# curl vhost.server1.example.com
vhost.server1.example.com
[root@server1 ~]# curl server1.example.com
server1.example.com
[root@server1 ~]# ls -Z /var/www/
drwxr-xr-x. root root system_u:object_r:httpd_sys_script_exec_t:s0 cgi-bin
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 error
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 html
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 icons
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 manual
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 server1.example.com
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 vhost.server1.example.com
[root@server1 ~]# ls -Z /var/www/*example.com/
/var/www/server1.example.com/:
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.htm
/var/www/vhost.server1.example.com/:
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.htm
Now, the sites are working. So, let’s go on to the next objective of configuring private directories.
We’ll set up vhost.server1.example.com to create a private directory with.
[root@server1 ~]# htpasswd -cm /var/www/vhost.server1.example.com/.htpasswd james
New password:
Re-type new password:
Adding password for user james
[root@server1 ~]# cat /var/www/vhost.server1.example.com/.htpasswd
james:$apr1$dTUr3R1T$l77COVCwfP0ZKoF05Vq081
[root@server1 ~]# vim /etc/httpd/conf/httpd.conf
[root@server1 ~]# tail -6 /etc/httpd/conf/httpd.conf
AuthType Basic
AuthName "Private"
AuthUserFile /var/www/vhost.server1.example.com/.htpasswd
Require valid-user
[root@server1 ~]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: [ OK ]
[root@server1 ~]# curl -I vhost.server1.example.com
HTTP/1.1 401 Authorization Required
Date: Sun, 28 Oct 2012 03:42:59 GMT
Server: Apache/2.2.15 (CentOS)
WWW-Authenticate: Basic realm="Private"
Connection: close
Content-Type: text/html; charset=iso-8859-1
[root@server1 ~]# curl --user james:testuser vhost.server1.example.com
vhost.server1.example.com
Now, let’s go ahead and set up group managed content, then we’ll deploy a cgi application.
[root@server1 ~]# echo "sysadmin: james user1 user2" > /var/www/vhost.server1.example.com/.htgroup
[root@server1 ~]# cat /var/www/vhost.server1.example.com/.htgroup
sysadmin: james user1 user2
[root@server1 ~]# vim /etc/httpd/conf/httpd.conf
[root@server1 ~]# tail -7 /etc/httpd/conf/httpd.conf
AuthType Basic
AuthName "Private"
AuthUserFile /var/www/vhost.server1.example.com/.htpasswd
AuthGroupFile /var/www/vhost.server1.example.com/.htgroup
Require group sysadmin
[root@server1 ~]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: [ OK ]
[root@server1 ~]# curl -I vhost.server1.example.com
HTTP/1.1 401 Authorization Required
Date: Sun, 28 Oct 2012 03:49:50 GMT
Server: Apache/2.2.15 (CentOS)
WWW-Authenticate: Basic realm="Private"
Connection: close
Content-Type: text/html; charset=iso-8859-1
[root@server1 ~]# curl --user james:testuser vhost.server1.example.com
vhost.server1.example.com
This time, the user ‘james’ was allowed because the user was in the ‘sysadmin’ group. Now the cgi application.
[root@server1 ~]# vim /var/www/cgi-bin/hello.cgi
[root@server1 ~]# chmod +x /var/www/cgi-bin/hello.cgi
[root@server1 ~]# cat /var/www/cgi-bin/hello.cgi
#!/usr/bin/perl
print "Content-type: text/html\r\n\n";
print "Hello!\n";
[root@server1 ~]# curl -I server1.example.com/cgi-bin/hello.cgi
HTTP/1.1 200 OK
Date: Sun, 28 Oct 2012 04:01:36 GMT
Server: Apache/2.2.15 (CentOS)
Connection: close
Content-Type: text/html; charset=UTF-8
[root@server1 ~]# curl server1.example.com/cgi-bin/hello.cgi
Hello!
The last and final objective, though not on the RHCE offical list, it’s a useful tool for working with httpd servers. Setting up the server-status tool.
First, you’ll need to edit the httpd.conf.
#
# Allow server status reports generated by mod_status,
# with the URL of http://servername/server-status
# Change the ".example.com" to match your domain to enable.
#
ExtendedStatus On
SetHandler server-status
Order deny,allow
Deny from all
Allow from 127.0.0.1
[root@server1 ~]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: [ OK ]
[root@server1 ~]# apachectl fullstatus
Apache Server Status for localhost
Server Version: Apache/2.2.15 (Unix) DAV/2 mod_nss/2.2.15 NSS/3.13.1.0
Basic ECC
Server Built: Feb 13 2012 22:31:42
----------------------------------------------------------------------
Current Time: Saturday, 27-Oct-2012 23:07:09 CDT
Restart Time: Saturday, 27-Oct-2012 23:06:51 CDT
Parent Server Generation: 0
Server uptime: 18 seconds
Total accesses: 1 - Total Traffic: 2 kB
CPU Usage: u.08 s.01 cu0 cs0 - .5% CPU load
.0556 requests/sec - 113 B/second - 2048 B/request
1 requests currently being processed, 7 idle workers
__W_____........................................................
................................................................
................................................................
................................................................
Scoreboard Key:
"_" Waiting for Connection, "S" Starting up, "R" Reading Request,
"W" Sending Reply, "K" Keepalive (read), "D" DNS Lookup,
"C" Closing connection, "L" Logging, "G" Gracefully finishing,
"I" Idle cleanup of worker, "." Open slot with no current process
Srv PID Acc M CPU SS Req Conn Child Slot Client VHost Request
GET
0-0 3474 0/1/1 _ 0.09 4 5 0.0 0.00 0.00 127.0.0.1 server1.example.com /server-status
HTTP/1.1
GET
2-0 3476 0/0/0 W 0.00 0 0 0.0 0.00 0.00 127.0.0.1 server1.example.com /server-status
HTTP/1.1
----------------------------------------------------------------------
Srv Child Server number - generation
PID OS process ID
Acc Number of accesses this connection / this child / this slot
M Mode of operation
CPU CPU usage, number of seconds
SS Seconds since beginning of most recent request
Req Milliseconds required to process most recent request
Conn Kilobytes transferred this connection
Child Megabytes transferred this child
Slot Total megabytes transferred this slot
----------------------------------------------------------------------
Apache/2.2.15 (CentOS) Server at localhost Port 80
You can use apachectl status|fullstatus
to get real time statistics of the web server utilization.