Category Archives: Web Server Configuration

Apache SSL Server on CentOS

After getting Apache running on Ubuntu, I also got Apache running in CentOS 6.3.  This went as smoothly as it did on Ubuntu.  The following are the steps I took to get it running.  As usual, CentOS was installed as a VM under VMWare player.

Unlike with Ubuntu, Apache comes pre-installed on CentOS and so all that was required to get it running was to start the httpd daemon and configure it to start when the server is booted:

# /etc/init.d/httpd start
# chkconfig --levels 235 httpd on

To implement SSL, the same steps as under Ubuntu were required. First I installed OpenSSL and generated the key and self signed certificate:

# yum install mod_ssl openssl
# openssl genrsa -out ca.key 2048
# openssl req -new -key ca.key -out ca.csr
# openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt

Of course for a real web site, the contents of the csr file is sent to a Certificate provider (Verisign, GeoTrust, etc.) who would then return the certificate to be included in the ca.crt file.  The steps below are then followed as shown.

I then moved the files to the correct location:

# cp ca.crt /etc/pki/tls/certs
# cp ca.key /etc/pki/tls/private/ca.key
# cp ca.csr /etc/pki/tls/private/ca.csr

Edited ssl.conf and updated the following two lines with the new key and certificate:

SSLCertificateFile /etc/pki/tls/certs/ca.crt
SSLCertificateKeyFile /etc/pki/tls/private/ca.key

I then restarted httpd.  This allowed the local browser to access the web page via SSL  http worked with ipv6 without any special configuration. https had issues because the browser could not “obtain identification status for the site.” and therefore would not allow me to add the exception.  I fixed this by adding an entry in the /etc/hosts file with a name that matched the certificate:

192.168.239.138 www.ssltest.com
fdc1:b20c:c011:1:20c:29ff:fe1d:635f www6.ssltest.com

Finally, I created a test index file under: /var/www/html/vhosts/ssltest.com/httpdocs and edited /etc/httpd/conf/httpd.conf to have a virtual host www.ssltest.com:

NameVirtualHost *:80
NameVirtualHost *:443

<VirtualHost *:80>
     DocumentRoot /var/www/html
     ServerName www.localhost.com
     ErrorLog logs/ssltest.com-error_log
</VirtualHost>

<VirtualHost *:80>
     DocumentRoot /var/www/html/vhosts/ssltest.com/httpdocs
     ServerName www.ssltest.com
     ErrorLog logs/ssltest.com-error_log
</VirtualHost>

<VirtualHost *:80>
     DocumentRoot /var/www/html/vhosts/ssltest.com/httpdocs
     ServerName www6.ssltest.com
     ErrorLog logs/ssltest.com-error_log
</VirtualHost>

<VirtualHost *:443>
     SSLEngine on
     SSLCertificateFile /etc/pki/tls/certs/ca.crt
     SSLCertificateKeyFile /etc/pki/tls/private/ca.key
     DocumentRoot /var/www/html
     ServerName www.localhost.com
     ErrorLog logs/ssltest.com-error_log
</VirtualHost>

<VirtualHost *:443>
     SSLEngine on
     SSLCertificateFile /etc/pki/tls/certs/ca.crt
     SSLCertificateKeyFile /etc/pki/tls/private/ca.key
     DocumentRoot /var/www/html/vhosts/ssltest.com/httpdocs
     ServerName www.ssltest.com
     ErrorLog logs/ssltest.com-error_log
</VirtualHost>

<VirtualHost *:443>
     SSLEngine on
     SSLCertificateFile /etc/pki/tls/certs/ca.crt
     SSLCertificateKeyFile /etc/pki/tls/private/ca.key
     DocumentRoot /var/www/html/vhosts/ssltest.com/httpdocs
     ServerName www6.ssltest.com
     ErrorLog logs/ssltest.com-error_log
</VirtualHost>

