OpenSSL Generate: Certificates, CSRs, and Self-Signed CA Certificates

If you’re a computer novice, start reading this at the top. If you know what you’re doing (even somewhat).

Introduction (Crash Course for Beginners)

SSL Certificates are all about trust. It’s how a website tells a user: “Hey, I’m trust worthy because other people trust me, so you should too.” The primary tool of that trust? OpenSSL. Depending on your needs, you might use OpenSSL to:

  1. Generate a self signed certificate
  2. Generage a CSR (Certificate Signing Request)
  3. Become your own CA (Certificate Authority), and if you do that:
  4. Sign CSRs that have been created by others.

This tutorial is going to teach you how to do each one of these tasks, but first, let’s discuss the public key infrastructure (PKI) and the  various degrees of trust it has. The PKI was established as a way to tell a complete stranger that another complete stranger is a good guy or a bad guy. When a webmaster decides they need a “secure” website (an httpswebsite), they seek out a certificate authority to give them a certificate. (“Give” is not really the appropriate word, “sell” might be better!). The webmaster is essentially paying the CA to vouch for them.

In order for the Certificate Authority (CA) to vouch for a webmaster and his site, they need (at least) a minimum amount of information about that webmaster and his site. This very basic information is:

  • Your Country
  • Your State / Province
  • Your Locality (City, Town, Village, etc…)
  • Your Organization Name
  • The Organization Unit Name (If you have one… could be “Sales” or “Corporate” or “IT DIvision”)
  • The common name (this is the full URL of your website)
  • Your email address.

This information, plus confirmation that you have control of that domain (via email or uploading a special file to the root of your website) is usually enough to get you a basic SSL certificate. These basic certificates can range anywhere between $5 – $80 depending on the vendor.

There are more expensive certificates out there, which go up in price from $200 – $10,000+. These are known as “EV” or “Extended Validation” certificates. In order to qualify for one of these certificates, you have to submit much more information about you and your company (as well as the basics above). EV Certificates give you that pretty green bar at the top of our browser. SSL certificate vendors sell this as a way to get the utmost trust from consumers, but the reality is that most consumers don’t know the difference. So, while it may underwhelm you to see that Bank of America is using an expensive, fancy EV certificate:

It may be very interesting to note that Amazon.com does not use an EV Certificate:

So, whether or not you choose to pony up the extra cash to get an EV certificate really boils down to answering two questions:

  1. Are my visitors / customers tech savvy enough to notice that I am using an EV certificate (and therefore trust me more)?
  2. Do I have the extra cash to buy an EV cert or will a standard certificate suffice?

In this tutorial, we are going to focus on standard SSL certificates and generating our own self-signed certs and self-signed Certificate Authority certificates because it’s completely free.

We’re not going worry about EV.

But, there is a VERY IMPORTANT distinction between purchasing an SSL cert from an established certificate authority versus generating your own (certificate or CA), and that’s called “the trusted root”.

Commercial Certificate Authorities like VeriSign, Digicert, GoDaddy, among others have their certificates in the “trusted root” of many operating systems. This means that when they sign your CSR and issue you a certificate where they vouch for you, the resulting certificate will be automatically accepted by FireFox, Chrome, Safari, and Internet Explorer without any further action. If you generate your own certificates, strangers that come to your site will get a certificate warning instead of a lock on their address bar.

There is a way around this problem if you become your own Certificate Authority and install certificates onall your computers (and the computers of all the users that will access your website or email system), but if you’re looking to allow strangers to be able to trust yoru site without installing software on their computers, servers, or mobile devices, you need to get a for-pay certificate from a commercial CA!

A Note on How Keys, Certificates and Cryptography Work

It’s important that you understand that modern cryptography works on the principle that two VERY large prime numbers form a key pair. These huge numbers are used because it is unfathomably difficult to factor the sum of two large prime numbers back into those two numbers. The public and private key are (essentailly) those two large numbers. If you have the private key, you can encrypt or decrypt information. If you have the public key you can only encrypt it. So, when you create a certificate, CSR, or get your key “signed” by a CA, you are essentially dealing with a pair of very large prime numbers and their sum. For more information, read Plain English: an RSA Encryption and Authentication Primer.

Common Certificate Generation Tasks in OpenSSL

Generating a CSR (Certificate Signing Request) with OpenSSL

The CSR (Certificate Signing Request) is a text file that we generate with OpenSSL, which contains both of the following items:

  1. The organization information (noted above as Country, Province, Locality, Organization, Unit, common name, and Email address)
  2. The public key that was generated as part of the key pair.

