Code Ghar

Create a Certificate Authority and Certificates with OpenSSL

Posted in configuration by hs on March 17, 2008

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;

Tagged with: ,

Apache 2.0 in Ubuntu

Posted in configuration by hs on March 15, 2008

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;

Tagged with: , ,