Hero Image

PKI advenced

We use the certificate server to create certificates and enable secure connection between all our servers and services. We do not need large resources for CA server. I choose 1Gb RAM, a CPU and 10Gb hard disk but we can run it on 512Mb RAM and 3Gb HD.

sudo virt-install --virt-type kvm --name ca \
  --location \
  https://deb.debian.org/debian/dists/bullseye/main/installer-amd64/ \
  --memory 1024 \
  --vcpus 1 \
  --disk pool=vmdisks,size=10,format=qcow2 \
  --network bridge=br0 \
  --hvm \
  --graphics none \
  --console pty,target_type=serial \
  --extra-args "console=ttyS0"

Configure Debian

Edit nano /etc/network/interfaces and set a static IP address:

source /etc/network/interfaces.d/*
auto lo
iface lo inet loopback
allow-hotplug ens2
iface ens2 inet static

sudo nano /etc/resolv.conf

search yourdomain.com

Set the system language to English to make it easier to find problems in the logs:

apt install locales-all
localectl set-locale LANG=en_US.utf8
localectl status

Update Debian and install the necessary administration tools

apt update
apt install wget sudo screen nmap telnet tcpdump rsync net-tools dnsutils htop \
apt-transport-https vim gnupg lsb-release

Create nano /etc/sudoers.d/10-nopasswd and add


Configure VIM

Open nano /etc/vim/vimrc and replace all its contents with:

runtime! debian.vim
syntax on
set background=dark
au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
filetype plugin indent on
set encoding=utf-8
set nobackup
set nowritebackup
set showcmd
set updatetime=300
set showmatch
set ignorecase
set smartcase
set incsearch
set tabstop=2
set softtabstop=2
set shiftwidth=2
set expandtab
if filereadable("/etc/vim/vimrc.local")
  source /etc/vim/vimrc.local

Create users vim config file nano ~/.vimrc and add:

set mouse=
set nocompatible
set cursorline
set nocursorcolumn
set nowrap
set showmode
set hlsearch
set wildmenu
set wildmode=list:longest
set wildignore=*.docx,*.jpg,*.png,*.gif,*.pdf,*.pyc,*.exe,*.flv,*.img,*.xlsx

From now on we will use VIM insteed for nano.


I am going to guide you trought quick configuration off certificate authority, and I am going to publish necessary files.


sudo mgdir /srv/pki
sudo chown -R emir:emir /srv/pki
cd /srv/pki

Create directories

mkdir -p private certs csr crl certs_by_serial intermediate/certs \
intermediate/private intermediate/csr intermediate/crl \

Create index.txt files

touch index.txt intermediate/index.txt private/.rand intermediate/private/.rand

Create CA serial files for both Root/Intermediate CA’s (Use any 4 digit number)

echo 1000 > serial
echo 1000 > intermediate/serial

Create CRL serial files for both Root/Intermediate CA’s (Use any 4 digit number)

echo 1000 > crlnumber
echo 1000 > intermediate/crlnumber


Generate root key and certificate: (Rambler Root CA)

openssl genrsa -aes256 -out private/root.key
openssl req -config openssl-root.cnf -days 14600 -new -x509 -sha512 -extensions v3_ca -key private/root.key -out root.pem
Show certificate
openssl x509 -in root.pem -text

Generate intermediate key, reqs, and certificate: (Rambler Intermediate CA)

openssl genrsa -aes256 -out intermediate/private/intermediate.key
openssl req -config intermediate/openssl-intermediate.cnf -new -key intermediate/private/intermediate.key -out intermediate/csr/intermediate.csr
openssl ca -config openssl-root.cnf -extensions v3_intermediate_ca -days 14600 -md sha512 -in intermediate/csr/intermediate.csr -out intermediate/intermediate.crt
Create intermediate certificate in pem (base64) format
openssl x509 -in intermediate/intermediate.crt -out intermediate/intermediate.pem

Generate CA chain file

cat intermediate/intermediate.crt root.pem > intermediate/chain.crt

and chain file in pem format:

cat intermediate/intermediate.pem root.pem > intermediate/chain.pem

Generate CRL files

openssl ca -config openssl-root.cnf -gencrl -out crl/root.crl
openssl ca -config intermediate/openssl-intermediate.cnf -gencrl -out intermediate/crl/intermediate.crl

Generate a server certificate DC01

Edit vim intermediate/openssl-server.cnf and change DNS name:

[ alt_names ]
DNS.0 = dc01.yourdomain.com
DNS.1 = dc02.yourdomain.com
openssl genrsa -aes256 -out intermediate/private/dc01.key
openssl req -config intermediate/openssl-server.cnf -new -key intermediate/private/dc01.key -out intermediate/csr/dc01.csr
openssl ca -config intermediate/openssl-server.cnf -extensions server_cert -days 10950 -in intermediate/csr/dc01.csr -out intermediate/certs/dc01.crt
sudo openssl x509 -in intermediate/certs/dc01.crt -out intermediate/certs/dc01.pem

Remove encryption from private key

openssl rsa -in intermediate/private/dc01.key -out intermediate/private/dc01-key.pem

Combine Cert/Key,.crt

cat intermediate/certs/dc01.crt intermediate/private/dc01-key.crt > intermediate/private/dc01.crt

Combine Cert/Key, pkcs12

openssl pkcs12 -export -inkey intermediate/private/dc01-key.crt -in intermediate/certs/dc01.crt -name dc01 -out intermediate/private/dc01.pfx
extended pkcs12
openssl pkcs12 -export -inkey intermediate/private/dc01-key.crt -in intermediate/certs/dc01.crt -certfile intermediate/chain.crt -name dc01 -out intermediate/private/dc01.p12
Do the same for DC02 and copy certificates to respective server:
scp intermediate/private/dc01-key.pem intermediate/certs/dc01.pem intermediate/chain.pem emir@dc01.yourdomain.com:
scp intermediate/private/dc02-key.pem intermediate/certs/dc02.pem intermediate/chain.pem emir@dc02.yourdomain.com:

Install chain certificate on each DC

# on dc01 and dc02
sudo cp chain.pem /usr/local/share/ca-certificates/chain.crt
sudo update-ca-certificates

Some examples

Generate a client authentication certificate

openssl genrsa -aes256 -out intermediate/private/client.key
openssl req -config intermediate/openssl-client.cnf -new -key intermediate/private/client.key -out intermediate/csr/client.csr
openssl ca -config intermediate/openssl-client.cnf -extensions client_cert -days 3650 -in intermediate/csr/client.csr -out intermediate/certs/client.crt

Remove encryption from private key:

openssl rsa -in intermediate/private/client.key -out intermediate/private/client-key.crt

Combine Cert/Key,.crt:

cat intermediate/certs/client.crt intermediate/private/client-key.crt > intermediate/private/client.crt

Combine Cert/Key, pkcs12:

# Regular (Windows)
openssl pkcs12 -export -inkey intermediate/private/client-key.crt -in intermediate/certs/client.crt -name client -out intermediate/private/client.pfx
# Regular (Chromebook)
cat intermediate/certs/client.crt intermediate/intermediate.crt > client-configs/keys/client.crt
openssl pkcs12 -export -inkey intermediate/private/client-key.crt -in client-configs/keys/client.crt -name client -out intermediate/private/client-cr.p12
# Extended
openssl pkcs12 -export -inkey intermediate/private/client-key.crt -in intermediate/certs/client.crt -certfile intermediate/chain.crt -name client -out intermediate/private/client.p12


Do everything in pki root directory:

Generate a server certificate:

openssl genrsa -aes256 -out private/server.key
openssl req -config intermediate/openssl-server.cnf -new -key private/server.key -out csr/server.csr
openssl ca -config openssl-server.cnf -extensions server_cert -days 10950 -in csr/server.csr -out certs/server.crt
sudo cp certs/server.crt /etc/openvpn/
Remove encryption from private key:
openssl rsa -in private/server.key -out private/server-key.crt
sudo cp private/server-key.crt /etc/openvpn/

Generate a client (work) authentication certificate

openssl genrsa -aes256 -out private/work.key
openssl req -config openssl-client.cnf -new -key private/work.key -out csr/work.csr
openssl ca -config openssl-client.cnf -extensions client_cert -days 3650 -in csr/work.csr -out certs/work.crt
cp certs/work.crt client-configs/keys/
Remove encryption from private key:
openssl rsa -in private/work.key -out private/work-key.crt
cp private/work-key.crt client-configs/keys/
sudo client-configs/make_config.sh work
Combine Cert/Key, pkcs12
openssl pkcs12 -export -inkey private/work-key.crt -in certs/work.crt -name work -out private/work-cr.p12
cp private/work-cr.p12 ~/openvpn/work/
cp client-configs/files/work.ovpn ~/openvpn/work/

Generate a client authentication certificate

openssl genrsa -aes256 -out private/client.key
openssl req -config openssl-client.cnf -new -key private/client.key -out csr/client.csr
openssl ca -config openssl-client.cnf -extensions client_cert -days 3650 -in csr/client.csr -out certs/client.crt
cp certs/client.crt client-configs/keys/
Remove encryption from private key:
openssl rsa -in private/client.key -out private/client-key.crt
cp private/client-key.crt client-configs/keys/
sudo client-configs/make_config.sh client
Combine Cert/Key, pkcs12:
openssl pkcs12 -export -inkey private/client-key.crt -in certs/client.crt -name client -out private/client-cr.p12
cp private/client-cr.p12 ~/openvpn/client/
cp client-configs/files/client.ovpn ~/openvpn/client/


# Revoke certificate
openssl ca -config intermediate/openssl-intermediate.cnf -revoke intermediate/certs/dc01.crt

# View certificate details
openssl x509 -in dc01.pem -noout -text

# Verifying the certificate (local)
openssl verify -CAfile chain.pem dc01.pem

# Veryfi certificate (remote)
openssl s_client -showcerts -connect localhost:636 -CAfile chain.pem