The information provided in #1 above must be cryptographically signed with the private key, or the CA will not be able to verify the information sent to them in the CSR. (When you sign information with a private key, you can forward that information along with a public key to a third party, and that third party can verify the signature using the public key – BUT they cannot duplicate the signature without the private key, which is always kepts secret, and never leaves your possesion).

Here’s the code to generate a private key (from which a public can will be derived) and a CSR that can be safely forwarded to a CA for signing:

openssl req -new -newkey rsa:2048 -nodes -keyout yourdomain.key -out yourdomain.csr

Here’s what’s going on with this command:

req tells OpenSSL that we are requesting something

-new makes it a new request for a…

-newkey, which takes the parameter: rsa:2048RSA is the type of key we are creating, and 2048 is the strength (length in bits, whcih is directly related to the complexity of th key).

-nodes is frequently confused as “nodes” when in reality it means “no DES” or, “do not produce a PKCS#12 compiant file. Most certificate authories cannot use this type of file; however, this is the type of file that IIS (Internet Information Services) on Windows Server systems uses to store their certificate files. Specifying -nodes means that the resulting file will not be encrypted, which is perfectly fine since you’re going to be transmitting a public key, which does not need protection as well as public information about yourself and your server.

-keyout tells OpenSSL to write the key to yourdomain.key. You can make this any output filename you want, but it makes the most sense to label it as yourdomain.key. Many people (myself included) use -yourdomain.tld.key, which is particularly useful if you own both the .net and .com of a particular domain name.

-out tells OpenSSL ‘write the certificate signing request to this file”. This is the file that you will transmit (in the clear) to the CA for signing.

Once you have completed this step, you’ll want to make sure that you keep your .key file under wraps. You don’t ever want to lose control of this file because then an evil actor (bad guys) could replicate your keys, decrypt your traffic, or even spoof your site’s online identity. The CSR, however, you can email to the CA for signing or use thier upload system to send it in to be signed.

Here’s what the execution of this command looks like:

You can see that the first thing it does is generate an RSA private key, then it writes that key to the specified output file, learnlinuxonline.com.key as I specified in the command on the first line. Next, you can see it asked me for information about myself, my site, and our location. Since learnlinuxonline.com is a free service of my company, High Powered Help, Inc., I entered in the company information. You should also notice that I left the challenge passwordblank. If you were to include a challenge password during the creation of these certificates, you would be required to enter the password into Apache every time you booted, restarted the web server or every time you restart or reload the Apache service. Ultimately, this inconvenience would cause you to end up stripping out the password anyway. So, don’t bother putting one in to begin with.

The resulting files that are generated are learnlinuxonline.com.key and learnlinuxonline.com.csr:

And, here’s what the contents of the CSR look like:

I’ll even show you what the private key looks like because this key was generated specifically for this tutorial, and discarded. So, try as you might, it isn’t going to help you spoof my site. But even still, I obfuscated a few lines anyway…

Generating a self-signed certificate with OpenSSL

self-signed certificate is nothing more than fulfilling a certificate signing request with a key you generated yourself. It’s a big like writing your own recommendation letter. Others will take it with a grain of salt. But, if you are dealing with a small number of users or just doing something in a testing environment, this can be an easy way to develop an application or website without having to go through the expense of buying a certificate from a certificate authority.

The self-signed certificate procedure is rather simple:

  1. Create a private key.
  2. Create a CSR for your server
  3. Sign the CSR with the private key

How to Create a Private Key for Self-Signed Certificates

As always, we’re going to execute an OpenSSL command:

<b>openssl genrsa -des3 -out server.key <b>2048</b>

Here’s how the command works:

  • genrsa tells OpenSSL to generate an RSA based private key.
  • des3 tells OpenSSL to use triple DES encryption
  • out tells OpenSSL where to write the resulting keys (into which file)
  • 2048 tells OpenSSL to use 2048-bit long modulus, which is the current standard (as of this writing).

The command execution looks like this:

You’ll notice that it asks for a pass phrase to protect the private key. You can make this a simple, easy to remember (and even weak) password for now because we are just going to remove it in later steps.

 Generate a CSR

Now that we have a key, you’ll need to generate a CSR as shown above (in great detail). Once you’ve done that, come back here, and proceed to the next step.

 Using OpenSSL to Self-Sign your CSR to create the Self-Signed Certificate

