Create a Certificate Authority and Certificates with OpenSSL
This tutorial will assume that you are using Ubuntu 7.10 (Gutsy Gibbon). This tutorial has been adapted from Setting up OpenSSL to Create Certificates and OpenSSL – Community Ubuntu Documentation. I would recommend that you get the latest info from these resources as mine may be out of date. Both of them are very helpful. Besides, without them I would not have been able to create this one.
Install OpenSSL
sudo apt-get install openssl
Create Directory Structure
You need to create a directory structure to store files and also create some initial files. We will first create a main directory. I would recommend creating it under /home so that if you upgrade, you will have access to those files.
mkdir /home/ca /home/ca/private /home/ca/certs /home/ca/conf
cd /home/ca
echo '01' > serial
touch index.txt
Create Certificate Authority (CA)
sudo vim /home/ca/conf/caconfig.cnf
This file would serve as the default config file for the CA. It should look something like the following (taken from the Setting up OpenSSL resource), of course with your own settings:
#..................................
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = /home/ca
serial = $dir/serial
database = $dir/index.txt
new_certs_dir = $dir/certs
certificate = $dir/certs/cacert.pem
private_key = $dir/private/cakey.pem
default_days = 365
default_md = md5
preserve = no
email_in_dn = no
nameopt = default_ca
certopt = default_ca
policy = policy_match
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
default_bits = 1024 # Size of keys
default_keyfile = key.pem # name of generated keys
default_md = md5 # message digest algorithm
string_mask = nombstr # permitted characters
distinguished_name = req_distinguished_name
req_extensions = v3_req
[ req_distinguished_name ]
# Variable name Prompt string
#------------------------- ----------------------------------
0.organizationName = Organization Name (company)
organizationalUnitName = Organizational Unit Name (department, division)
emailAddress = Email Address
emailAddress_max = 40
localityName = Locality Name (city, district)
stateOrProvinceName = State or Province Name (full name)
countryName = Country Name (2 letter code)
countryName_min = 2
countryName_max = 2
commonName = Common Name (hostname, IP, or your name)
commonName_max = 64
# Default values for the above, for consistency and less typing.
# Variable name Value
#------------------------ ------------------------------
0.organizationName_default = My Organization
localityName_default = NEW YORK
stateOrProvinceName_default = NEW YORK
countryName_default = US
emailAddress_default = email@mydomain.net
[ v3_ca ]
basicConstraints = CA:TRUE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
[ v3_req ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
Generate CA Key and Certificate
Once you have the config file created the way you want, you will have to create a root (CA) key and certificate.
You will be prompted for some questions. Those questions for which you provided the default answers in your caconfig.cnf file, you do not need to enter any other information; you may just press enter key. However, the most important thing is this: Common Name should be unique, and should be the full legal name of your organization. If you are an individual, make sure it is your name. As you create more certificates, Common Name has to be unique for each of them.
You will also have to enter a passphrase. Make sure it is long, difficult, and then keep it safe. It would be awesome if you could encrypt it as well. But whatever you do, however you save it, do not, I repeat, do not lose it.
cd /home/ca/
openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out cacert.pem -days 365 -config conf/caconfig.cnf
Create Server Certificate
You first have to create a key and signing request, both of which can be done in the same command. You will be prompted for some questions again, and once again you have to make sure Common Name is unique. To create a server certificate, you should always choose the full domain name of the server, or its IP address. For example, if you are creating a certificate for www.mydomain.net, you should enter www.mydomain.net as Common Name. However, if you want to use the same certificate across many domains, enter *.mydomain.net as Common Name.
I also like to name the requests, keys, and certificates after the domain I will be usig them for. So let’s say you are choosing to create a certificate for www.mydomain.net, then
cd /home/ca/
openssl req -new -nodes -out www.mydomain.net.req.pem -keyout private/www.mydomain.net.key.pem -config conf/caconfig.cnf
Next you have to sign this request to create a certificate. It will ask you to enter the passphrase chosen when creating the root key. So just enter it.
openssl ca -out certs/www.mydomain.net.cert.pem -config conf/caconfig.cnf -infiles www.mydomain.net.req.pem
You can use this certificate in your server applications now.
Create Client Certificate
Creating a client certificate, such as for your web browser, is similar to creating one for a server. One can use client certificates to identify clients, and also to authenticate them.
For Common Name, you should choose the name of the client. If it is an individual, their full name, or if it’s an organization then its full name. For more details, check out the details under Create Server Certificate.
cd /home/ca/
openssl req -new -nodes -out myfriend.req.pem -keyout private/myfriend.key.pem -days 365 -config conf/caconfig.cnf
Similarly, you have to sign this request with the root key. Again, details are provided under Create Server Certificate.
openssl ca -out certs/myfriend.cert.pem -days 365 -config conf/openssl.cnf -infiles myfriend.req.pem
Set up Apache 2.0 with SSL
Please read my guide titled Apache 2.0 in Ubuntu for a detailed guide.
Get Certificates from CAcert
If you do not wish to pay for certificates, check out CAcert. They are aiming to become a well-recognized CA which gives free certificates. It would be better than creating your own as it will be much more secure and you would not have to pay any money.
Hat Tips
Other very good guides and resources are: Client Authentication with SSL; subjectAltName setup;
Apache 2.0 in Ubuntu
This post will deal with setting up a web server in Ubuntu using Apache 2.0. I will not be able to cover every scenario but I hope I can cover the most common ones. Default paths and so on are based on Ubuntu 7.10, Gutsy Gibbon.
Install Apache
sudo apt-get install apache2
Make sure it has been installed and is working properly by going to the server’s IP address using any web browser.
Custom Configurations
Since Apache allows you to include other files for configuration, it might be a good idea to create a file with all your custom configurations in it. Then you just have to save that file and use it whenever needed without messing around with the default configurations.
sudo mkdir /etc/apache2/customconfig/
sudo touch /etc/apache2/customconfig/server.conf
And then add the following line to /etc/apache/apache2.conf
Include /etc/apache2/customconfig/
And from then on all custom configurations will be loaded by Apache.
Give Apache a Server Name
Check that the configuration files have a server name or not.
grep -n ServerName /etc/apache2/apache2.conf
grep -n ServerName /etc/apache2/httpd.conf
grep -n ServerName /etc/apache2/ports.conf
Usually, if a server name has not been set, Apache will complain when you start it. So just add a server name to your config file. If you have created a custom config file, such as server.conf above, just add the following line
sudo vim /etc/apache2/customconfig/server.conf
If you haven’t created a custom config file, add the following line to the main config file
sudo vim /etc/apache2/apache2.conf
And add the line:
ServerName localhost
Now when you restart Apache, it will not complain that it doesn’t have a server name.
Listen on Ports
You need to make sure that Apache is listening on at least two ports: 80 (HTTP) and 443 (HTTPS). Your /etc/apache2/ports.conf file should look something like this:
Listen 80
<IfModule mod_ssl.c>
Listen 443
</IfModule>
Create Site
To create a site, you first have to decide where to store the files. I like to store them under my home directory, with read access to the user under which Apache runs, which is more likely than not www-data in Ubuntu.
mkdir /home/me/web/ /home/me/logs/
sudo chown -R www-data /home/me/logs/
chmod g+rwx /home/me/logs
VirtualHost Configuration
Since I may need to host more than one sites on the server, I want to use VirtualHost and its associated settings. I prefer to keep separate files for each virtual host.
sudo cp /etc/apache2/sites-available/default /etc/apache2/sites-available/sitedomain
sudo vim /etc/apache2/sites-available/sitedomain
And then get to editing the file. After editing, my first virtual host config looks like this:
NameVirtualHost *:80
<VirtualHost *:80>
ServerName mydomain.com
DocumentRoot /home/me/web/
ErrorLog /home/me/logs/error.log
</VirtualHost>
Enable New Site
After creating the config file for new web site, you need to enable it.
sudo a2ensite sitedomain
But to use it, you must also disable the default site
sudo a2dissite default
Next you have to reload configurations in Apache
sudo /etc/init.d/apache2 reload
Now when you navigate to the server, it will show your new site.
Install SSL
Make sure apache has SSL module available into it:
ls /etc/apache2/mods-available | grep ssl.conf
ls /etc/apache2/mods-available | grep ssl.load
Install OpenSSL and ssl-cert
sudo apt-get install openssl ssl-cert
Your Ubuntu installation may not have one critical piece of software: apache2-ssl-certificate. You may download it from Launchpad (apache2-ssl) and do the following steps (instructions courtesy of Apache2-SSL-Certificate for Ubuntu Feisty..How to install this missing script to get the SSL certificates up):
cd ~/
wget http://librarian.launchpad.net/7477840/apache2-ssl.tar.gz
tar xvzf apache2-ssl.tar.gz
sudo mv ssleay.cnf /usr/share/apache2/
sudo mv apache2-ssl-certificate /usr/sbin
sudo mkdir /etc/apache2/ssl
Now you may proceed with the next steps.
Configure SSL
First you have to generate an SSL certificate.
sudo apache2-ssl-certificate -days 365
It started asking a bunch of questions and here are sample answers:
Country name: US
State: New York
Locality: New York
Organization Name: My Organization
Organizational Unit Name: .
Server name: ssl.mysite.net
Email: myemail@mysite.net
To enable the SSL module in Apache, run the following
sudo a2enmod ssl
Site Configuration
Your virtual host config will change and be something like:
NameVirtualHost *:80
<VirtualHost *:80>
ServerName mydomain.com
DocumentRoot /home/me/web/
ErrorLog /home/me/logs/error.log
</VirtualHost>
NameVirtualHost *:443
<VirtualHost *:443>
ServerName mydomain.com
DocumentRoot /home/me/web/
ErrorLog /home/me/logs/error.log
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/apache.pem
</VirtualHost>
Now you may navigate your site without problems.
Configure SSL with OpenSSL
If you want to use OpenSSL to create and maintain your certificates, and also use them with Apache, read my guide titled Create a Certificate Authority and Certificates with OpenSSL. Once you have created server certificates, you have to make just a few changes in your virtual host config: location of the key and certificate files. For example, your config file might now look like
NameVirtualHost *:80
<VirtualHost *:80>
ServerName mydomain.com
DocumentRoot /home/me/web/
ErrorLog /home/me/logs/error.log
</VirtualHost>
NameVirtualHost *:443
<VirtualHost *:443>
ServerName mydomain.com
DocumentRoot /home/me/web/
ErrorLog /home/me/logs/error.log
SSLEngine On
SSLCertificateFile /home/ca/certs/mydomain.com.cert.pem
SSLCertificateKeyFile /home/ca/private/mydomain.com.key.pem
SSLCACertificateFile /home/ca/certs/cacert.pem
</VirtualHost>
Redirect Traffic to SSL
And if you want to redirect all your port 80 traffic to the secure, SSL-enabled part of your web server, you first have to enable the Rewrite engine
sudo a2enmod rewrite
Then you have to enable it in your virtual host configuration and change it to
NameVirtualHost *:80
<VirtualHost *:80>
ServerName mydomain.com
DocumentRoot /home/me/web/
ErrorLog /home/me/logs/error.log
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</VirtualHost>
NameVirtualHost *:443
<VirtualHost *:443>
ServerName mydomain.com
DocumentRoot /home/me/web/
ErrorLog /home/me/logs/error.log
SSLEngine On
SSLCertificateFile /home/ca/certs/mydomain.com.cert.pem
SSLCertificateKeyFile /home/ca/private/mydomain.com.key.pem
SSLCACertificateFile /home/ca/certs/cacert.pem
</VirtualHost>
Now all traffic on regular port will be redirected to secure port.
Access Using Client Certificates
If you want only selected people to be able to browse your website, you can create certificates for clients and set Apache to only allow them access. To create client certificates, read my guide titled Create a Certificate Authority and Certificates with OpenSSL.
On the Apache side, you have to change your virtual host config and make it look something like:
NameVirtualHost *:80
<VirtualHost *:80>
ServerName mydomain.com
DocumentRoot /home/me/web/
ErrorLog /home/me/logs/error.log
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</VirtualHost>
NameVirtualHost *:443
<VirtualHost *:443>
ServerName mydomain.com
DocumentRoot /home/me/web/
ErrorLog /home/me/logs/error.log
SSLEngine On
SSLCertificateFile /home/ca/certs/mydomain.com.cert.pem
SSLCertificateKeyFile /home/ca/private/mydomain.com.key.pem
SSLCACertificateFile /home/ca/certs/cacert.pem
<Directory /home/me/web>
SSLVerifyClient require
SSLVerifyDepth 1
</Directory>
</VirtualHost>
Hat Tips
To be honest, my starting point was Ubuntu LAMP Server Guide, from where I took steps and then added more details where I thought they were needed.
Also helpful were: Apache2 SSL in Ubuntu; Apache2-SSL-Certificate for Ubuntu Feisty..How to install this missing script to get the SSL certificates up; SSL FAQ;