TLS, or transport layer security, and its predecessor SSL, secure sockets layer, are secure protocols created in order to place normal traffic in a protected, encrypted wrapper.
These protocols allow traffic to be sent safely between remote parties without the possibility of the traffic being intercepted and read by someone in the middle.
They are also instrumental in validating the identity of domains and servers throughout the internet by establishing a server as trusted and genuine by a certificate authority.
In this guide, we'll cover how to create a self-signed SSL certificate for Apache on an Ubuntu server, which will allow you to encrypt traffic to your server.
To enable TLS between the server and client you need to setup both the server and the client with appropriate certificates and configuration. The following instructions walk you through the setup process.
Pre-requisites
Before you begin, you should have some configuration already taken care of.
We will be operating as a non-root user with sudo privileges in this guide.
You are also going to need to have Apache installed. If you don't already have that up and running, you can quickly fix that by typing:
> sudo apt-get update > sudo apt-get install apache2
Step One — Activate the SSL Module
SSL support actually comes standard in the Ubuntu 14.04+ Apache package. We simply need to enable it to take advantage of SSL on our system.
Enable the module by typing:
> sudo a2enmod ssl
After you have enabled SSL, you'll have to restart the web server for the change to be recognized:
> sudo service apache2 restart
With that, our web server is now able to handle SSL if we configure it to do so.
Using self-signed certificate.
Step Two — Create a Self-Signed SSL Certificate for the Server/Client
While doing this always keep in mind that the root CA certificate you will create now is used by the webserver as comparison to the final webserver certificate and that this root CA certificate must be imported in your browser.
For doing this without any oncoming problems we advise to create RSA keys without a passphrase; otherwise Apache and your browser will not be able to resolve the certificate chain!
On the server create a couple of directories for working with the certificates:
SERVER: mydir> mkdir $HOME/buildcerts mydir> mkdir $HOME/certs
Copy the following script to the buildcerts directory that was just created:
#!/bin/sh # File Name "generate-keys.sh" # mkdir -p $HOME/buildcert # cd $HOME/buildcert # rm -f *.key *.csr *.crt *.pem *.srl SUBJ="/C=/ST=/L=/O=/CN=ca" # Generate CA Private Key openssl req \ -newkey rsa:2048 \ -nodes \ -keyout ca.key \ -subj $SUBJ # Generate Req openssl req \ -key ca.key \ -new -out ca.csr \ -subj $SUBJ # Generate self signed x509 openssl x509 \ -signkey ca.key \ -in ca.csr \ -req \ -days 365 -out ca.crt ## Change restconf to your entry-point SUBJ="/C=/ST=/L=/O=/CN=restconf" # Generate Server Private Key openssl req \ -newkey rsa:2048 \ -nodes \ -keyout server.key \ -subj $SUBJ # Generate Req openssl req \ -key server.key \ -new -out server.csr \ -subj $SUBJ # Generate x509 with signed CA openssl x509 \ -req \ -in server.csr \ -CA ca.crt \ -CAkey ca.key \ -CAcreateserial \ -out server.crt SUBJ="/C=/ST=/L=/O=/CN=client.com" # Generate Client Private Key openssl req \ -newkey rsa:2048 \ -nodes \ -keyout client.key \ -subj $SUBJ # Generate Req openssl req \ -key client.key \ -new -out client.csr \ -subj $SUBJ # Generate x509 with signed CA openssl x509 \ -req \ -in client.csr \ -CA ca.crt \ -CAkey ca.key \ -out client.crt echo "" echo " == Validate Server" openssl verify -verbose -CAfile ca.crt server.crt echo "" echo " == Validate Client" openssl verify -verbose -CAfile ca.crt client.crt
Cd to the buildcerts directory, run the key generation script and check the files were created:
SERVER: mydir> cd buildcerts buildcerts> ./generate-keys.sh buildcerts> ls -l -rw-rw-r-- 1 user group 956 Mar 16 15:05 ca.crt -rw-rw-r-- 1 user group 883 Mar 16 15:05 ca.csr -rw-rw-r-- 1 user group 1708 Mar 16 15:05 ca.key -rw-rw-r-- 1 user group 17 Mar 16 15:05 ca.srl -rw-rw-r-- 1 user group 969 Mar 16 15:05 client.crt -rw-rw-r-- 1 user group 891 Mar 16 15:05 client.csr -rw-rw-r-- 1 user group 1708 Mar 16 15:05 client.key -rwxrwxr-x 1 user group 1513 Feb 23 16:29 generate-keys.sh -rw-rw-r-- 1 user group 969 Mar 16 15:05 server.crt -rw-rw-r-- 1 user group 891 Mar 16 15:05 server.csr -rw-rw-r-- 1 user group 1704 Mar 16 15:05 server.key
Copy the server certificates to their proper places:
SERVER: buildcerts> sudo cp ca.crt /usr/local/share/ca-certificates/ buildcerts> sudo cp client.crt /etc/ssl/certs/ buildcerts> cp server.crt ../certs/ buildcerts> cp server.key ../certs/
For the client certification, if the client is not localhost, also create a couple of directories on your client machine for working with the certificates:
CLIENT: mydir> mkdir $HOME/buildcerts mydir> mkdir $HOME/certs
On the server copy the files you created to the client machine using sftp:
SERVER: mydir> cd $HOME/buildcerts buildcerts> sftp CLIENT_USERNAME@CLIENT sftp> cd buildcerts sftp> put * sftp> bye
Now copy the certificates on the client to their proper places:
CLIENT: mydir> cd $HOME/buildcerts buildcerts> sudo cp ca.crt /usr/local/share/ca-certificates buildcerts> sudo cp server.crt /etc/ssl/certs buildcerts> cp client.crt $HOME/certs/ buildcerts> cp client.key $HOME/certs/
If you want to run client and server on localhost, copy client certificates described in the previous step to the same place you copied server certificates.
Go to the /etc/ssl/certs directory, run updates and check the results:
SERVER: buildcerts> cd /etc/ssl/certs #make sure system does not have any previously installed certificates etc/ssl/certs> sudo rm /etc/ssl/certs/ca.pem etc/ssl/certs> sudo update-ca-certificates etc/ssl/certs> ls -l | grep ca.crt lrwxrwxrwx 1 root root 39 Mar 16 15:52 ca.pem -> /usr/local/share/ca- certificates/ca.crt etc/ssl/certs> ls -l | grep client.crt lrwxrwxrwx 1 root root 10 Mar 16 15:52 55a71c96.0 -> client.crt lrwxrwxrwx 1 root root 10 Mar 16 15:52 ca0a1cd4.0 -> client.crt -rw-r--r-- 1 root root 969 Mar 16 15:43 client.crt
Generate the client Fingerprint:
certs> cd $HOME/buildcerts buildcerts> openssl x509 -noout -fingerprint -sha1 -inform pem -in client.crt SHA1 Fingerprint=4B:A7:05:1E:12:F7:BC:FF:2D:9E:48:66:0A:8B:CC:D7:A5:65:E5:97
Add following four parameters lines in /etc/yumapro/netconfd-pro.conf and substitute the Fingerprint value.
netconfd-pro { with-netconf-tls true netconf-tls-certificate ~/certs/server.crt netconf-tls-key ~/certs/server.key cert-usermap <YOUR_USERNAME>@<first_six_pairs_of_the_SHA1_Fingerprint> }
Repeat the same steps on your client (if you are not running client and server on localhost)
CLIENT: buildcerts> cd /etc/ssl/certs etc/ssl/certs> sudo update-ca-certificates etc/ssl/certs> ls -l | grep ca.crt lrwxrwxrwx 1 root root 39 Mar 16 16:25 ca.pem -> /usr/local/share/ca- certificates/ca.crt etc/ssl/certs> ls -l | grep server.crt lrwxrwxrwx 1 root root 10 Mar 16 16:25 5ec6e3b0.0 -> server.crt lrwxrwxrwx 1 root root 10 Mar 16 16:25 942ef14c.0 -> server.crt -rw-r--r-- 1 root root 969 Mar 16 16:24 server.crt
Step Three — Configure Apache to Use TLS protocol and generated certificates
Now that we have our certificate and key available, we can configure Apache to use these files in the RESTCONF virtual host file.
Open the file with root privileges now:
> sudo <your_editor> /etc/apache2/sites-available/restconf.conf
Replace <your_editor> with the editor of your choice such as vi, vim, emacs, gedit, etc.
And add the following configurations into the file:
<IfModule mod_ssl.c> <VirtualHost *:443> DocumentRoot /var/www/yang-api #### CHANGE 'localhost' to match your server name ServerName localhost AllowEncodedSlashes On AddHandler fcgid-script .fcgi #### CHANGE '/var/www/yang-api' to match DocumentRoot if needed <Directory /var/www/yang-api> SetHandler fcgid-script Options Indexes FollowSymLinks ExecCGI AllowOverride all Order allow,deny allow from all </Directory> #### CHANGE '/var/www/yang-api' to match DocumentRoot if needed <Directory /var/www/yang-api/.well-known> SetHandler default-handler ForceType 'application/xrd+xml' ## enable mod_headers to use the following directives ## > a2enmod headers Header unset Etag Header unset Last-Modified Header unset Accept-Ranges Header set Cache-Control no-cache Header merge Cache-Control no-store Header set Pragma no-cache ## Ony GET is allowed <Limit POST PATCH DELETE PUT> Order deny,allow Deny from all </Limit> AllowOverride all Order allow,deny allow from all </Directory> SSLEngine on #### CHANGE '/home/user' to your certificates dir SSLCertificateFile /home/user/certs/server.crt SSLCertificateKeyFile /home/user/certs/server.key </VirtualHost> </IfModule>
Save and exit the file when you are finished.
Step Four — Activate the TLS Virtual Host
Now that we have configured our TLS-enabled virtual host, we need to enable it:
> sudo a2ensite restconf.conf
We then need to restart Apache to load our new virtual host file:
> sudo service apache2 restart
This should enable your new virtual host, which will serve encrypted content using the TLS certificate you created.
To verify that the site was loaded correctly examine the output of the following command:
> sudo apache2ctl -S AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message VirtualHost configuration: *:443 localhost (/etc/apache2/sites-enabled/restconf.conf:24) *:80 is a NameVirtualHost default server localhost (/etc/apache2/sites-enabled/restconf.conf:74) port 80 namevhost localhost (/etc/apache2/sites-enabled/restconf.conf:74) ServerRoot: "/etc/apache2" Main DocumentRoot: "/var/www/html" Main ErrorLog: "/var/log/apache2/error.log" Mutex default: dir="/var/lock/apache2" mechanism=fcntl Mutex fcgid-pipe: using_defaults Mutex watchdog-callback: using_defaults Mutex rewrite-map: using_defaults Mutex ssl-stapling-refresh: using_defaults Mutex fcgid-proctbl: using_defaults Mutex ssl-stapling: using_defaults Mutex ssl-cache: using_defaults PidFile: "/var/run/apache2/apache2.pid" Define: DUMP_VHOSTS Define: DUMP_RUN_CFG User: name="www-data" id=33 Group: name="www-data" id=33
As shown in the output we have configred our Web server as a localhost Virtual Host that listens on port 443 for any incoming connection from clients.
Step Five — Test your Setup
Now that you have everything prepared, you can test your configuration by visiting your server's domain name or public IP address after specifying the https://
protocol.
Via browser, you will need to add your self-signed certificate into browser. Open Browser's Certificate Manager and import Your Certificate.
Via yangcli-pro:
Next you need to configure the client with the parameters needed to use TLS by editing the yangcli-pro.conf file. If you have an existing yangcli-pro.conf then add the following parameter lines,
within “yangcli-pro {“ and “}”, to the existing file. If you don’t have an existing yangcli-pro.conf file then run your editor as shown and a yangcli-pro.conf file will be created, then add the lines shown.
buildcerts> sudo <your_editor> /etc/yumapro/yangcli-pro.conf
Replace <your_editor> with the editor of your choice such as vi, vim, emacs, gedit, etc.
Add the following parameters:
yangcli-pro { ssl-fallback-ok false ssl-certificate $HOME/certs/client.crt ssl-key $HOME/certs/client.key ssl-trust-store $HOME/certs/ca.crt }
Run yangcli-pro on the client and connect using the command show below:
CLIENT: mydir> yangcli-pro user=<username> server=<SERVER_HOST> protocol=restconf transport=tls