Now that we have a private key with which we can do the signing and a CSR that needs to be signed, we’re almost ready to generate the certificate. But, as noted above, we’re going to need to remove that pesky password that we added to the private key before we can get started. Why? Because if you retain the password, you’ll need to enter it every time you restart Apache or reboot the server. That can cause a lot of downtime. Without the password, Apache cannot read the certificate (since it was encrypted with 3DES using that password as the key).

To prevent this pandemonium, we’re just going to remove the password and rely on file system permissions and security to keep the key safe. So, first we’ll make a backup of the original key:?

cp server.key server.key.backup

Then we’ll remove the password with this command:?

openssl rsa -in server.key.backup -out server.key

This command tells OpenSSL to read -in the original key (that we’ve saved as a backup copy) and output a pure RSA key (with no encryption) to the -out file server.key.

Now that we have a private key without a password, we’re ready to sign the CSR with that key to create the self-signed certificate:

The OpenSSL command for this is:

openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

This command has the following paremeteres:

  • x509 is the certificate type, which has been standardized for the Public Key Infrastructure (PKI). This format is required for browsers to be able to interact with them properly.
  • -req tells open SSL we are dealing with a CSR (request).
  • -days tells OpenSSL we only want to vouch for this certificate for X number of days. In most cases, 365 days for a self-signed certificate is sufficient. (Later, when we start running our own CA, you’ll see that  value go up to 730 days – two years).
  • -in tells OpenSSL what file to use as the certificate signing request.
  • -signkey tells OpenSSL which private key to use for the signing
  • -out tells OpenSSL where to write the resulting certificate.

The whole process looks like this:

How to become your own CA (Certificate Authority)

Becoming your own CA (Certificate Authority) is nothing more than having a specific private key that you use to sign all CSRs. It is essentially the same process that we used above in the section about creating self signed certificates, but the difference is: instead of using a throw-away key, we re-use a single key AND we have to install that key on computers that we want to recognize and trust us.

But first, before we go through this effort, let’s discuss when and why we want to be our own CA:

  1. You are generating a number of self-signed certificates that a number of users will all need to know and trust. (And you’re looking to save some cash).
  2. You are running a VERY high security application where you want to maintain 100% control over the entire trust chain.
  3. You think it would be fun.

In any case, you’ll need to have the UTMOST security precautions surrounding your master CA private key. I highly recommend that you store it on an encrypted drive with very strict file permissions (600) so that ONLY your user can access and deal with the key. It should never be stored “in the cloud” and it should be backed up in multiple locations (also encrypted). If you choose to use a cloud backup service, the only one I would recommend would be Carbonite, but ONLY if you use their RSA encryption backup scheme.

Bascially, you have to treat this private key like the most improtant, confidential, and sensitive data possible because it is.

Setting Up your OpenSSL Config File and CA Directories

As a Certificate Authority, you need to setup basic information and configurations so that your entire system is consistent. We also need to have a nice place to store everything. So, let’s first create a directory to store everything in /root/ca. We have chosen the /root/ directory to hold this information because it should be the most guarded account on your system. So, first: become root using either the sudo or su command:

sudo su

Now, change directory to the root user’s home directory, and create a directory structure for the CA system:

cd ~/ mkdir ca cd ca mkdir private mkdir certs echo "101010" > serial echo -n > index.txt echo "101010" > crl_number

You should now be in /root/ca/, and have an additional sub-directories certs and private in that directory along with three files: serial, index.txt, and crl_number. The serial file holds the serial numbers that willbe assigned to certificates as they are issued. index.txt is the database that holds information about certificates. With this directory structure setup, we are ready to configure our openssl.cnf file for our CA.

Download our example-openssl.cnf, and customize it to your own settings. Be sure to fill in the blank areas, and rename the file to openssl.cnf from example-openssl.cnf.

Make sure you keep this in the same directory that your private key and other root-ca data will be kept!

Generating a CA Root Certificate with OpenSSL

First, we’ll need to generate our root-ca private key using this command:?

[openssl genrsa -des3 -out root-ca.key 4096/bash] Next, we'll need to create the root-ca certificate [bash]openssl req -new -x509 -days 3650 -key root-ca.key -out root-ca.crt -config openssl.cnf

Once these have been generated, we need to put them in the directories that are specified in the openssl.cnf file for the CA. If you used the defaults, that would be /root/ca/private.

Installing your CA certificate in the trusted certificates store

Installing the CA Certificate in Linux (Ubuntu / Debian)

  1.  Create a directory in /usr/loca/share/ca-certificates to hold your cert.
  2. Copy the cert to that directory
  3. Run update-ca-certificates.

For example, you can create the directory (as root):

mkdir /usr/local/share/ca-certificates/yourdomain.com

