Hi – Welcome back to the Ubuntu Apache LAMP Server Quick Howto. This second part of the series will cover configuring SSL for use with Apache for securing website content. SSL stands for Secure Sockets Layer, and is a method of providing transport layer encryption or TLS (transport layer security). SSL typically uses X.509 digital certificates to perform authentication and encryption functions. X.509 is based on public key infrastructure or PKI. PKI is beyond the scope of this article (sounds like a good topic for a future article), but we will at least create a self-signed certificate for instructional purposes here.
SSL adds a few caveats to Apache configuration. One of those is name based virtual hosting. SSL does not allow the use of name based virtual hosts. From the apache SSL/TLS Strong Encryption Guide:
Name-Based Virtual Hosting is a very popular method of identifying different virtual hosts. It allows you to use the same IP address and the same port number for many different sites. When people move on to SSL, it seems natural to assume that the same method can be used to have lots of different SSL virtual hosts on the same server.
It comes as rather a shock to learn that it is impossible.
The reason is that the SSL protocol is a separate layer which encapsulates the HTTP protocol. So the SSL session is a separate transaction, that takes place before the HTTP session has begun. The server receives an SSL request on IP address X and port Y (usually 443). Since the SSL request does not contain any Host: field, the server has no way to decide which SSL virtual host to use. Usually, it will just use the first one it finds, which matches the port and IP address specified”
My experience is that Apache will reject the configuration if you attempt to use named based virtual hosts with SSL.
So, with this in mind, if I have multiple “sites” to serve with SSL, I either use different IP addresses for each site, or I serve one site with multiple directories of content that can be referenced by http://<site fqdn>/directory. For example, if I had a site called www.stuff.com and it used SSL, I would add content for different functions/site at https://www.stuff.com/systeminfo or http://www.stuff.com/shopping.
Anyway, so, how do we set up SSL? First thing is to make sure its enabled on your LAMP server. To turn on SSL use the following command:
sudo a2enmod ssl
sudo /etc/init.d/apache2 restart
Also – we should create a specific document root directory for the SSL Apache to use. This way, if you have both SSL and non-SSL sites on the same server, not all the non-ssl sites will be published automatically by the SSL definition.
sudo mkdir /var/www-ssl
Creating a self signed certificate:
In order to use SSL with Apache you must have a certificate. Here is how to make a self signed certificate. Note: Self Signed certs are fine for testing and lab servers, but are not recommended for production environments or internet facing servers.
First, you will need to create a private key file:
sudo openssl genrsa 1024 > host.key
sudo chmod 400 host.key
Next, you will need to create the certificate:
sudo openssl req -new -x509 -nodes -sha1 -days 365 -key host.key > host.cert
After hitting enter, you will be prompted for several pieces of information that will be encoded into the certificate. Here is an example output:
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) [AU]:US
State or Province Name (full name) [Some-State]:Kansas
Locality Name (eg, city) :Topeka
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Test.com
Organizational Unit Name (eg, section) :IT
Common Name (eg, YOUR name) :www.test.com
Email Address :email@example.com
Note, the Common Name should be the fully qualified domain name of your web server. Your cert and key will be in the current directory, and will be called host.cert (cert) and host.key (key). Both of these files will be needed for the next step. As root or using sudo, copy the key file to the /etc/ssl/private directory on your LAMP server, and copy the cert file (host.cert) to the /etc/ssl/certs directory.
Next go to the /etc/apache2/sites-available and edit the default-ssl file. This file controls the default SSL virtual host configuration. We will be modifying the following some the lines in the file. As root, find the beginning stanza in the file (with your favorite editor) and it will look something like this:
<IfModule mod_ssl.c> <VirtualHost _default_:443> ServerAdmin webmaster@localhost DocumentRoot /var/www <Directory /> Options FollowSymLinks AllowOverride None </Directory> <Directory /var/www> Options Indexes FollowSymLinks MultiViews AllowOverride None Order allow,deny allow from all </Directory>
Change the webmaster@localhost to an email address of the person responsible for the server (this isn’t required, but is probably good practice).
Also, you should probably add a ServerName directive right after the ServerAdmin directive. The ServerName directive should reflect the fully qualified domain name as the server.
The DocumentRoot directive should be changed to /var/www-ssl – the directory we made earlier. Lastly, the Directory /var/www directive should be changed to Directory /var/www-ssl.
Here is the same code snip, modified for a server called www.test.com:
<IfModule mod_ssl.c> <VirtualHost _default_:443> ServerAdmin firstname.lastname@example.org ServerName www.test.com DocumentRoot /var/www-ssl <Directory /> Options FollowSymLinks AllowOverride None </Directory> <Directory /var/www-ssl> Options Indexes FollowSymLinks MultiViews AllowOverride None Order allow,deny allow from all </Directory>
Next, lets find the following couple of lines:
These lines tell Apache where to find the SSL certificate to use for the site. We are going to replace these with the certificate and private key we created earlier. We will change them to read:
Ok – make sure you save your default-ssl file with the changes we have detailed above. After the file is saved, run the following command:
Now, its time to test to see if you can connect to the server with SSL. You might want to create an index.html file at the /var/www-ssl directory first though. To do this simply create a file with “It works, SSL!” in it as root and save it to the /var/www-ssl directory with the name of index.html. Afterwards, open Firefox, and go to https://<server name or IP address>. You probably get a certificate error, since we created a self-signed cert for our tutorial. You should tell Firefox to trust the certificate. If all goes well, you should see: It works, SSL! at the top of the page.
If all went well, we should have a working Apache server with SSL. At this point, you can place content directly under /var/www-ssl or in folders under that directory. If you have some folders under the non-ssl Document root (normally /var/www) simply sim-linking those directories to /var/www-ssl will publish them via SSL as well.
So, what if it doesn’t work? Generally, this is the result of either SSL not being enabled, or an errror in your default-ssl file. Double check that you have enabled SSL with the a2enmod command, and make sure the default-ssl file is correct, and that it has been enabled with the a2ensite command. Also note, that when enabling SSL for the first time, make sure you restart Apache with the command:
To make sure SSL support is enabled. You can check that Apache is listening for SSL connection by doing a
and looking for an entry like this:
Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN
If that line is not present, then double check your configuration.
Next time we will focus on the Mysql portion of a LAMP server – look for it soon.
Linux web application servers typically use the Linux/Apache/Mysql/PHP stack. Linux being the OS, Apache the web server layer, Mysql provides the database, and PHP the dynamic HTML/Scripting language. Their is an amazing amount of LAMP based applications out there, so getting to know how to administer a LAMP server is a key skill set for running Linux Application servers.
This first article will focus on installing the LAMP stack on an Ubuntu machine, and administering the Apache web server.
There are a few of concepts I would like to cover first though. One of them seems to escape a lot of people in this space. This is a the concept of name based virtual hosts. Name based virtual hosting is the ability for a web server to serve content based on the URL of the incoming request. This is a method of allowing a single server to serve multiple websites content without needing multiple IP addresses. Essentially the server processes the URL request by matching it against a know set of virtual host definitions. When it matches a URL to a virtual host, it serves content from the directory structure assigned to that virtual host.
The other concept is fully qualified domain names. A fully qualified domain name or FQDN is a hostname containing the host and the domain, including the top level domain suffix. Common top level domains (TLDs) are .gov, .com, .org etc. So an example of a FQDN would be: www.linuxpoweruser.com. The www is the host, and linuxpoweruser.com is the domain, so www.linuxpoweruser.com indicates the host called www in the domain linuxpoweruser.com.
The last concept is how what part of a URL is handled by the domain name system (DNS). DNS is responsible for resolving the part of a URL that is between the http:// and the next / in a URL. If there are no following /’s in a URL than DNS processes all of the URL after the http://. I am a DNS administrator for a large retailer and I am constantly asked to add an entry to add a redirect in DNS to allow, for instance, a URL called http://www.test.com to redirect to http://www.retest.com/test/test.html. Since DNS only handles the “www.test.com” or “www.retest.com” everything after the / in the destination, ie /test/test.html is not handled by DNS, and therefore DNS cannot do this sort of redirection. In this case, I can modify DNS to do a redirect for www.test.com to go to the name www.retest.com (or its corresponding server IP address) but its up to the virtual hosting definition or, a bit of redirect html code to handle the rest. Ok, enough said about that.
First, in order to install the LAMP stack on an Ubuntu system, we need to make sure we install the associated packages:
sudo apt-get install apache2 php5-mysql libapache2-mod-php5 mysql-server php5-gd phpmyadmin
There are some commands that are very useful to control Apache features and served content. The first set of commands will control the availability of Apache features. For instance, you might want to enable home directory public_html serving, which is the ability to serve content from a users public_html folder in their home directory. Content is then accessed at the web browser by going to
http://server ip/~username. To do this, use the a2enmod command:
sudo a2enmod userdir && sudo /etc/init.d/apache2 restart
Other apache modules can be enabled with this a2enmod command. Here is an example that covers server side includes (we will cover server side includes in a later article):
sudo a2mod include && sudo /etc/init.d/apache2 restart
The default document root is /var/www (you need superuser privileges to write in this directory), any files in this directory that are world readable will be accessible by entering the following in a web browser:
http://server ip or name/filename
Anything in a subdirectory below /var/www will appear by appending the directory name to the url. For example, if there is a directory with content at /var/www/mywebsite, it would be accessible with the following url:
http://server/mywebsite/filename where server is the name or IP of your apache server.
New sites can be added by creating site definition files in the /etc/apache2/sites-available directory. Files in this directory are essentially apache configuration files that can be read in or included when apache starts up. This is useful for adding new websites via virtual host definitions, or enabling SSL for your sites.
Edit a new configuration file for the new site :
gksudo gedit /etc/apache2/sites-available/<filename>
Here is an example of a site definition file for adding a directory phpsysinfo as a virtual host on the server, accessible via the sysinfo.rtwsecurenet.com url.
# Possible values for the Options directive are “None”, “All”,
# or any combination of:
# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
# Note that “MultiViews” must be named *explicitly* — “Options All”
# doesn’t give it to you.
# The Options directive is both complicated and important. Please see
# for more information.
#-Indexes disables directory browsing +Includes turns on SSI
Options -Indexes FollowSymLinks +Includes
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be “All”, “None”, or any combination of the keywords:
# Options FileInfo AuthConfig Limit
# Controls who can get stuff from this server.
Allow from all
#add this to allow for different default page names
DirectoryIndex index.html index.shtml index.php
Note :80 in VirtualHost statement – needed if running combination of ssl and non-ssl sites. We will break down the components of this file later.
To enable the new site use the a2ensite command:
sudo a2ensite <sitename> && sudo /etc/init.d/apache2 restart
Later, if you would like to disable that site, you can use the a2dissite command to remove the site:
sudo a2dissite <sitename> && sudo /etc/init.d/apache2 restart
Note, that if the site content is at /var/www or a directory below it, you do not have to create a site file. The site file is only used to include other directories other than what is below /var/www or to create virtual hosts for making content available at a specific host name.
So what is happening with this a2ensite/a2dissite commands? Essentially, a2ensite makes symbolic links in the /etc/apache2/sites-enabled/ directory for the appropriate file/site being enabled (from the /etc/apache2/sites-available directory). The a2dissite command simply deletes the symbolic links.
Beware of some web applications that install themselves outside of the normal /var/www and /etc/apache2/sites-available directory structures. An example comes to mind: phpmyadmin. Phpmyadmin is a php based tool for administering Mysql servers. Phpmyadmin on ubuntu does not install in the /var/www folder. Instead it installs in /usr/share/phpmyadmin. It also stores configuration in /etc/phpmyadmin. In the /etc/phpmyadmin folder there is an apache.conf file. This file is executed when Apache is started, and it includes the /usr/share/phpmyadmin directory in the web servers directory structure, so that it appears at http://servername/phpmyadmin, as if it was a directory under /var/www. How does it do this? Another directory, /etc/apache2/conf.d includes symlinks to files to be included in the apache configuration. Its actually very similar to sites-enabled/available. In /etc/apache2/conf.d/ there is a phpmyadmin.conf that is symlinked to /etc/phpmyadmin/apache.conf. These symlinks are created by apt during package installation.
So, in short we have covered installing the LAMP stack, and controlling Apache’s configuration for serving content. In the next article, we will cover creating Secure Sockets Layer (SSL) websites using apache.