===== 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