Saturday, April 27, 2013

How do I set up Apache virtual hosts on a Debian based Linux machine and configure to support HTTPS?

Preliminary quick note, if you haven't enabled ssh keys between your local machine and your remote machine, I recommend that you do. I just posted a how to on this you can check out here:

Okay, now on to virtual host configuration! Connect to your remote machine (hopefully via ssh keys!):
ssh -p your_port you@your_ip_address
Then run the following command:
sudo mkdir -p /etc/apache2/ssl/
Then run the following command:
sudo openssl req -new -x509 -days 365 -nodes -out /etc/apache2/ssl/ -keyout /etc/apache2/ssl/
You'll see the following output:
Generating a 1024 bit RSA private key
writing new private key to '/etc/apache2/ssl/'
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]: # your input here...
State or Province Name (full name) [Some-State]: # your input here...
Locality Name (eg, city) []: # your input here...
Organization Name (eg, company) [Internet Widgits Pty Ltd]: # your input here...
Organizational Unit Name (eg, section) []: # your input here...
Common Name (eg, YOUR name) []: # your input here...
Email Address []: # your input here...
Now enable ssl within apache:
sudo a2enmod ssl
You'll see the following output:
Enabling module ssl.
See /usr/share/doc/apache2.2-common/README.Debian.gz on how to configure SSL and create self-signed certificates.
Run '/etc/init.d/apache2 restart' to activate new configuration!
We don't need to restart apache at the moment as we still have work to do! Also note, you can open and read the file they recommend and get apache config info straight from the horse's mouth too if you want! Here's a blog post that shows you the content of that file:

While we're at it let's enable apache's mod_rewrite too:
sudo a2enmod rewrite
Again, it's not necessary to restart your server at this time.

Next we're going to set up our virtual hosts. Run the following command:
sudo cp /etc/apache2/sites-available/default /etc/apache2/sites-available/
Then run:
sudo nano /etc/apache2/sites-available/
Update it with your site's info (and set "AllowOverride" to "All" to enable .htaccess files):
<VirtualHost *:80>

        DocumentRoot /home/admin/
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        <Directory /home/admin/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all

        ErrorLog /error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog /access.log combined
Also, be sure to add ServerName and ServerAlias after the ServerAdmin line (so you'll be in a position to host multiple https sites on a single machine).

Now, we need to create almost the exact same thing in the same file but wrap the config settings in <VirtualHost *:443> rather than <VirtualHost *:80>, to do this easily, run the following series of commands:
su root
Then run the following TWO commands as root (we're appending to the new file so we want to run the same command twice):
cat /etc/apache2/sites-available/ >> /etc/apache2/sites-available/new_temp
cat /etc/apache2/sites-available/ >> /etc/apache2/sites-available/new_temp
Then exit from root:
Then replace your old file:
sudo mv /etc/apache2/sites-available/new_temp /etc/apache2/sites-available/
Now open your file for editing:
sudo nano /etc/apache2/sites-available/
Scroll down to the second instance of <VirtualHost *:80> and replace it with:
<VirtualHost *:443>
Now add the following two lines within your :443 settings block:
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/
Next, you need to create your website's document root. I do this by running a git clone. If you don't have git installed on your server or you haven't yet linked your machine with your BitBucket/GitHub account, checkout the following post before continuing (it's easy):

Okay cool, you're back. After checking out that post you should now have your project cloned to your remote machine (i.e. the document root dir referenced in our vhost config file now points to a directory that exists).

Next, we need to edit our ports.conf file:
sudo nano /etc/apache2/ports.conf
Add the following line as depicted in the following image:
NameVirtualHost *:443
Now is a good time to double check and make sure "" points to "your_ip_address" at the DNS level. Once you've double checked that all we need to do is enable our site, disable default, and restart apache:
sudo a2ensite
Output will tell you to run a follow up command. You don't need to at this time. Next run:
sudo a2dissite default
Now restart apache (as opposed to reload):
sudo /etc/init.d/apache2 restart
Badda bing, badda boom! You're up and running with a secure site! Now let's test it!

Put a "test" info.php file inside your project's web root:
echo '<?php phpinfo();' >
Now access via http first and https second. The following screenshots show what you should see!

If your screens look like my screens then you rock! Let's wrap up by removing our test file:
After doing that you're done! You can exit your remote machine.

In a future post we'll be looking at how to add a release management library I wrote called clitools to a CodeIgniter project and doing your first release to your new machine! Stay tuned!

No comments:

Post a Comment

About Me

My photo
I code. I figured I should start a blog that keeps track of the many questions and answers that are asked and answered along the way. The name of my blog is "One Q, One A". The name describes the format. When searching for an answer to a problem, I typically have to visit more than one site to get enough information to solve the issue at hand. I always end up on,, random blogs, etc before the answer is obtained. In my blog, each post will consist of one question and one answer. All the noise encountered along the way will be omitted.