===== Setup of the certification system =====
The goal is to delivered certificates for openvpn servers and clients. We are going to create a self-signed certificate authority
==== Description of the CA system ====
root_ca: Global auto-generated Certification authority
vpn_ca: Intermediate certification authority from root_ca
==== Directories and files building ====
mkdir -p /etc/ssl/root_ca/{certs,crl,newcerts,private}
mkdir -p /etc/ssl/vpn_ca/{certs,crl,newcerts,private}
touch /etc/ssl/root_ca/index.txt
touch /etc/ssl/vpn_ca/index.txt
touch /etc/ssl/root_ca/serial
touch /etc/ssl/vpn_ca/serial
I also create a directory where I put the created certificates
mkdir /etc/ssl/generate_certs
==== OpenSSL configuration file ====
Replace the openssl.cnf file by the one located in 3 Annex 1 :
==== Generation of the main certification authority ====
=== Generate Root CA ===
cd /etc/ssl/root_ca/
openssl req -x509 -config /etc/ssl/openssl.cnf -newkey rsa:8192 -sha256 -extensions ROOT_CA -days 3650 -keyout private/root_ca.key -out root_ca.pem
You must input a passphrase and a FQDN specific for the root_ca (ex: root_ca@example.org)
=== Protect the root private key ===
chmod -R 600 /etc/ssl/root_ca/private
=== Serial number initialization ===
openssl x509 -serial -noout -in root_ca.pem | cut -d= -f2 > serial
=== Generate Root CA certificate ===
openssl req -new -newkey rsa:2048 -keyout private/cakey.pem -out careq.pem -config /etc/ssl/openssl.cnf
You must input a new passphrase and a FQDN specific for the root_ca certificate (ex: ca-root-cert.example.org)
openssl ca -create_serial -out cacert.pem -days 365 -keyfile private/cakey.pem -selfsign -config /etc/ssl/openssl.cnf -infiles careq.pem
==== Generation of the intermediate authority certificate ====
=== Certification request for the intermediate authority ===
cd /etc/ssl/vpn_ca
openssl req -newkey rsa:8192 -sha256 -keyout private/vpn_ca.key -out vpn_ca.req
You must create a new passphrase (again).
Add also a commpn name dedicated (for example: vpn-ca-cert.example.org)
=== Private keys protection ===
chmod -R 600 /etc/ssl/vpn_ca/private
=== Intermediate authority certificate signature ===
openssl ca -extensions VPN_CA -in vpn_ca.req -out vpn_ca.pem
=== Intermediate authority serial implementation ===
openssl x509 -serial -noout -in vpn_ca.pem | cut -d= -f2 > serial
==== Create a CA file with all the chain ====
cd /etc/ssl/generate_certs
cat /etc/ssl/root_ca/root_ca.pem /etc/ssl/vpn_ca/vpn_ca.pem > /etc/ssl/vpn_ca-chain.pem
==== Generate and sign certificate for the openvpn server ====
cd /etc/ssl/generate_certs
openssl req -nodes -newkey rsa:4096 -keyout razorback.key -out razorback.req
openssl ca -name vpn_ca -extensions VPN_SERVER -in razorback.req -out razorback.pem
==== Generate and certificate for the openvpn clients ====
cd /etc/ssl/generate_certs
openssl req -nodes -newkey rsa:4096 -keyout vesta.key -out vesta.req
openssl ca -name vpn_ca -extensions VPN_CLIENT -in vesta.req -out vesta.pem
openssl req -nodes -newkey rsa:4096 -keyout yahweh.key -out yahweh.req
openssl ca -name vpn_ca -extensions VPN_CLIENT -in yahweh.req -out yahweh.pem
==== Generate Diffie-Hellman ====
mkdir –p /etc/ssl/generate_keys
cd /etc/ssl/generate_keys
openssl dhparam -out dh2048.pem 2048
===== Openvpn server configuration =====
==== Creation of the configuration directory for the first installation ====
mkdir -p /usr/local/etc/openvpn/ssl
mkdir –p /usr/local/etc/openvpn/log
touch /usr/local/etc/openvpn/log/openvpn.log
touch /usr/local/etc/openvpn/log/openvpn-status.log
==== Generate specific keys for openvpn ====
openvpn --genkey secret /usr/local/etc/openvpn/ssl/ta.key
==== Copy the certificate generated on openvpn directory ====
Adapt the source files for the copy command
cp opvn-srv1.pem /usr/local/etc/openvpn/ssl/
cp opvn-srv1.key /usr/local/etc/openvpn/ssl/
cp dh2048.pem /usr/local/etc/openvpn/ssl/
cp vpn_ca-chain.pem /usr/local/etc/openvpn/ssl/
==== Configuration of the server ====
Create the file usrlocal/etc/openvpn/ovpnesm.conf
# Network parameters
port 1195
proto udp
dev tap1
# Certificates and keys
ca ssl/vpn_ca-chain.pem
cert ssl/razorback.pem
key ssl/razorback.key
dh ssl/dh2048.pem
tls-auth ssl/ta.key 0
# Vpn parameters
server-ipv6 fec0::/64
client-to-client
keepalive 10 120
cipher AES-256-CBC
persist-key
persist-tun
# Log
status log/openvpn-status.log
log log/openvpn.log
log-append log/openvpn.log
verb 3
explicit-exit-notify 1
persist-tun
==== Openvpn start-up configuration ====
cp /usr/local/etc/rc.d/openvpn /usr/local/etc/rc.d/openvpn_ovpnesm.conf
sysrc openvpn_ovpnesm_configfile=”/usr/local/etc/rc.d/openvpn_ovpnesm.conf”
sysrc openvpn_ovpnesm_enable=YES
service openvpn_ovpnesm start
==== Openvpn start validation ====
* Check processus
ps -ax | grep openvpn
Result:
7002 - Ss 0:00.02 /usr/local/sbin/openvpn --cd /usr/local/etc/openvpn --daemon openvpn --config /usr/local/etc/openvpn/ovpnesm.conf --writepid /var/run/openvpn.pid
* Check network listening
netstat -4anl | grep 1195
Result:
Active Internet connections (including servers)
Proto Recv-Q Send-Q Local Address Foreign Address (state)
udp46 0 0 *.1195 *.*
* Check logs
cat /usr/local/etc/openvpn/log/openvpn-status.log
Result :
OpenVPN CLIENT LIST
Updated,2021-04-23 05:11:36
Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since
ROUTING TABLE
Virtual Address,Common Name,Real Address,Last Ref
GLOBAL STATS
Max bcast/mcast queue length,0
END
==== Openvpn network validation ====
ifconfig tap0
Result :
tap0: flags=8843 metric 0 mtu 1500
options=80000
ether 58:9c:fc:10:ff:91
inet6 fec0::1 prefixlen 64
inet6 fe80::5a9c:fcff:fe10:ff91%tap0 prefixlen 64 scopeid 0x4
groups: tap
media: Ethernet autoselect
status: active
nd6 options=21
Opened by PID 7002
===== Openvpn client configurations =====
==== Creation of the configuration directory for the first installation ====
mkdir -p /usr/local/etc/openvpn/ssl
mkdir –p /usr/local/etc/openvpn/log
mkdir –p /usr/local/etc/openvpn/scripts
touch /usr/local/etc/openvpn/log/openvpn.log
==== Openvpn start-up configuration ====
cp /usr/local/etc/rc.d/openvpn /usr/local/etc/rc.d/openvpn_ovpnesm.conf
sysrc openvpn_ovpnesm_configfile=”/usr/local/etc/rc.d/openvpn_ovpnesm.conf”
sysrc openvpn_ovpnesm_enable=YES
==== Vesta configuration ====
=== Copy the certificate generated on openvpn directory ===
Adapt the source files for the copy command
cp vesta.pem /usr/local/etc/openvpn/ssl/
cp vesta.key /usr/local/etc/openvpn/ssl/
cp vpn_ca-chain.pem /usr/local/etc/openvpn/ssl/
cp ta.key /usr/local/etc/openvpn/ssl/
=== Create the bridgeParms.sh script ===
Adapt the source files for the copy command
cat > /usr/local/etc/openvpn/scripts/bridgeParams.sh << EOF
#!/bin/sh
ovpnAction=$1
if [ "$ovpnAction" = "up" ]; then
ifconfig bridge create name ovpnb0
ifconfig ovpnb0 addm tap1
ifconfig ovpnb0 addm re1
ifconfig re1 up
ifconfig ovpnb0 up
elif [ "$ovpnAction" = "down" ]; then
ifconfig ovpnb0 destroy
ifconfig re1 down
else
echo nothing
fi
EOF
chmod a+x /usr/local/etc/openvpn/scripts/bridgeParams.sh
=== Configuration of the openvpn service ===
cat > /usr/local/etc/openvpn/ovpnesm.conf << EOF
# Network parameters
client
dev tap1
proto udp
remote 5.196.65.162 1195
# Certificates and keys
ca ssl/vpn_ca-chain.pem
cert ssl/vesta.pem
key ssl/vesta.key
remote-cert-tls server
tls-auth ssl/ta.key 1
# Vpn parameters
resolv-retry infinite
nobind
cipher AES-256-CBC
persist-key
persist-tun
# Log
log log/openvpn.log
log-append log/openvpn.log
verb 3
script-security 2
up "./scripts/bridgeParams.sh up"
down "./scripts/bridgeParams.sh down"
ping-restart 10
EOF
=== Openvpn start ===
service openvpn_ovpnesm start
=== Openvpn start validation ===
* Check process
ps -ax | grep openvpn
Result:
85363 - Ss 5:44.68 /usr/local/sbin/openvpn --cd /usr/local/etc/openvpn --daemon openvpn_ovpnesm --config /usr/local/etc/openvpn/ovpnesm.conf --writepid /var/run/openvpn_ovpnesm
=== Openvpn network validation ===
ifconfig tap1
Result :
tap1: flags=8843 metric 0 mtu 1500
options=80000
ether 58:9c:fc:10:ff:91
inet6 fec0::1000 prefixlen 64
inet6 fe80::5a9c:fcff:fe10:ff91%tap0 prefixlen 64 scopeid 0x4
groups: tap
media: Ethernet autoselect
status: active
nd6 options=21
Opened by PID 7002
* Check ping
ping -6 -c 5 fec0::1
Result :
16 bytes from fec0::1, icmp_seq=0 hlim=64 time=1.014 ms
16 bytes from fec0::1, icmp_seq=1 hlim=64 time=1.035 ms
16 bytes from fec0::1, icmp_seq=2 hlim=64 time=1.219 ms
16 bytes from fec0::1, icmp_seq=3 hlim=64 time=1.760 ms
16 bytes from fec0::1, icmp_seq=4 hlim=64 time=1.212 ms
===== Annex 1 : openssl.cnf =====
HOME = .
#RANDFILE = $ENV::HOME/.rnd
#oid_file = $ENV::HOME/.oid
oid_section = new_oids
[ new_oids ]
tsa_policy1 = 1.2.3.4.1
tsa_policy2 = 1.2.3.4.5.6
tsa_policy3 = 1.2.3.4.5.7
####################################################################
[ ca ]
default_ca = root_ca # The default ca section
####################################################################
[ root_ca ]
dir = /etc/ssl/root_ca
certs = $dir/certs
new_certs_dir = $dir/newcerts
database = $dir/index.txt
certificate = $dir/root_ca.pem
serial = $dir/serial
private_key = $dir/private/root_ca.key
default_days = 3650
default_md = sha256
preserve = no
policy = policy_match
#unique_subject = no # Set to 'no' to allow creation of several certs with same subject.
[ vpn_ca ]
dir = /etc/ssl/vpn_ca
certs = $dir/certs
new_certs_dir = $dir/newcerts
database = $dir/index.txt
certificate = $dir/vpn_ca.pem
serial = $dir/serial
private_key = $dir/private/vpn_ca.key
default_days = 3650
default_md = sha256
preserve = no
policy = policy_match
#unique_subject = no # Set to 'no' to allow creation of several certs with same subject.
[ policy_match ]
countryName = match
stateOrProvinceName = match
localityName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
string_mask = utf8only
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = FR
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Pays de la Loire
localityName = Locality Name (eg, city)
localityName_default = Nantes
0.organizationName = Organization Name (eg, company)
0.organizationName_default = Orange
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
#organizationalUnitName_default =
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 64
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name
[default_conf]
ssl_conf = ssl_sect
[ssl_sect]
system_default = system_default_sect
[system_default_sect]
MinProtocol = TLSv1.2
CipherString = DEFAULT@SECLEVEL=2
[ROOT_CA]
nsComment = "ROOT CA"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
basicConstraints = critical,CA:TRUE,pathlen:1
keyUsage = keyCertSign, cRLSign
[VPN_CA]
nsComment = "VPN CA"
basicConstraints = critical,CA:TRUE,pathlen:0
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
issuerAltName = issuer:copy
keyUsage = keyCertSign, cRLSign
nsCertType = sslCA
[VPN_SERVER]
nsComment = "VPN Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
issuerAltName = issuer:copy
basicConstraints = critical,CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment
nsCertType = server
extendedKeyUsage = serverAuth
[VPN_CLIENT]
nsComment = "VPN CLIENT Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
issuerAltName = issuer:copy
basicConstraints = critical,CA:FALSE
keyUsage = digitalSignature, nonRepudiation
nsCertType = client
extendedKeyUsage = clientAuth