Abstract |
This document covers the installation and configuration of Fedora Core 1/2 RPM packages for Apache on Fedora Core. |
In the past, I had a lot of gripes about the Apache packages supplied by Red Hat : it seemed to defy my attempts at integrating it with Tomcat (although other individuals did not seem to have the same problems), and it seemed to stay at version 2.0.40 for the longest time, even after the tarballs supplied by Apache moved several versions ahead.
With Fedora Core 1, I was pleasantly surprised by how easy it was to install Apache 2 and enable SSL on it. The layout of the various files seemed very logical (another surprise), and the scripts supplied with the packages made creating certificates and setting yourself up as a CA (Certificate Authority) a breeze. The only drawback I can think of is that I'm pretty sure the packages would not work with other distributions.
With Fedora Core 2, the same ease of use is there. Performance has improved, or so I have heard, because of the improvements in the 2.6 kernel.
Red Hat used to ship only one version of Apache, and then issue patches on their website. With Fedora, they seemed to be (finally) tracking the release cycles of the Apache HTTP Server Project. The version bundled with Fedora Core 2 is 2.0.49, but these instructions should still be applicable to previous versions of Apache 2.x.
If you did a full install of Fedora Core 1, the packages should be already available. If, like me, you normally do a Minimal Install, then add components, you will need to download the following packages from the Fedora download site or its mirrors:
httpd-2.0.49-4.i386.rpm
httpd-devel-2.0.49-4.i386.rpm
httpd-manual-2.0.49-4.i386.rpm
The Apache packages do not include additional modules, such as SSL and perl. If you need these or other modules, you will need to download the appropriate RPM packages, such as:
mod_ssl-2.0.49-4.i386.rpm
mod_perl-1.99_12-2.1.i386.rpm
mod_perl-devel-1.99_12-2.1.i386.rpm
mod_dav_svn-1.0.2-1.i386.rpm
If you require php, you will also need to download the php packages.
These instructions were last tested on Fedora Core 2. I have tested these instructions on Fedora Core 1, and if you are still using it, you can try to follow along. I do not believe that these instructions will work on other Linux distributions, however. If it does on yours, please let me know.
This is a relatively simple process. You can either download the packages from the Fedora site and install as follows:
# rpm -ivh httpd-2.0.49-4.i386.rpm # rpm -ivh httpd-devel-2.0.49-4.i386.rpm # rpm -ivh httpd-manual-2.0.49-4.i386.rpm |
You will want to check if there are any updates available for these packages on the Fedora Updates directory. You should be able to upgrade the packages like so:
# rpm -Uvh httpd-2.0.xx-xx.i386.rpm # rpm -Uvh httpd-devel-2.0.xx-xx.i386.rpm # rpm -Uvh httpd-manual-2.0.xx-xx.i386.rpm |
A much simpler way is to install yum or apt-get, which will automatically resolve dependencies for you. You can find information about yum here. If your yum updates seems slow, look at the information here.
A yum installation of httpd looks like this:
# yum install httpd httpd-devel httpd-manual |
For information on apt-get see this page.
If your installation completed without errors, Apache should be able to startup and serve pages. To test your installation, execute the following command as root:
# service httpd start |
Now, open your browser and point to http://localhost. You should see a welcome page.
The RPM packages are a little different from the standard Apache tarball. For example, if you were using the standard tarball, you would find that all configuration directives are contained inside httpd.conf. For the RPM package, you would find that SSL configuration exists as a separate configuration file, ssl.conf.
In my opinion, this is a good thing because it promotes modularity and is easier to find the appropriate places where you would add directives or make changes. The downside of this is, of course, that instructions in existing HOW-TOs and books dealing with Apache would need to be adapted to the different file layout.
The Apache configuration remains in httpd.conf, and the directory where you can find it is /etc/httpd/conf. I will not be covering the directives for this file, but you can find out more about them from the Apache manual or other books and documentation on this subject. Additional configuration files, if you are installing modules, can be found in /etc/httpd/conf.d directory.
The "executable file" is httpd and it can be found inside /usr/sbin. There is also an apachectl script in the same directory, for those who are more accustomed to the traditional way of starting and stopping Apache.
The RPM package automatically installs a startup script in /etc/init.d, but Apache does not start on boot by default. You will need to use chkconfig to enable this.
Log files can be found in /etc/httpd/logs. There are 2 log files created : access_log and error_log.
Your web pages should go into /var/www/html directory. This is the default DocumentRoot. Interestingly though, for a default RPM installation, there are no files in that directory. The default page that is served up after install is /var/www/error/noindex.html. The configuration file that controls this is /etc/httpd/conf.d/welcome.conf.
A lot of people think that SSL is something that "automagically" protects your server. Some people expect a login prompt when a server is configured for SSL operation. SSL is more complex than that, and if you are one of these people, please refer to the links in the References section before continuing.
Getting SSL to work on Apache is surprisingly easy for the Apache RPM packages because of the supplied scripts. I will not be covering the theory behind SSL and web server security in this document. Instead, I will merely give the steps I took to get SSL installed and working for my Apache installation.
But first, let me explain the scenario I will be covering :
There are actually several different ways SSL can be configured. You could order and pay for a CA certificate, server certificate and server private key from a trusted CA (Certificate Authority) institution, such as Verisign. If you do not want to spend the money, you could set yourself up as a Certificate Authority. (Note : If you do not understand what certificates are, and how they relate to SSL, I strongly recommend that you read the links in the References section) If you are going to be running a public website, it would be a good idea to purchase your certificates from Verisign, especially if you are handling transactions. If you are running a private intranet or extranet server, you could get by with just setting yourself up as a CA, but you really should consider the Verisign option.
For this section, I shall be setting myself up as a Certificate Authority (CA), and generating my own server key and certificate.
You will need the following components installed along with your base Apache RPM packages
mod_ssl-2.0.48-1.2
openssl-0.9.7a-23
openssl-devel-0.9.7a-23
Look inside the directory /usr/share/ssl/ for a file named openssl.cnf and open it in your favorite editor. You will need to look for and change the following values in the file:
countryName_default: put the name of your country
stateOrProvinceName_default: put the name of your state or province
localityName_default: put the name of your locality (street? region?)
0.organizationName_default: put the default organization name
organizationalUnitName_default: put your organization unit (OU) name
You don't actually need to do the above step, but it can be very useful later on, when you are generating your certificates, because you have already setup your defaults here.
There is a supplied CA script inside the directory /usr/share/ssl/misc/ that you can use to generate your certificate. To begin generating your certificate, simply execute the following commands:
[root@localhost root]# cd /usr/share/ssl/misc [root@localhost misc]# ./CA -newca |
Press ENTER to create the new certificate and you will be prompted to key-in a passphrase. You will need to use this passphrase later, so you should remember what you keyed in here. Then you will be prompted for the particulars of your organization, etc. If you edited the openssl.cnf file properly in the previous step, you should be able to just hit ENTER for all the options except your server host name. A sample session is shown below. In this session, I am generating a CA certificate for my local Fedora Core 1 workstation:
[root@localhost misc]# ./CA -newca CA certificate filename (or enter to create) Making CA certificate ... Generating a 1024 bit RSA private key ..++++++ ............++++++ writing new private key to './demoCA/private/./cakey.pem' Enter PEM pass phrase: Verifying - Enter PEM pass phrase: ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [SG]: State or Province Name (full name) [Singapore]: Locality Name (eg, city) [Singapore]: Organization Name (eg, company) [Cymulacrum, Pte Ltd]: Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []: localhost.localdomain Email Address []: [email protected] |
To create a CSR, we will use the same CA script, but with a different switch.
[root@localhost misc]# ./CA -newreq Generating a 1024 bit RSA private key ...++++++ ................++++++ writing new private key to 'newreq.pem' Enter PEM pass phrase: Verifying - Enter PEM pass phrase: ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [SG]: State or Province Name (full name) [Singapore]: Locality Name (eg, city) [Singapore]: Organization Name (eg, company) [Cymulacrum, Pte Ltd]: Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []: localhost.localdomain Email Address []: [email protected] |
You see how useful creating or editing the template file is ? If you did not set the defaults, you'd have to key in the same information all over again.
You will be prompted for extra attributes, a challenge password and an optional company name. If you don't need any of this, you can safely ignore these messages and just hit ENTER.
Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: Request (and private key) is in newreq.pem |
Note the last line, which states that your CSR has been created, and is called newreq.pem in the current directory.
If you have gotten this far without any errors, you can now sign the CSR. To do that, we will use the CA script again, but, again, with a different switch.
[root@localhost misc]# ./CA -sign |
You will be prompted for your passphrase, and then information about your certificate will spew out on the screen. You should see something like what is shown below. I have omitted some information that comes up after the particulars of your organization.
Using configuration from /usr/share/ssl/openssl.cnf Enter pass phrase for ./demoCA/private/cakey.pem: Check that the request matches the signature Signature ok Certificate Details: Serial Number: 1 (0x1) Validity Not Before: Feb 7 06:15:19 2004 GMT Not After : Feb 6 06:15:19 2005 GMT Subject: countryName = SG stateOrProvinceName = Singapore localityName = Singapore organizationName = Somewhere, Pte Ltd commonName = localhost.localdomain emailAddress = [email protected] |
You will then be asked to sign the certificate and commit the changes.
Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y |
Information about your signed certificate will then be dumped to screen. Note the validity dates of the certificate.
At the end of the information dump, you will be told that the certificate filename is newcert.pem, and can be found in the current directory.
-----END CERTIFICATE----- Signed certificate is in newcert.pem |
Finally, we will create a directory and copy the newly created certificates to the new directory.
[root@localhost var]# mkdir myCA [root@localhost var]# cd myCA [root@localhost myCA]# cp /usr/share/ssl/misc/demoCA/cacert.pem . [root@localhost myCA]# cp /usr/share/ssl/misc/newcert.pem ./servercert.pem [root@localhost myCA]# cp /usr/share/ssl/misc/newreq.pem ./serverkey.pem [root@localhost myCA]# ls cacert.pem servercert.pem serverkey.pem |
We will now need to copy the certificates and keys to a directory where Apache can access it. For simplicity, we will overwrite the default certificates that come with the mod_ssl RPM package.
[root@localhost myCA]# cd /var/myCA [root@localhost myCA]# cp servercert.pem /etc/httpd/conf/ssl.crt/server.crt cp: overwrite `/etc/httpd/conf/ssl.crt/server.crt'? y [root@localhost myCA]# cp serverkey.pem /etc/httpd/conf/ssl.key/server.key cp: overwrite `/etc/httpd/conf/ssl.key/server.key'? y |
Now, we enable SSL operations for Apache. Open ssl.conf for editing and uncomment and edit the following directives:
DocumentRoot
ServerName
ServerAdmin
You may want to change DocumentRoot to point to another directory, such as /var/www/ssl, and place your SSL files inside there instead.
To test your SSL configuration, create a simple HTML file, name it index.html and place it inside the DocumentRoot directory defined above.
Finally, we are ready to test our new SSL_enabled Apache web server. Start Apache. You will be asked to key in your passphrase. Enter your passphrase and observe that Apache 2 starts up. Open a browser and try to go to the URL https://localhost or http://localhost:443. If you have already created an index.html inside your DocumentRoot for your SSL configuration, you should see that page open up, but not before you get a certificate warning in your browser. If you see the certificate warning, it means that you have successfully setup Apache for SSL operations. Congratulations!
Sometimes, the passphrase prompt can be inconvenient, especially when you want Apache to startup automatically on boot, without user intervention. We can disable the passphrase prompt by simply de-crypting the server key. To do this, we begin by making a copy of the server keyfile, then run the following command to decrypt it:
# cd /etc/httpd/conf/ssl.key # cp server.key server.bak # openssl rsa -in server.bak -out server.key |
I always run a local copy of Apache on my laptop. Previously, it was because I needed to keep my Java API documentation handy, in case I needed to look up something. More recently, because the variety of my work has increased, I find that I have to include my bookmarks on a "home page".
Generating bookmarks from Mozilla is easy, it can be exported into a HTML page, named --quite logically-- "bookmarks.html". The problem is, how do I add the content of that generated page to my local home page?
With Server Side Includes (SSI), you can include other HTML pages inside one web page. You can even generate some dynamic content, such as adding a "Last Modified" field on the page or printing environment variables. This section explains how to enable SSI on your Apache server.
If you are using a clean install of Apache from the Fedora Core RPM packages, SSI is not enabled by default. To begin, open /etc/httpd/conf/httpd.conf and locate this line :
<Directory "/var/www/html"> |
Directly under that line is a stanza describing the Options directive that immediately follows. Simply add "Includes" to the end of the Options directive like so,
Options Indexes FollowSymLinks Includes |
Next, look for this line:
AddType text/html .shtml |
It should be uncommented by default. If it is commented out, simply uncomment it. That's all ! Files with the extension .shtml are SSI files. If you wish to use an .shtml file as the default page for your website or directory, you will need to make one more change. Locate the DirectoryIndex directive and add index.shtml to it, like so :
DirectoryIndex index.html index.html.var index.shtml |
I will not be covering SSI syntax on web pages here, because it can get quite involved. In the References section, I have included a couple of links that can help you get started on SSI coding for your web pages.
There are already a lot of articles on this subject on the Internet. The reason why I am writing this is, there were a few small but significant details that were missed in all the articles I came across.
We will be setting up name-based virtual hosts, that is, we will have a single Apache instance serving web pages for several different domains, but using the same IP address.
Suppose we want to setup 2 virtual domains, companyABC.com and companyDEF.com. We begin by setting up directories to store the web pages for these 2 domains:
[root@localhost root]$ mkdir -p /var/www/co_abc [root@localhost root]$ mkdir -p /var/www/co_def |
Next, we should create some dummy web pages for both directories, so that we can test later. Just create a simple HTML page that shows "Hello World" and save it to each of the directories.
We will now open /etc/httpd/conf/httpd.conf. Locate the section on virtual hosts and you should see an example that is already commented out. The Virtual Host section begins with this line:
### Section 3: Virtual Hosts |
Instead of telling you which lines to uncomment, I'm going to show you below, the stanzas to add to the Virtual Host section to get companyABC.com and companyDEF.com websites running:
# # Use name-based virtual hosting. # NameVirtualHost 127.0.0.1:80 NameVirtualHost 127.0.0.1:443 <VirtualHost 127.0.0.1:80> ServerName localhost DocumentRoot /var/www/html DirectoryIndex index.html index.shtml </VirtualHost> <VirtualHost 127.0.0.1:80> ServerName companyABC.com DocumentRoot /var/www/co_abc ErrorLog /var/log/httpd/abc_error_log CustomLog /var/log/httpd/abc_access_log common DirectoryIndex index.html index.shtml <Directory "/var/www/co_abc"> Options Indexes FollowSymLinks Includes AllowOverride None Order allow,deny Allow from all </Directory> </VirtualHost> <VirtualHost 127.0.0.1:80> ServerName companyDEF.com DocumentRoot /var/www/co_def ErrorLog /var/log/httpd/def_error_log CustomLog /var/log/httpd/def_access_log common DirectoryIndex index.html index.shtml <Directory "/var/www/co_def"> Options Indexes FollowSymLinks Includes AllowOverride None Order allow,deny Allow from all </Directory> </VirtualHost> |
Notice that in the firsst 2 uncommented lines, I specified "NameVirtualHost" followed by the IP address and the port number. The IP address used here is the localhost loopback address. Substitute that with your server's network IP address. The port numbers *must* be specified, especially if you have name-based virtual hosts listening on more that one IP address or on port addresses other than port 80. You will need one "NameVirtualHost" directive for each virtual host listening on a different port.
Next, notice that I defined 3 <VirtualHost> stanzas, one for "localhost" which uses the default directory /var/www/html, one for companyABC.com and one for companyDEF.com. It is also necessary for each name virtual host to have a separate stanza here, including the default host (if you want it to be accessible).
Finally, notice that for each stanza, I defined separate log files for each domain. I think this is a good idea, instead of lumping them all together, because this can help with troubleshooting.
After you have added the stanzas, save the file. At this point, you will need to add the appropriate records to your DNS server to make these domains reachable by anyone on the network. If you have no access to a DNS server, or you just want to test the configuration, just edit your /etc/hosts file. Here is what my file looks like:
# Do not remove the following line, or various programs # that require network functionality will fail. 127.0.0.1 localhost.localdomain localhost 127.0.0.1 companyABC.com 127.0.0.1 companyDEF.com |
After you have made the changes, save the file, and you're ready to test. Just start Apache up, open a browser and try to open http://companyABC.com. You should see your test page. Try for http://companyDEF.com as well. If everything works, then congratulations ! Pretty simple, huh ?
Suppose that we want to redirect all requests to a certain URL to another URL. We can implement it programatically by writing a HTML page with a Javascript redirect, or we could use Apache's Redirect function.
This is actually a very involved topic, so what I will provide here is actually a very simple example to help you get started. If you are going to be writing complex redirects, you will need an in-depth understanding of regular expressions. Because I do not have that, I will just cover something simple.
Say that you want to redirect all requests to http://domain.com/premium/ to https://domain.com/registered. Here's what you will need inside your httpd.conf
RewriteEngine on RewriteCond %{SERVER_PORT} ^80$ RewriteRule ^/premium(.*)$ https://localhost/registered$1 [L,R] |
These three lines go inside your <VirtualHost> stanza. Here's what mine looks like:
<VirtualHost 127.0.0.1:80> ServerName localhost DocumentRoot /var/www/html DirectoryIndex index.html index.shtml RewriteEngine on RewriteCond %{SERVER_PORT} ^80$ RewriteRule ^/premium(.*)$ https://localhost/registered$1 [L,R] RewriteLog "/var/log/httpd/rewrite.log" RewriteLogLevel 4 </VirtualHost> |
Notice that I defined a log file and log level for this rewrite rule, and that it rewrites to an SSL-enabled URL.
You can test your new redirect rule by opening a browser and trying to go to http://localhost/premium. You should be automatically redirected to the SSL part of Apache.
Not clear about SSL ? Here are some links to get you started.
This is a very good introduction to the issues SSL is supposed to solve, encryption and certificates. It's written by Netscape, the originator of the SSL spec.
Another excellent writeup from Netscape. SSL concepts are illustrated by a scenario.
Want to know more about how Apache uses SSL to secure communications? Read this.
Some useful links about SSI and SSI syntax
This page has several useful links on SSI. This can be a good starting point if you are new to SSI.
This site has an excellent tutorial on SSI directives. Read this if you do HTML coding and want to use SSI.
Concise introduction to SSI configuration and directives, including brief explanation of XSSI.