Thursday,
February
23,
2012
Font Size
   

Create your own CA on Vyatta

 
When setting up OpenVPN you definitively want to use certificates, especially when you configure Remote-Access.
In the end, there are several ways how to get hold of the required certificates, i.e. a Public Certificate Authority like Verisign, GoDaddy, etc., you can use your own CA if you have one (or the customer), i.e. an Active Directory Certificate Server and several other ways.
But sometimes it's just quicker and easier to build your own CA on the Vyatta Router, especially if it's a "closed" environment like Site-to-Site links, Remote Access for users where no other CA is available or Lab setups.
There are some HOW-TOs on the net and also Vyatta has something in the Knowledgebase, but unfortunately there are always missing bits and pieces which require you to search elsewhere (after you spend hours on trying to figure out what is going wrong). 
 
Here I'll "try" to have a complete guide for you. Hope it helps.
 
This guide is explicitely for the usage on a Vyatta Device, but with some changes it should work on any other *nix based system as well.
 
Luckily the Vyatta Software already contains all the software, libraries and binaries we need in order to build our own ca and use it to issue certificates and revoke them if required.
BTW: using only certificates might be a "not so good" idea and I highly suggest you use additional authentication and athorization methods like external OpenVPN Access Servers, RADIUS, TACACS+ or Active Directory integration.
 
Build you own CA
 
The first thing you need to do is become root, as the normal Vyatta or any other user doesn't have the correct rights to access / execute the files.
You cannot just add "sudo" in front of every command (for whatever reason that doesn't work, I believe it's related to the environment settings, some path are missing). This might cause some more work but is safer in the end. So do the following:
 
 

adieball@vyatta:~$ sudo su
vyatta:/home/adieball# cd
vyatta:~#
 
 
 
Now we copy the required code from the OpenVPN examples directory into a place were we can use it.
Do not just "use" the code from the examples directory, as all you stuff might be overwritten with a software upgrade which renders your complete VPN useless, as all keys are missing then.
 
 

vyatta:~# cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 /root/ca
vyatta:~# cd /root/ca
vyatta:~/ca#

 
 
If you want, you can edit the defaults like KEY_COUNTRY, KEY_PROVINCE, KEY_CITY, KEY_ORG, and KEY_EMAIL. These settings are in the vars file. You don't have to edit the defaults, you make sure, none of these are left blank!
 
Next we need to initialize the CA:
 

vyatta:~/ca# source vars
NOTE: If you run ./clean-all, I will be doing a rm -rf on /root/ca/keys
vyatta:~/ca# ./clean-all

 
Do the "./clean-all" only the first time, as it'll delete all your keys!
Each time you create a new certificate / key, you need to "source vars" first.
 
Also, make sure that you do everything always out of the "root/ca" directory. OpenSSL will find the required stuff (e.g. keys, certificates, etc.) on it's own)
Next, we build the CA itself:
 

