Self Signed Ssl Cert

 

Self Signed SSL Certificate for Servers with no Domain

Server: Apache2 \ Platform: Ubuntu server 16.04 LTS

Create Root CA

Generate Root Key

openssl genrsa -des3 -out rootCA.key 4096

Remove -des3 option if you want a key with no pass phase protected.

Create and self sign the Root Certificate

openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.crt

Here we create a root certificate using the root key.
Option -x509 refers to the protocol of self-signed certificate.
Value following -days refers to the lifespan of this certificate as in days.

Create Certificate for Each Server

Create the certificate key

openssl genrsa -out server-a.key 2048

Create signing request file

When creating a request file, you need to specify the information of this address. You can just use this line of script to creating this file. You need to enter all the information after this script is executed.

openssl req -new -sha256 -nodes -newkey rsa:2048 -keyout server-a.key -out server-a.csr

Or, there is a more elegant way. You can create a config file named server-a.csr.conf, in which you can enter all the information needed. Notice that all the items in this file needs to be filled.

[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn

[dn]
C=CN
ST=Beijing
L=Beijing
O=THU
OU=Network Architecture Lab
emailAddress=kongxiao0532@gmail.com
CN = 101.6.30.207

Then run this line of script below and the request file will be created.

openssl req -new -sha256 -nodes -out server.csr -newkey rsa:2048 -keyout server.key -config <( cat server-a.csr.conf )

Generate the certificate using the request file and server key along with the CA Root key

Here comes the tricky part. I was stuck here for half of a day. After version 58, Chrome requiresd Subject Alt Name domain to be filled in the certificate file or it will show the Privacy Error page. To solve this problem, a ext file is needed when creating the certificate. The file is as follows.

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = %%DOMAIN_NAME%%

In this case, we do not have a domain. So I simply replace %%DOMAIN_NAME%% with the IP address. But it didn’t work. The problem is that the name of the attribute should be IP.1 rather than DNS.1.

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
IP.1 = 101.6.30.207

Run the following script after creating the ext file above, and you will get the certificate file for the server.

openssl x509 -req -in server-a.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server-a.crt -days 9999 -sha256 -extfile v3.ext

Trust the root certificate on clients

Since we create the certificate using the root certificate generated by our own, we need to trust the root certificate on every client machine in order to set up HTTPS connection.

Windows

Double click the root certificate file and install. Remember to store it in the category of Trusted Root Certificates.

Ubuntu

Copy the .crt file into */usr/local/share/ca-certificates, and run the script below.

update-ca-certificates

Redirect all HTTP traffic to HTTPS

Add the following line to http server config file (/etc/apache2/sites-enabled/owncloud.conf in this case), and turn on rewrite mod in apache2 by running sudo a2enmod rewrite in shell.

RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteRule   ^(.*)  https://%{SERVER_NAME}:4430$1 [L,R]