Now, copy the cert there, or download it from the web using wget.

cp ./mycert /usr/local/share/ca-certificates/yourdomain.com/

or

wget http://certs.yourdomain.com/yourcert.crt

Then, once that is there, run update-ca-certificates to automatically update the system to trust that new certificate.

When you do it correctly, you should see output similar to this:

Installing the CA Certificate in the Windows Trusted Root Store

In order for your CA Certificate to be put into the trusted root store of a Windows computer (or server), you must first convert it to p12 format. The command to perform this conversion is:

openssl pkcs12 -export -out server.p12 -inkey root-ca.key -in root-ca.crt

This will output a file, server.p12, which you can then transport to your windows server and install.

For a Windows Computers (Workstations or Servers, individually)

The certificate can be copied to the desktop, and then, just double click it:

Make sure you select the Local Machine, not Current User.

Next, browse to the location of the p12 file. Remember to keep this file secure because it contains the private key!

When prompted for the password for the private key, leave it blank since we did not set a password when we exported the key to p12 format.

When prompted, select Trusted Root Certification Authorities as the designated certificate store:

When prompted to select the certificate store, do not let it “automatically” select. This will place the certificate in the least invasive store possible. Usually a personal store. We want this to be trusted absolutely, so we’re going to purposefully place it in the Trusted Root Certification Authorities store:

Lastly, confirm the import:

To confirm that the certificate was installed properly, you can find it in the certificate manager in Windows. Check the Trusted Root Certificate Authorities store, and you should find your certificate there next to Godaddy, Equifax, DigiCert, and other famous CAs.

For a Windows Domain (Group Policy)

To roll out your trusted root certification network wide using group policy, see the Microsoft Knowledge-base Article Use Policy to Distribute Certificates.

 Installing the CA Certificate in the Trusted Root of Macs

This section will be written in the future. If you really want it, leave a comment below to ping me.

Signing CSRs with your CA Certificate

By the time you reach this section of this tutorial, you should know that a CSR is generated by a client / third party who wants you to vouch for them. In general, when you sign a certificate signing request you are saying: “I know this person / organization, and their resources are legit.” So, you wouldn’t want to sign CSRs without doing some sort of confirmation that they are who they say they are. Typically, this includes ensuring that they have control over the domain that the SSL certificate will be used (domain validation) or even going as far as doing a background check on them (Extended Validation style).

If you’re running your own CA because you have a need for a lot of certificates that your own users will all be using, then you can probably vouch for yourself!

Bottom line, when you receive a CSR from a third party, figure out who they are before you sign it. If you’re generating the CSR requests yourself, then there is no one to check up on.

To sign a CSR with your root-ca certificate, execute the following command:

openssl ca -config openssl.cnf -out client.crt -infiles client.req

This, of course, requires that you copy client.req into the /root/ca/ directory so that it can be accessed. Additionally, it requires that you are root as well.

In our example, we are going to generate a CSR as if we were a third party. (This is the same procedure described above, but shortened because we are using it as an example):

This example creates client.key in our /root/ca/ directory, but since we would normally never have this file when filling a CSR request, let’s delete it. Thus, at this point, we have essentially “copied” the CSR into the ca directory to fulfill the signing request as if it had come in via email. So, our directory currently looks similar to this:

Notice that the only “new” file here is client.csr.

Now we are ready to sign the CSR (assuming you’re ready to vouch for the requestor!). To sign the CSR:

openssl ca -config openssl.cnf -out client.crt -infiles client.csr

This process will require that you:

  1. Enter the password for the CA certificate.
  2. Verify the information for the cert is as you expected it
  3. Confirm the certification commit

The resulting file, client.crt, is the certificate the requester can use on the mail, web, or other servers.

Here’s What Else Just Happened:

When you executed the signing of the certificate, a few other things happened as well, which are part of the record keeping process.

  1. A copy of the signed certificate was stored in the certs/ directory as {serial}.pem.
  2. The serial number in the serial file was incremented by 1, and the original was saved as serial.old
  3. The database (index.txt) was managed to keep any relevant information.

Because these things happened, it is wise to keep backups of your CA directory.

Setting Up a VPN with Tinc VPN Software

Setting up a VPN can seem like a daunting task. There are some high-priced options out there, but most of those are closed source, and therefore not to be trusted. Instead, the internet has a variety of open source and free VPN server solutions. OpenVPN is a good one, but does not offer a distrbuted style “mesh network”. It requires a dedicated server, which may or may not be in your budget or scope. But, tinc-vpn offers “point to point” VPN as well as server style and everything in between.