vyatta:~/ca# ./build-ca
Generating a 1024 bit RSA private key
....++++++
....++++++
writing new private key to 'ca.key'
-----
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) [US]:DE
State or Province Name (full name) [CA]:Brandenburg
Locality Name (eg, city) [SanFrancisco]:Velten
Organization Name (eg, company) [Fort-Funston]:dieball.net
Organizational Unit Name (eg, section) []:IT Chamber of Horror
Common Name (eg, your name or your server's hostname) [Fort-Funston CA]:Home Vyatta
Name []:
Email Address [me@myhost.mydomain]:andre@dieball.net
vyatta:~/ca#

 
That's it, now your CA is ready to serve you. You can quickly confirm that all required stuff is created by looking into the "keys" subdirectory:
 

vyatta:~/ca# ls -lai keys/
total 20
120139 drwx------ 1 root root 4096 Nov 17 21:06 .
120112 drwxr-xr-x 1 root root 4096 Nov 17 21:00 ..
120556 -rw-r--r-- 1 root root 1383 Nov 17 21:06 ca.crt
120152 -rw------- 1 root root 887 Nov 17 21:06 ca.key
120140 -rw-r--r-- 1 root root 0 Nov 17 21:00 index.txt
120141 -rw-r--r-- 1 root root 3 Nov 17 21:00 serial
vyatta:~/ca#

 
Oh, btw: DO NOT mess around with these files.
 
Next we need to create our first certificate. This will be used by the Vyatta or better the OpenVPN process itself:
 

./build-key-server $SERVER

where $Server is the name of your Vyatta Device serving as the "VPN Concentrator"
 

vyatta:~/ca# ./build-key-server minime.dvrdns.org
Generating a 1024 bit RSA private key
.....................++++++
..............................++++++
writing new private key to 'minime.dvrdns.org.key'
-----
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) [US]:DE
State or Province Name (full name) [CA]:Brandenburg
Locality Name (eg, city) [SanFrancisco]:Velten
Organization Name (eg, company) [Fort-Funston]:dieball.net
Organizational Unit Name (eg, section) []:IT Chamber of Horror
Common Name (eg, your name or your server's hostname) [minime.dvrdns.org]:
Name []:
Email Address [me@myhost.mydomain]:andre@dieball.net

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: <-- Enter a Passsword here or leave blank. See below!!!
An optional company name []:
Using configuration from /root/ca/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'DE'
stateOrProvinceName :PRINTABLE:'Brandenburg'
localityName :PRINTABLE:'Velten'
organizationName :PRINTABLE:'dieball.net'
organizationalUnitName:PRINTABLE:'IT Chamber of Horror'
commonName :PRINTABLE:'minime.dvrdns.org'
emailAddress :IA5STRING:'andre@dieball.net'
Certificate is to be certified until Nov 14 20:12:25 2020 GMT (3650 days)
Sign the certificate? [y/n]:y <-- Yes, it must be signed by the already ceated CA

1 out of 1 certificate requests certified, commit? [y/n]y <-- Yes, we want to issue that certificate
Write out database with 1 new entries
Data Base Updated
vyatta:~/ca#

 
 
A quick word in regards to the "Challenge Password" request: you don't need to add a password here, but this is true only for the Server Certificate. You DO want to have a password for the client certificates. The password is requested everytime the certificates key file is accessed. Do if you enter a password for the server certificate ... hmm, there is no one at the server to enter it, so you'd have to put it in the config :-)
 
That's it, if you do a "ls -lai keys/" now, you should see:
 

vyatta:~/ca# ls keys/ -lai
total 56
120139 drwx------ 1 root root 4096 Nov 17 21:12 .
120112 drwxr-xr-x 1 root root 4096 Nov 17 21:00 ..
120648 -rw-r--r-- 1 root root 4163 Nov 17 21:12 01.pem
120644 -rw-r--r-- 1 root root 4163 Nov 17 21:12 minime.dvrdns.org.crt
120643 -rw-r--r-- 1 root root 741 Nov 17 21:12 minime.dvrdns.org.csr
120623 -rw------- 1 root root 887 Nov 17 21:12 minime.dvrdns.org.key
120556 -rw-r--r-- 1 root root 1383 Nov 17 21:06 ca.crt
120152 -rw------- 1 root root 887 Nov 17 21:06 ca.key
120646 -rw-r--r-- 1 root root 150 Nov 17 21:12 index.txt
120647 -rw-r--r-- 1 root root 21 Nov 17 21:12 index.txt.attr
120140 -rw-r--r-- 1 root root 0 Nov 17 21:00 index.txt.old
120645 -rw-r--r-- 1 root root 3 Nov 17 21:12 serial
120141 -rw-r--r-- 1 root root 3 Nov 17 21:00 serial.old
vyatta:~/ca#

 
The next important (and unfortunately missing bit in the Vyatta Docs) is to create the CRL (Certificate Revocation List), so that you can revoke certificates and force the OpenVPN Process to check each by a client offered certificate against this list.
Best way to do this is to create a certificate/key and revoke it immediately, this will create the needed crl.pem file. You don't need to add any useful data in the requested information fields, we are generating the certificate only in order to revoke it afterwards:
 

