Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am trying to create an Apache SSL server to be used in pre-production testing and that even in production would be accessed by less than 5 or so users. Because of the small user base, I felt that the easiest way to manage certificates would just be to self-sign them and then explicitly tell Apache to only trust the small number of certificates we create. From what I can tell, it seems like Apache needs a CA, though I'm hoping there's a way around that.

Also, as far as development goes I tend to know my stuff but I am pretty much a newb at being a sysadmin so the simpler the better in terms of solutions.

As a side note, I also saw this post: here which I think is similar to what I'm asking but not quite a solution I'm looking for. Ideally, I could just use openSSL to generate self-signed certs on the fly and add copies of them to a directory so when they're used to access the server Apache will let the connection be created.

share|improve this question
That question still applies Just create a cert, self sign and save a copy in the SSLCACertificatePath directory. – Zoredache Jul 28 '10 at 16:21

After great struggle, we have finally found a solution. Not entirely ideal, but now that we have it in place it seems to be working well.

In Apache, we first had to enable mod_ssl, require client auth, and then set verify depth to 1. Then we had to set the server cert and key to something generated and signed by our CA (I'll get to that in a minute) and set the SSLCACertificateFile to our CA's cert. In so far as creating your CA, this guide was pretty thorough and I found it to be very accurate. Other than slightly modifying a few directory paths so that it worked with Ubuntu ie using /etc/ssl it worked fine. We created a CA, then generated a CA cert. We then generated a server key and server cert request, and signed the request with the CA. We then set Apache to use the new server cert and key. At that point, you were able to do server auth but not client auth. To do the later portion, we just built off of some of the examples already in the above link. The process for creating/signing cert-key combinations is generic ie you could use the combo on either a server or a client. So we just repeated the process to create a client cert (and could do it again and again to create more). Once we had that we converted the two files in a .pk12

# openssl pkcs12 -export -in certs/client.crt -inkey private/client.key -out ~/clientcred.p12

And finally we imported the cred into firefox for use. We also added our new CA to firefox's internal list of trusted CA's. Hope this helps anybody else who is trying something similar.

share|improve this answer

There are two things you need to do.

First, you need to generate certificates for the browsers that you are going to have connected.

Then, you need to set Apache to require these certs for some folder.

The apache portion is simple - just add this to your /etc/apache2/sites-enabled/your_apache_file.conf:

<Location /path/to/folder>
SSLVerifyClient require
SSLVerifyDepth 1

Now assuming you've set up your apache SSL like this:

SSLEngine on
SSLCertificateFile /etc/apache2/ssl/server.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
SSLCACertificateFile /etc/apache2/ssl/ca.crt

SSLVerifyClient optional
SSLOptions +StdEnvVars +ExportCertData

You also need to set yourself up as a CA.

Here is a chunk of Python code we use for generating client certs - this should give you a good idea of what you need to do from here:

commonname = "name_of_client_machine"

serial_file = open('/usr/local/my/web/certs/','r')
serial =

cert_folder = '/usr/local/my/web/certs/clients/%s_%s' % (serial,commonname)


    os.makedirs(cert_folder, 0755)

except OSError:

commands.getstatusoutput("sed s/hostname/%s/ /usr/local/my/web/certs/client.tpl > %s/client.tpl" % (commonname,cert_folder))

commands.getstatusoutput("openssl genrsa -des3 -passout pass:mypassword -out %s/web_client.key 4096" % cert_folder)

commands.getstatusoutput("openssl req -new -key %(cert_folder)s/web_client.key -out %(cert_folder)s/web_client.csr -config %(cert_folder)s/client.tpl -passin pass:mypassword" % ({'cert_folder':cert_folder}))

commands.getstatusoutput("openssl x509 -req -days 3650 -in %(cert_folder)s/web_client.csr -CA /usr/local/my/web/certs/ca.crt -CAkey /usr/local/my/web/certs/ca.key -out %(cert_folder)s/web_client.crt -passin pass:mypassword"  % ({'cert_folder':cert_folder}))

commands.getstatusoutput("openssl pkcs12 -export -clcerts -in %(cert_folder)s/web_client.crt -inkey %(cert_folder)s/web_client.key -out %(cert_folder)s/web_client.P12 -passin pass:mypassword -passout pass:mypassword" % ({'cert_folder':cert_folder}))

Now you take the .p12 file and you import it into the client browser. You will be asked for the password (which above was just 'mypassword'), and then it will be installed and ready to go.

share|improve this answer
This was very close to what we ended up doing. But instead of using Python, we just used OpenSSL from the command line. We also set up our own CA to sign the certs. – themaestro Jul 29 '10 at 19:16

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.