As stated on the project homepage , tinc is a Virtual Private Network (VPN) daemon that uses tunnelling and encryption to create a secure private network between hosts on the Internet. It’s is an excellent way to create connections to servers and workstations over the internet. In particular, I came across it while looking for free alternatives to logmein.com. While tinc does not provide any sort of interface, it can be used to solve the problem of “permanent” remote access.

There are not a lot of great tutorials on the internet for tinc. So, we are going to take an in-depth look at exactly how to set-up a “server” and a client.

For starters, let’s build out our network on paper before we attempt to get it working in real life. In order to get around firewalls on remote networks, we have “punch through” by initiating a connection from within those remote networks. Routers assume that connections made by computers on the “inside” of their networks have permission to do so, and let those connections be made. Additionally, those same routers allow the return traffic through the firewall because: “what good is a request of we don’t allow the response back through to the requester?”

Thus, we need a centralized VPN “server” that all our remote nodes can connect to. Once we have that set-up, we can connect other computers (like a management workstation and a remote file server that we need to manage) to the VPN via the central node.

Setting up a VPN: the tinc VPN Basics

Up until now, I have been referring to a “server” for the central node. tinc does not have a “server”mode because all nodes are configured the same. For our purposes, the “server” we are configuring is a regular node that doesn’t connect to anyone else (pro-actively). Instead, it’s the place where “everyone else” connects to the network.

With that piece of information out of the way, let’s get back to the basics.

Order of Operations: How tinc reads configuration files (and in what order).

When tincd is started, the first thing it does is check /etc/tinc/nets.boot. Each line in that configuration file can contain the name of a network to join. For this tutorial, we are just going to use a single network, but you could set-up as many networks for your server as you wanted to.

After reading /etc/tinc/nets.boot, tinc goes to each network folder looking for a tinc.conf file. So, if your nets.boot file has a single entry: myvpn, tincd will look in /etc/tinc/myvpn/ for a tinc.conf file. (It will look for /etc/tinc/myvpn/tinc.conf).

Once it finds the tinc.conf file for this network, it will read it, and access information under the hosts directory for that network. So, if we use the “ConnectTo” directive to tell tincd that it should connect to a given server, it will look in /etc/tinc/myvpn/hosts/ for the value of that directive.

So, for example, if we are configuring a client (node) to ConnectTo a server that we have nicknamed “MainServer”, we’d use a directive like this:

ConnectTo=MainServer

Once tincd sees the value of that ConnectTo directive is “MainServer” it will immediately look in /etc/tinc/myvpn/hosts for the MainServer file. (It will want /etc/tinc/myvpn/hosts/MainServer). Once it finds that file, it will load configuration information about that host (node) from that file.

But, it also looks in the hosts directory to find information about itself! So, to get two computers to connect to one another, you must (at minimum) have two files in the hosts/ directory for your connections. One for the “server” and one for the “client”

But, tinc also uses the files in the hosts/ directory to get information about itself! As you’ll see in our example, we will create a file in hosts/ for machines each node will connect to as well as the node itself.

Authentication: How Each Node Knows It’s OK To Grant Access to the VPN Network.

tinc uses RSA authentication to authenticate nodes. If you’re not sure how RSA works, take a look at our RSA authentication primer. But for now, let’s suffice it to say that this is a key exchange. Each end of the node has to provide a key to be accepted by the other nodes

This means that each node has to have its own public / private RSA key pair. But don’t let that intimidate you, we’ll show you had to make these without having a Ph.D. in mathematics.

Preparing Your Computer

Whether you are running a server or a workstation, you have to make sure you have fulfileld the system requirements for tinc. They are:

  • A kernel that supports tun/tap. If you are using a modern version of any Debian based system, you’re already set here. (This includes Debian, Ubuntu, Mint, and other flavors). Most other modern Linux systems support this right out of the box. Except those distros that require you compile the kernel in order to install… but then again, if you’re using one of those experts-only distros, you won’t need much help installing this feature.
  • Make sure you have the following packages installed and available:
  1. OpenSSL
  2. zlib
  3. lzo

How to Install tinc-VPN

In Debian based systems, this is easy. Just use

apt-get install tinc

Do this for all the machines that will be participating in the VPN.

Setting up the Network

Do it on Paper First! Write down:

  1. Public IP of the “server”.
  2. VPN IP of the “server”.
  3. VPN IP of the “client(s)”

In our case, we are going to assume:

  • Public IP of the “server”: 12.345.67.89.
  • VPN IP of the “server”: 192.168.100.1
  • VPN IP of the client: 192.168.100.2