The first virtual host was added as the default page to answer requests directed to the ip address (for example Error:404 or some such thing.  The error page was placed in the default html directory.   I also added both host entries to my Windows7 workstation and everything worked as expected.

Apache SSL Server

Got a basic web server with ssl running on Apache under Ubuntu 12.04 LTS with a self signed certificate.  Here are the steps I followed:

Installed Apache2:

$  sudo apt-get install apache2

Generated the certificate with openssl:

$ openssl genrsa -out ssltest.key 1024
$ openssl req -new -key ssltest.key -out ssltest.csr
$ openssl x509 -req -days 365 -in ssltest.csr -signkey ssltest.key 
  -out ssltest.cert

Moved the certificates to a dedicated directory:

$ sudo mkdir /etc/apache2/ssl
$ sudo mv /home/cbroccoli/*.cert /etc/apache2/ssl
$ sudo mv /home/cbroccoli/*.key /etc/apache2/ssl
$ sudo chmod 400 /etc/apache2/ssl/*.key (make key read-only)

Created an ssl configuration file for the new site by copying the default file in /etc/apache2/sites-available:

sudo cp /etc/apache2/sites-available/default-ssl /etc/apache2/sites-available/sslsite.ssl

Updated sslsite.ssl with the following lines:

     ServerName sslsite.com 
     ServerAlias *.sslsite.com
     ...
     SSLCertificateFile    /etc/apache2/ssl/ssltest.cert
     SSLCertificateKeyFile /etc/apache2/ssl/ssltest.key

Started the ssl module:

$ sudo a2enmod ssl

Enabled the site:

$ sudo a2ensite sslsite.ssl

Restarted apache:

$ sudo service apache2 reload

I then accessed the site with the IP address and got the error message that the certificate is not secure as expected.

Access via IPv6 required an additional minor configuration for both http and https access to the page.  In the file/etc/apache2/ports.conf, the following lines were added after the respective “Listen” lines which were already included.

Listen [fdc1:b20c:c011:1:20c:29ff:fe27:ec05]:80
...
Listen [fdc1:b20c:c011:1:20c:29ff:fe27:ec05]:443

By default, Apache see the wildcards (*) as only IPv4 addresses, so it needs these extra lines in addition to the lines with the wildcard.

Migration to WordPress and Multi-Site Issues

I finally bit the bullet and have now migrated my site from b2evolution to WordPress.  The b2evolution user interface was far too cumbersome, especially in terms of adding diagrams to my posts.  In WordPress it is just a matter of drag and drop or browse and upload all from within the edit window.  As far as the migration of the posts goes, I could not find easy way to automate the import of the b2evolution data and since I only have 29 posts, I just manually copied and pasted the entries, resetting the dates so that they would appear in the proper chronological order.  All diagrams were on my hard drive so adding them back into the posts was easy.  The whole process took maybe 3 hours.

The bare-bones WP installation normally just allows for a single blog within its base installation.  To get multiple independent blogs, you need to either install WP multiple times or enable networking.  This brought up the following problem,  since I had decided to configure networking and I installed WP in a sub-directory (two important decisions when setting up a site)….

Say you have two blogging sites, Bobs_Blog and Alices_Blog on your main site www.mainsite.com/blogs.  These blogs will be reachable over the following URLs (assuming WP was installed in the blogs sub-directory):

http://www.mainsite.com/blogs/Bobs_Blog/

and

http://www.mainsite.com/blogs/Alices_Blog/

The two sub-directories, /Bobs_Blog and /Alices_Blog do not really exist and are just used as variables for the php scripts in WP to be able to build the web pages dynamically.   So if you now try and point some sub-domains in DNS to these paths, the web browser will not find the directory and fail.  If you add the directories manually, the browser will not be able to find a home or index file (since there really  isn’t one) and give you an error.  For example… if you configure http://bob.mainsite.com to point to www.mainsite.com/blogs/Bobs_Blog/, this will not work.  The server will try and find the Bobs_Blog directory and will fail.

The prescribed solution to this problem is to install MU Domain Mapper plugin and use that to redirect the http requests to the correct location.  Unfortunately the MU Domain Mapper plugin only works if WP is installed in the root directory!

A second idea was to just ask my DNS hosting provider to map a CNAME to the path … for example:

bob.mainsite.com     IN      CNAME     www.mainsite.com/blogs/Bobs_Blog/

Unfortunately, this is not a valid DNS entry 🙁

So the idea I had was to add an index file to the sub-directory which would only redirect the http request to the real site. Based on our example, the index file would have the following php code (taken from http://www.cyberciti.biz/faq/php-redirect/ )…

<?php
/* Redirect browser */
header(“Location: http://www.mainsite.com/blogs/Bobs_Blog/”);
/* Make sure that code below does not get executed when we redirect. */
exit;
?>

When I added a sub-directory called blogs/Bobs_Blog and included this file, I ran into the problem that it created a redirect loop and generated yet another browser error.

The final solution was to create a new independant directory and add the redirect file there.  Then point the DNS sub-domain to this directory and voila… it worked!  The final configuration has http://bob.mainsite.com pointing to www.mainsite.com/blogs/Bobs_Blog_redir/and the sub-directory Bobs_Blog_redir contains an index.php file with the code shown above.  One Caveat… once you connect to the site, the real URL then appears (www.mainsite.com/blogs/Bobs_Blog) and is used throughout.  For me this is not a problem, my goal was to have a simple URL for people to use (and remember).  Once in the site, everything is automated anyway.