Home Learn Linux Linux Tutorials Creating Self-Signed SSL Certificates for Apache on Linux

Creating Self-Signed SSL Certificates for Apache on Linux


If Firesheep and other menaces have you freaked out about using unsecured connections, it's time to take matters into your own hands. In just under 20 minutes, you can create a self-signed certificate for Apache to connect to your Web site for passing any kind of sensitive information. It's easy and takes very little time to configure.

This tutorial assumes you're going to do a self-signed certificate. Note that you can pretty much follow along with the tutorial for getting and installing a certificate via a Certificate Authority (CA), but omit the steps for generating your own self-signed cert. Generate the request, work with the CA to get the certificate, and then follow the installation and configuration steps.

Self-signed vs. Certificate Authorities

Why am I giving a guide for self-signed certs? Self-signed certificates should really only be used in a few situations — but a lot of users fit the profile for using a self-signed certificate but fail to create one and work over plain HTTP instead.

I use a self-signed certificate because I want to connect to my server securely when managing my blog using WordPress. If I'm in a coffee-shop or airport, I really don't want to be sending my credentials over the network without encryption. Bad idea.

But I wouldn't use a self-signed cert for any site that will be handling traffic from people outside an organization or for a "mission critical" type of application. That is, if you're working with a small business and have two or three road warriors who have to connect to Webmail and such over SSL, a self-signed cert is probably acceptable. If you're doing support for a larger organization, or if you're going to have people outside the organization connecting — spring for a paid certificate.

The reason? You should want to give users a cert that is signed by a third party that's recognized by major browsers. This knocks out CaCert, unfortunately, because their root certificate is not distributed with the major browsers. But if you don't have a cert from a trusted third party, users will get the nasty "this is an untrusted site" warning. Aside from the fact that it looks unprofessional, it's also a real risk — in a large organization, do you assume that all users will know the difference between a legitimate key generated by your IT department, and keys generated by a malicious third party? No, you do not. So don't place that responsibility on your users — buy a cert.

But there are thousands upon thousands of sites that need SSL, and don't need a paid certificate. And I'm not a fan of spending money (and wasting time) when it's not necessary. So let's get started.

A Cert of My Own

Believe it or not, I don't generate certs every day, so I had to troll around for some instructions of my own. The post on Ubuntu Forums, and Ubuntu Server Guide were useful and got me most of the way there.

Here's what we're going to do, in order:

  1. Make sure Apache has SSL enabled.
  2. Generate a certificate signing request (CSR).
  3. Generate a self-signed certificate.
  4. Copy the certificate and keys we've generated.
  5. Tell Apache about the certificate.
  6. Modify the VirtualHosts to use the certificate.
  7. Restart Apache and test.

Let's start with making sure that SSL is enabled by using the a2enmod utility to enable the SSL module:

sudo a2enmod ssl

Generate the CSR

Now it's time to generate the CSR, and fill out the questions you'd normally have verified by a Certificate Signing Authority:

sudo openssl req -new > new.ssl.csr

Once you do this, you'll be prompted for a passphrase — you're going to want to remember the passphrase.

Now, you're going to walk through a set of questions:


Generating a 1024 bit RSA private key
writing new private key to 'privkey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
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]:Enter Code Here
State or Province Name (full name) [Some-State]:Enter State Here
Locality Name (eg, city) []:Enter City Here
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Enter Company Name
Organizational Unit Name (eg, section) []:Org Unit (if you have one)
Common Name (eg, YOUR name) []:First and Last Name
Email Address []:Work Email

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:Leave Blank
An optional company name []:Optional

Parts in bold emphasis require input. You want to leave the challenge password blank, otherwise you'll need to enter this every time you restart Apache.

Generate the Certificate

Now it's time to create the certificate. You're going to use OpenSSL again to create the certificate and then copy the certificate to /etc/ssl where Apache can find them.


sudo openssl rsa -in privkey.pem -out new.cert.key
sudo openssl x509 -in new.cert.csr -out new.cert.cert -req -signkey new.cert.key -days NNN
sudo cp new.cert.cert /etc/ssl/certs/server.crt
sudo cp new.cert.key /etc/ssl/private/server.key