vyatta:~/ca# ./build-key revokekey
Generating a 1024 bit RSA private key
.....................++++++
.....++++++
writing new private key to 'revokekey.key'
-----
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) [US]:
State or Province Name (full name) [CA]:
Locality Name (eg, city) [SanFrancisco]:
Organization Name (eg, company) [Fort-Funston]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [revokekey]:
Name []:
Email Address [me@myhost.mydomain]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /root/ca/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'US'
stateOrProvinceName :PRINTABLE:'CA'
localityName :PRINTABLE:'SanFrancisco'
organizationName :PRINTABLE:'Fort-Funston'
commonName :PRINTABLE:'revokekey'
emailAddress :IA5STRING:'me@myhost.mydomain'
Certificate is to be certified until Nov 14 20:17:53 2020 GMT (3650 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
vyatta:~/ca#

 
Next, revoke it:

vyatta:~/ca#./revoke-full revokekey
Using configuration from /root/ca/openssl.cnf
Revoking Certificate 02.
Data Base Updated
Using configuration from /root/ca/openssl.cnf
revokekey.crt: /C=US/ST=CA/L=SanFrancisco/O=Fort-Funston/CN=revokekey/emailAddress=me@myhost.mydomain
error 23 at 0 depth lookup:certificate revoked
vyatta:~/ca#

Ignore the error message, it's only becasue there is no crl.pem yet. (I believe)
 
A "ls-lai keys/" should reveal the new crl.pem now:
 

vyatta:~/ca# ls -lai keys/
total 88
120139 drwx------ 1 root root 4096 Nov 17 21:21 .
120112 drwxr-xr-x 1 root root 4096 Nov 17 21:00 ..
120648 -rw-r--r-- 1 root root 4163 Nov 17 21:12 01.pem
120698 -rw-r--r-- 1 root root 3949 Nov 17 21:17 02.pem
120644 -rw-r--r-- 1 root root 4163 Nov 17 21:12 minime.dvrdns.org.crt
120643 -rw-r--r-- 1 root root 741 Nov 17 21:12 minime.dvrdns.org.csr
120623 -rw------- 1 root root 887 Nov 17 21:12 minime.dvrdns.org.key
120556 -rw-r--r-- 1 root root 1383 Nov 17 21:06 ca.crt
120152 -rw------- 1 root root 887 Nov 17 21:06 ca.key
120706 -rw-r--r-- 1 root root 573 Nov 17 21:21 crl.pem
120704 -rw-r--r-- 1 root root 278 Nov 17 21:21 index.txt
120705 -rw-r--r-- 1 root root 20 Nov 17 21:21 index.txt.attr
120697 -rw-r--r-- 1 root root 20 Nov 17 21:17 index.txt.attr.old
120696 -rw-r--r-- 1 root root 265 Nov 17 21:17 index.txt.old
120707 -rw-r--r-- 1 root root 1956 Nov 17 21:21 revoke-test.pem
120694 -rw-r--r-- 1 root root 3949 Nov 17 21:17 revokekey.crt
120693 -rw-r--r-- 1 root root 684 Nov 17 21:17 revokekey.csr
120692 -rw------- 1 root root 887 Nov 17 21:17 revokekey.key
120695 -rw-r--r-- 1 root root 3 Nov 17 21:17 serial
120645 -rw-r--r-- 1 root root 3 Nov 17 21:12 serial.old
vyatta:~/ca#

 
Next and last thing we need to do for the server side is to create the Diffie-Hellman parameters file:
 

vyatta:~/ca#./build-dh
Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time
............................................................................+..............................................+...+.........................+......................................+.........+........+.....................................+.............................
[truncated]
vyatta:~/ca#

 
 
OK, no it's time to tell the Vyatta Code the OpenVPN Part. There are several ways to do that (tons of options), The following is a basic - but working - example. Here only the TLS Stuff is of interrest, the rest depends on your OpenVPN configuration and needs.
 

openvpn vtun0 {
local-port 443
mode server
openvpn-option "--comp-lzo --push route 192.168.0.0 255.255.128.0"
protocol tcp-passive
server {
subnet 192.168.255.0/24
topology subnet
}
tls {
ca-cert-file /root/ca/keys/ca.crt
cert-file /root/ca/keys/minime.dvrdns.org.crt
crl-file /root/ca/keys/crl.pem
dh-file /root/ca/keys/dh1024.pem
key-file /root/ca/keys/minime.dvrdns.org.key
}
}

 
One word: I case you wonder why I changed the default UDP/1194 to TCP/443: It just makes it easier to get through all kind of firewalls, UDP/1194 might be blocked :-)
 
Now you can create certificates for the clients. You to this with "./build-key $CLIENTNAME" just as you did above.
I recommend you choose something meaningful as the name for the certificate, e.g. the ADS name or the email address.
 
After you created the certificate, you need to send the following files to the client:
 

ca.crt
CLIENTNAME.crt
CLIENTNAME.key

 
If you found any errors, have suggestions, etc., just let me know below.

Comments

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options