How To: Setting up the tincd “Server”

Setting up the “server” simply means we need to setup the files tinc uses in the order that it uses them:

  1. nets.boot
  2. the network directory
  3. tinc.conf in the network directory
  4. the hosts directory for the network
  5. the individual host files for hosts on the network.
  6. tinc-up
  7. tinc-down

First, change to the /etc/tinc/ directory, and edit the nets.boot file. We are going to add a single line to the end of the file: myvpn.

echo 'myvpn' >> nets.boot

Next, create the myvpn folder under /etc/tinc because tincd is going to look in that folder after it discovers that nets.boot has “myvpn” as one of the entries.

mkdir /etc/tinc/myvpncd /etc/tinc/myvpn

Next, create the tinc.conf file, which tells tincd how to setup its own node. Using your favorite Linux text editor (vim!), create tinc.conf with these two lines in the file:

Name=vpnserverDevice=/dev/net/tun

Save the file.

This, of course, assumes you are running a Debian based system that has a device at /dev/net/tun. Most do. But, if your distro doesn’t, you can change this to something like /dev/tap0 of you have tunctl installed. But for our example, we’re going to leave it like  this.

Now, if you remember from our order of operations above, as soon as tincd finds this file, it’s going to look for mycpn in the hosts directory. So, we need to create that directory so we can create the file.

mkdir /etc/tinc/myvpn/hosts

But we don’t create the myvpn file that goes in hosts/! That will be created for us when we generate the RSA keys for this system. So, let’s generate the keys:

tincd -n myvpn -K

If you haven’t set-up the tinc.conf file correctly (or yet), This command will generate two keys: rsa_key.priv and rsa_key.pub. Both of these will appear in your /etc/tinc/myvpn/ directory (because we specified -n myvpn in the command above). These two keys represent the keys to THIS system. So, we’ll keep the private key where  it is, but let’s move the public key into hosts:

mv /etc/tinc/myvpn/rsa_key.pub /etc/tinc/myvpn/hosts/vpnserver

If you DID correctly set-up your tinc.conf file, tincd will read that file, and find the name of this computer and use it to put the public key in the correct spot. So, instead of creating the public key as /etc/tinc/myvpn/rsa_key.pub, it should read Name=vpnserver, and put the public key in /etc/tinc/myvpn/hosts/vpnserver.

Right now, that file (/etc/tinc/myvpn/hosts/vpnserver) only contains the RSA public key, but we need to add some more information about this node to that file. So, let’s edit that file:

vim /etc/tinc/myvpn/hosts/vpnserver

and add some lines to it to identify the node both to itself, and later, to the other nodes on the network. We’ll add two lines: Subnet and Address.

Subnet identifies the IP address this node will have on the VPN network. Address identifies (to other nodes) what IP address they should use to connect to this server.

Subnet=192.168.100.1Address=12.345.67.89-----BEGIN RSA PUBLIC KEY-----MIIBCgKCAQEAoEgxyY5DANAlKSP3pkHJvX5Co1uihxcCwFGW7G3bXUsKTkg6TE1Pqs7Fae9HQIYPzu0uHhjR0jFNP0rAEWl3VoQnpe3E6uIBs+8PWlIpB6OvLXjaYbo7FhCje3OYTQMDwbhGaeZ/TdoOvAhHlu8giHZFc4SZ/Bd4z58UmLC5ShAtHKhMJr6KdYsZjBWnz341Q/dY+NRW5RXpH8akt8yW7xw/9So8CM3Lyf9Vvtn1RyY0IJcIq1kVUXYOmx/j5Ef48GrbziF5DhEhYCqVSYzqfeIS0PKesNyTWvqr0/n2owSH3q5a2mNIb+DuppRFSWxzkymrvrGfxVRuhi1Hj5lQPwIDAQAC-----END RSA PUBLIC KEY-----

Lastly, we need to set-up the tinc-up and tinc-down scripts. These scripts execute automatically when the VPN network comes up and when the VPN network goes down (respectively).

Essentially, we need these scripts to create the interface that the computer will use to talk to the VPN network when the VPN comes up, and then remove it when the VPN service stops.

Create a file called /etc/tinc/myvpn/tinc-up, and put the following lines of code in it:

#!/bin/bashifconfig $INTERFACE 192.168.100.1 netmask 255.255.255.0

Because tincd runs in router mode by default, we do not need to put any other configurations (or routes) in this file because tincd will build and maintain routing tables for us.