The -days option sets the length of time before the certificate expires. I went ahead and (roughly) calculated the time until the release of Ubuntu I'm using will be out of support. You can revoke a certificate or replace one before the cert expires, of course.

Now, you have the key (server.key) and PEM certificate (server.crt is a PEM certificate). You need to make sure that the key is not world-readable, but that the certificate is.

Configure Apache

Now that we've got the certificate in place, you need to edit the Apache configuration to add SSL to your site. Your configuration may differ, depending on how you have your sites set up and whether you're only serving one site or whether you're serving several domains from your server.

Here's how I edited my configuration, which was located in /etc/apache2/sites-available/


NameVirtualHost *:443
NameVirtualHost *:80

<VirtualHost *:80>
    ServerAdmin email address here
    DocumentRoot /srv/www/
    ErrorLog /srv/www/
    CustomLog /srv/www/ combined

<VirtualHost *:443>
 This e-mail address is being protected from spambots. You need JavaScript enabled to view it
    DocumentRoot /srv/www/

    ErrorLog /srv/www/
    CustomLog /srv/www/ combined

    SSLEngine on
    SSLOptions +StrictRequire
    SSLCertificateFile /etc/ssl/certs/server.crt
    SSLCertificateKeyFile /etc/ssl/private/server.key

If you're already using the domain, you don't need to do anything but restart Apache. If you're setting Apache up for the first time, or this is a new domain, then you want to run this:

sudo a2ensite

If you run it and the site is already enabled, then you'll just get an error from Apache saying it's already enabled. Note that all that really does is set up a symlink under /etc/apache2/sites-enabled that links to the configuration in /etc/apache2/sites-available.

Finally, check and make sure your server address is in /etc/hosts with the IP address you're using for the server.

That should be it. Go ahead and connect to your Web site using SSL (connect to instead of and you'll need to approve the certificate the first time — unless you skipped the self-signing and sprung for a paid certificate that's recognized by major browsers. If that's the case, you shouldn't see an error at all — just an indication that you have a secure browser connection.

Note that you can also use SSL for securing other traffic. In upcoming tutorials we'll look at securing IMAP, SMTP, and other connections, and more tips and tricks for using SSH too.



Subscribe to Comments Feed
  • Micky Said:

    Now it's time to generate the CSR, and fill out the questions you'd normally have verified by a Certificate Signing Authority: sudo openssl req -new > new.ssl.csr should be "sudo openssl req -new > new.cert.csr". Not because it's wrong, but because that's what you use later on.

  • Pete Said:

    This needs a little bit more explanation... Finally, check and make sure your server address is in /etc/hosts with the IP address you're using for the server.

  • Joachim Said:

    Nice m8 it worked perfect. i tried some different guides but this is the one that worked for me.

  • Mufleeh Said:

    Hi wonderful article, thanks for all info. As it's a tutorial people may run the codes as it is without intending to understand them. In that case the certificate signing request file's name created in the beginning is new.ssl.csr and the one used below is new.cert.csr, hope they should be the same!

  • Oscar Said:

    There is a wrong line, sudo openssl x509 -in new.cert.csr -out new.cert.cert -req -signkey , here you are referencing the csr as cert, but the one you previously created is ssl. And also it would be nice if you could add the sudo chmod for the required files in "You need to make sure that the key is not world-readable, but that the certificate is."

  • Sridhar Said:

    Oscar, I was wondering why no one pointed that out. good call.

  • BigDaddy68 Said:

    This is a great post and is really appreciated. How does this change w.r.t Heartbleed OpenSLL vulnerability ?

  • GambitRS Said:

    You add -patch HeartBleed to the last command

  • aprogrammer Said:

    Thanks for the post. I found many usefull commands to generate csr, key and self-signed crt on the fly with one command in non-interactive mode. Here is the link - ,maybe if would be usefull

Who we are ?

The Linux Foundation is a non-profit consortium dedicated to the growth of Linux.

More About the foundation...

Frequent Questions

Join / Linux Training / Board