The Certificate Authority Root Certificate
With the master configuration file taken care of we can now set up the directory structure to hold our CA. We choose a suitable location and make our directories and initialize the serial file.
[admin@tamarack admin]$ mkdir CA-DB [admin@tamarack admin]$ cd CA-DB [admin@tamarack CA-DB]$ mkdir crl [admin@tamarack CA-DB]$ mkdir newcerts [admin@tamarack CA-DB]$ mkdir private [admin@tamarack CA-DB]$ echo "01" > serial [admin@tamarack CA-DB]$ touch index.txt [admin@tamarack CA-DB]$
Notice that we seed the file serial with the first serial number. As we issue certificates, the number stored in this file will automatically increment so each certificate will receive a unique serial number. The file index.txt will record all certificates issued. Records in this file will map the subject DN in a certificate to its assigned serial number. Using index.txt, we can look up the serial number for any certificate using the subject's DN. This will become important when we decide that we need to revoke a certificate and need to find the original.
As defined in the configuration file, the new_certs_dir will hold copies of all certificates issued by this CA. The filenames for these certificates will consist of the serial number assigned to the certificate by the CA followed by an extension.
With the directory structure in place, we can create our self-signed root certificate. This certificate will sit at the top of our trust hierarchy. We will use it to sign all of the rest. For our tutorial, we will only use a single layer of trust, but a more robust design would probably use more.
[admin@tamarack CA-DB]$ openssl req -new -x509 -keyout \ > private/cakey.pem -out cacert.pem Generating a 1024 bit RSA private key ...................................................... writing new private key to 'private/cakey.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. ----- Organization Name (eg, company) [Inyo Technical Services]: Organizational Unit (eg, west) : Common Name (eg, YOUR name) :Root CA [admin@tamarack CA-DB]$
Note: here and in the code examples that follow, the output has been reformatted to a maximum width of 60 characters.
To clarify some potential confusion, the
-x509 option will
req command to output a self-signed certificate rather
than a certificate request. We will only use this option with the
req command one time when we create our root certificate.
Next, we create a certificate request for the OpenVPN server endpoint
installed on our local network. Note that we use the
argument. This prevents the private key generated with the request from being
encrypted and password-protected. We will need to guard the key carefully
because of this. We don't password protect this one private key because later
we may want to start our OpenVPN server automatically at boot time when there
is no interactive user available to supply the password. We could enter the
password into the boot script itself, but that would sort of defeat the purpose
of having a password in the first place. Physical security (such as locking the
door to the server room) is the best way to protect this non-encrypted private
[admin@tamarack admin]$ openssl req -new -nodes -keyout \ > vpnkey.pem -out vpncert-req.pem Generating a 1024 bit RSA private key ........................................................ writing new private key to 'vpnkey.pem' ----- 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. ----- Organization Name (eg, company) [Inyo Technical Services]: Organizational Unit (eg, west) : Common Name (eg, YOUR name) :vpn.inyotech.com [admin@tamarack admin]$
Now we digitally sign the server certificate using the root certificate we created initially. OpenSSL will retrieve the location of the root certificate from the configuration file, which is why it does not appear as a argument on the command line. This command will update the files serial and index.txt when it completes.
[admin@tamarack admin]$ openssl ca -out vpncert.pem \ > -in vpncert-req.pem Using configuration from /home/admin/install/openssl.cnf Enter pass phrase for /home/admin/CA-DB/private/cakey.pem: Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows organizationName :PRINTABLE:'Inyo Technical Services' commonName :PRINTABLE:'vpn.inyotech.com' Certificate is to be certified until Aug 18 22:50:07 2005 GMT (365 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated [admin@tamarack admin]$
After creating the server certificate, we can create certificates for all of
the clients to whom we want to give VPN access. The procedure is the same,
except we don't specify the
-nodes option with the
req command. This will encrypt the private key, and OpenSSL will
prompt for a password use when seeding the cipher.
OpenSSL Test Framework
Now, after we have issued a couple of user certificates, we can make sure
that our procedures are all correct by taking advantage of the two test
commands provided by the OpenSSL package. The programs
s_client (secure client) can exercise almost the
entire library and their operation is straightforward.
Start an OpenSSL secure server session in one terminal window. Start an OpenSSL secure client session in another. The client will contact the server using the SSL/TLS protocol at localhost using port 4433. You will be able to type messages into the console hosting the secure client and see them appear at the secure server. It will be immediately obvious if your certificates are not correct or there is a problem with your OpenSSL library installation.
Here we start an OpenSSL secure server at the command line. For arguments,
we include the server certificate and server private key. The argument
-verify 1 causes the server to ask any connecting client to send a
certificate for authentication. (Note that the output from these commands
is more verbose than these trimmed code examples indicate.)
[admin@tamarack admin]$ openssl s_server -cert vpncert.pem \ > -key vpnkey.pem -verify 1 verify depth is 1 Using default temp DH parameters ACCEPT ... [admin@tamarack admin]$
Now, in another console window, we start an OpenSSL secure client using the
-cert to provide a certificate to send to the
server for authentication. The
-key argument gives the private key
to use when encrypting messages and the
-CAfile argument points to
the root certificate.
[admin@tamarack admin]$ openssl s_client -CAfile \ > CA-DB/cacert.pem -cert client1cert.pem -key client1key.pem Enter PEM pass phrase: ... [admin@tamarack admin]$
When the connection attempt succeeds, you can send sample messages between
the client and server by typing text into either secure endpoint. To quit the
Q in the terminal window.
Now we know that our certificates can encrypt messages passed between
two OpenSSL applications. However, we have not yet made sure that we can use
our certificates with any arbitrary X.509-certificate-secured application.
-WWW option to the
s_server command will
effectively create a secure web server that can serve any local file to a
web-browsing client connecting using SSL/TLS. We will exercise this feature
In the current working directory, create a small HTML file containing text similar to the following:
<html> <body> <h1>Hello World!</h1> </body> </html>
Give the file a name such as hello.html and then start a secure web
server from the same directory as the file using the
[admin@tamarack admin]$ openssl s_server -cert vpncert.pem \ > -key vpnkey.pem -WWW Using default temp DH parameters ACCEPT
Start any modern web browser, such as Mozilla, Netscape, or Opera. Internet
Explorer should also work, if you are following along with this tutorial on
Windows. Enter the following URL in the address bar, noting that the protocol
https and not
The web browser should alert you to the fact that it does not recognize the subject in the certificate offered by the server. Most browsers will allow you to accept the authenticity of a server certificate temporarily for a single session. After clicking through any such warning messages, you should see the sample page appear in the browser window. A client can connect to the secure web server from a remote server, as well.
s_server is an extremely useful test tool. Secure
applications using certificates can be difficult to debug, especially if you
are not sure where a potential problem may exist. OpenSSL's test client and
server let an administrator more easily isolate problems to either a network
application or its supporting certificate infrastructure.