Now for tinc-down, which will execute when we shut down tinc and disconnect from the VPN. Create a file: /etc/tinc/myvpn/tinc-down, and add this content.

#!/bin/bashifconfig $INTERFACE down

This removes the vpn adapter from the system when the vpn service is shut down.

Once you have created those two files, you have to grant them permission to execute:

chmod +x /etc/init.d/myvpn/tinc-*

Now, you’re ready to start the tinc vpn server:

/etc/init.d/tinc start

If all goes well, you should see the following in syslog:

tincd 1.0.19 (Apr 22 2013 21:45:36) starting, debug level 9/dev/net/tun is a Linux tun/tap device (tun mode)Executing script tinc-upListening on 0.0.0.0 port 655Listening on :: port 655Ready

If you see any errors, google them, fix them, and then restart tinc until the errors resolve.

Setting up the VPN Clients

Because a “server” and a “client” have just ONE difference (the Server doesn’t use a ConnectTo directive in tinc.conf), The basic setup is exactly the same. So, follow the steps above to setup your client(s), but note these differences in /etc/tinc/myvpn/tinc.conf:

  • Clients will use a “ConnectTo” directive.
  • Clients need to be uniquely named. The server uses Name=vpnserver, but the clients should have their own individual (unique) network names. Name=Client01 would work, so would Name=George.

There is two major differences for clients in the public rsa key, which is stored in hosts/ for the network:

  • The Name directive must be unique
  • The subnet must be a different IP for the client than the server has.

Here is an example tinc.conf for a client:

Device=/dev/net/tunConnectTo=webservicesName=George01

Notice the Name is unique (this is for “George’s computer”) and it also uses the ConnectTo directive to tell this client node to connect to the main vpn server node.

Here is an example /etc/tinc/myvpn/hosts/George01 file:

Name=George01Subnet=192.168.100.2-----BEGIN RSA PUBLIC KEY-----MIIBCgKCAQEAzkkYpNIWSrm1kNX49PXYZR4SALGUtDY/iKHVGF2oqvsoKhl5hENiiNw9QqUtKUSDuJxP8w2AbeHBYaqr9kVyw3c/2Vzp1oGIxpbtMRcSEDJUcgJlpNeJ8iEvjEPUiliLNrfnpu7dEk8gT6Fu+b94R1n/5JnLueny3i0p8+qbA5/z4KUqVQCHnQqcDQ+8DY2Otrljae6YwEMgtShtUNA6nkUfJ61Y/2UITL6RQP7rAXbn3kJYozm/gjJPQ4W0oUlTSFwM2qziGIj68KrUXBj6V3VjInuVdAgFii6B2aXI+qUst705B/Bw+BZIsQxiKNruU+gi/+aQx2mtP2YPiTYk1QIDAQAB-----END RSA PUBLIC KEY-----

Notice:

  • the file name matches the Name directive in the /etc/tinc/myvpn/tinc.conf file.
  • The Subnet is different than the server. In this case, it is the next available address, but it doesn’t half to be. It could be any address on the 192.168.100.0/24 network.

Now, your client is setup! Start the tincd service and watch /var/log/syslog for errors that need correcting:

/etc/init.d/tinc start

The Last Step: Exchanging Keys

As mentioned in the introduction as well as in our RSA Authentication Primer, both sides of the VPN need to exchange public keys so that the “conversation” can actually take place.

So, let’s use secure copy to copy the vpnserver public key to the client. From the client:

cd /etc/tinc/myvpn/hostsscp root@12.345.67.89:/etc/tinc/myvpn/hosts/vpnserver .

If (when) prompted to enter your password, enter the password for the VPN server’s root account.

Now, let’s send the client public key to the vpn server:

cd /etc/tinc/myvpn/hostsscp George01 root@12.345.67.89:/etc/tinc/myvpn/hosts

Testing Your Connection

If all has gone well, you’ll now be able to ping the machines over the vpn network. From the “client” node:

ping -c4 192.168.100.1

should give you:

PING 192.168.100.1 (192.168.100.1) 56(84) bytes of data.64 bytes from 192.168.100.1: icmp_req=1 ttl=64 time=1.15 ms64 bytes from 192.168.100.1: icmp_req=2 ttl=64 time=0.905 ms64 bytes from 192.168.100.1: icmp_req=3 ttl=64 time=0.979 ms64 bytes from 192.168.100.1: icmp_req=4 ttl=64 time=0.943 ms

Form the server node, you should be able to execute:

ping -c4 192.168.100.2

and get:

PING 192.168.100.2 (192.168.100.2) 56(84) bytes of data.64 bytes from 192.168.100.2: icmp_req=1 ttl=64 time=1.15 ms64 bytes from 192.168.100.2: icmp_req=2 ttl=64 time=0.905 ms64 bytes from 192.168.100.2: icmp_req=3 ttl=64 time=0.979 ms64 bytes from 192.168.100.2: icmp_req=4 ttl=64 time=0.943 ms

Special Thanks

Special thanks to Guus Sliepen, who not only developed tinc-vpn, but also generously provides support via his tinc-vpn mailing list

RSA Encryption and Authentication Primer

RSA Encryption is a cryptographic system that uses public and private keys to exchange messages. It was first published in 1977 by Ron Rivest, Adi Shamir, and Leonard Alderman. RSA stands for Rivest, Shamir, and Alderman.

The system works by generating two RSA encryption keys: one public and one private. The key generation itself requires a good random number generator and the ability to resolve very large prime numbers. (Wikipedia has a more precise explanation of how the keys are generated, but this is sufficient for our purposes).

The public key can:

  • Encrypt messages destined for the person who has the corresponding private key.

The private key can:

  • Encrypt messages for anyone who has a the public key (not used often)
  • Decrypt messages encrypted with the private key (99.9% of all usage)
  • Sign messages to authenticate “I am who I say I am”

The public key can be used to encrypt messages, but only the private key can decrypt messages.

Because a public key can encrypt, but only the corresponding private key can decrypt, this means:

  • I have to keep my private key a secret. I can’t share it, email it, or let anyone see / touch it.
  • I can give my public key to anyone without regard. I can publish it on the internet if I like.
  • This public / private key set can only be used to send me messages. If I want to send someone else a message, my keys won’t work.

This last point is very crucial. In order to have a conversation, you and your friend both have to have a public and private key set. You will keep your private key a secret, and your friend will keep theirs a secret. But, you have to email your public key to your friend and your friend has to email you their public key.

Once the exchange of public keys is complete, you can have a conversation.

How a Conversation Works

There are two parties to the conversation: You and your friend (who we will call “Friend” for simplicity’s sake).

  1. You send friend your public key.
  2. Friend sends you their public key.
  3. You use Friend’s public key to encrypt a message to them.
  4. You send the encrypted message to Friend.
  5. Friend receives the message.
  6. Friend uses his private key to decrypt the message.
  7. Fried reads the message.
  8. Friend uses your public key to encrypt his response.
  9. Friend sends you the message encrypted with your public key.
  10. You receive the message from your friend.
  11. You decrypt the message using your private key.
  12. You read the message.

At this point, if you want to respond, you’ll return to step 3 and repeat steps 3-12 until the conversation ends.

How RSA Authentication Works

RSA Authentication works similarly to how a conversation between two friends works above. The Both sides have to have private keys, and both sides must exchange their public keys so the other side has it. Then, a system known as challenge-response is used to prove to both sides that each is the entity it claims to be.

Typically, a server administrator will setup an application, system service, or daemon to use RSA keys for authentication. When they do this, they:

  1. Generate a public / private key pair for server A
  2. Generate a public / private key pari for server B.
  3. Give server A server B’s public key so that Server A can validate server B when it tries to sign in.
  4. Give server B server A’s public key so that it can validate Server A when it tries to sign in.
  5. Start the relevant system services or daemons.

Now, when server A attempts to authenticate with server B, the conversation goes something like this:

Server A: “Hello. I am Server A. I would like access please.”

Server B looks at the request, and doesn’t trust this “computer” who claims to be server A. So, Server B looks up the public key for Server A, and generates a random “challenge”, which it encrypts with server A’s public key. It then sends the encrypted challenge to the computer claiming to be server A.

Server A receives the encrypted challenge. Since Server A really is who it claims to be, this server has the private key needed to decrypt the challenge from Server B. So, it uses the private key to decrypt the message and finds out that the challenge phrase is “I love world peace and fluffy bunnies”. But, at this point, Server A still needs to convince Server B that they really are the computer they say they are. At the same time, we can’t send the challenge message back to server B in plain text. So, Server A uses Server B’s public key to re-encrypt the message, and then sends it back to server B. This is called the response.

Server B receives the response, decrypts it using its private key, and then checks to make sure the response message is identical to the challenge message. If it is, Server B will grant access. If it’s not, no access will be granted.

Note: In reality, the challenge string will not be human readable. It is much more likely to be a series of randomly generated values like: sxCz3yQ0jj94TNBHCavAK43jiIkOVOTBkSA4oQGClXw=