kb:internet:connectivity:openvpn
                OpenVPN
Server
Incomplete documentation.
curl -fsSL https://swupdate.openvpn.net/repos/repo-public.gpg | gpg --dearmor | sudo tee /etc/apt/keyrings/openvpn-repo-public.gpg > /dev/null echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/openvpn-repo-public.gpg] https://build.openvpn.net/debian/openvpn/stable jammy main" | sudo tee /etc/apt/sources.list.d/openvpn-aptrepo.list > /dev/null sudo apt update sudo apt install openvpn openvpn-dco-dkms wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.2/EasyRSA-3.1.2.tgz tar -xzvf EasyRSA-3.1.2.tgz ./easyrsa init-pki ./easyrsa build-ca ./easyrsa gen-req client ./easyrsa sign-req client cd /usr/share/doc/openvpn/examples/sample-config-files/ sudo cp server.conf /etc/openvpn/server/ sudo cp client.conf /etc/openvpn/client/ sudo openvpn server.conf
OpenVPN client
Update: To update with new info.
In Alpine containers, note the container must have NET_ADMIN privilege, or run in --privileged (privileged: true) mode.
mkdir -p /dev/net
mknod /dev/net/tun c 20 100
chmod 666 -R /dev/net
apk add openvpn
openvpn {% CONFIG_FILE %}
For Docker containers, need to redirect to VPN container.
expressvpn:
  container_name: expressvpn
  image: polkaned/expressvpn
  environment:
    - ACTIVATION_CODE={% your-activation-code %}
    - SERVER={% LOCATION/ALIAS/COUNTRY %}
    - PREFERRED_PROTOCOL={% protocol %}
    - LIGHTWAY_CIPHER={% lightway-cipher %}
  cap_add:
    - NET_ADMIN
  devices: 
    - /dev/net/tun
  stdin_open: true
  tty: true
  command: /bin/bash
  privileged: true
  restart: unless-stopped
  ports:
    # ports of other containers that use the vpn (to access them locally)
downloader:
  image: example/downloader
  container_name: downloader
  network_mode: service:expressvpn
  depends_on:
    - expressvpn
  # ports should not be published here
For automated connections as client, consider creating a service and connect on boot:
[Unit]
Description=OpenVPN
Wants=network-online.target
After=network-online.target
[Service]
User=root
Group=root
Type=simple
ExecStart=openvpn \
    --config /home/justin/config.ovpn \
    --auth-user-pass /home/justin/config.ovpn.passwd \
    --auth-nocache
[Install]
WantedBy=multi-user.target
To check the server certificate as a client, execute the following (copied from ServerFault):
WD=/tmp/openvpn-cert mkdir $WD echo -e '#!'"/bin/sh\ncp \$peer_cert $WD/server-cert-\$1.pem" >$WD/extract-cert.sh chmod +x $WD/extract-cert.sh echo -e "fakeusername\nfakepassword" >$WD/creds.dat openvpn --config config.ovpn --auth-user-pass $WD/creds.dat --tls-export-cert $WD --script-security 2 --tls-verify $WD/extract-cert.sh --log /dev/null openssl x509 -in $WD/server-cert-0.pem -noout
OpenVPN server
Following this tutorial: https://linuxconfig.org/how-to-setup-a-openvpn-server-on-ubuntu-20-04/
Historical stuff I have no idea why it's here
$ sudo apt install easy-rsa $ make-cadir ca & cd ca # makes a directory 'ca' and populate with required tools $ vim ./vars ... set_var EASYRSA_REQ_COUNTRY "US" set_var EASYRSA_REQ_PROVINCE "California" set_var EASYRSA_REQ_CITY "San Francisco" set_var EASYRSA_REQ_ORG "Copyleft Certificate Co" set_var EASYRSA_REQ_EMAIL "me@example.net" set_var EASYRSA_REQ_OU "My Organizational Unit" ... $ ./easyrsa init-pki # reinitialize directory for clean PKI $ ./easyrsa build-ca Note: using Easy-RSA configuration from: ./vars Using SSL: openssl OpenSSL 1.1.1f 31 Mar 2020 Enter New CA Key Passphrase: Re-Enter New CA Key Passphrase: Generating RSA private key, 2048 bit long modulus (2 primes) ..........................+++++ ...............+++++ e is 65537 (0x010001) Can't load /home/ubuntu/ca/pki/.rnd into RNG 281473638455776:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:98:Filename=/home/ubuntu/ca/pki/.rnd You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Common Name (eg: your user, host, or server name) [Easy-RSA CA]:justin CA creation complete and you may now import and sign cert requests. Your new CA certificate file for publishing is at: /home/ubuntu/ca/pki/ca.crt $ ./easyrsa gen-req server nopass
Copy
ubuntu@ubuntu:~$ ls
ubuntu@ubuntu:~$ ll
total 36
drwxr-xr-x 4 ubuntu ubuntu 4096 Aug  7 15:53 ./
drwxr-xr-x 4 root   root   4096 Jun 14 18:15 ../
-rw------- 1 ubuntu ubuntu  246 Jun 14 18:16 .bash_history
-rw-r--r-- 1 ubuntu ubuntu  220 Feb 25  2020 .bash_logout
-rw-r--r-- 1 ubuntu ubuntu 3771 Feb 25  2020 .bashrc
drwx------ 2 ubuntu ubuntu 4096 Jun 10 08:27 .cache/
-rw-r--r-- 1 ubuntu ubuntu  807 Feb 25  2020 .profile
-rw------- 1 ubuntu ubuntu   14 Aug  7 15:53 .python_history
drwx------ 2 ubuntu ubuntu 4096 Apr  2  2020 .ssh/
-rw-r--r-- 1 ubuntu ubuntu    0 Jun 10 08:28 .sudo_as_admin_successful
ubuntu@ubuntu:~$ make-cadir ca
ubuntu@ubuntu:~$ ll
total 40
drwxr-xr-x 5 ubuntu ubuntu 4096 Aug  7 16:07 ./
drwxr-xr-x 4 root   root   4096 Jun 14 18:15 ../
-rw------- 1 ubuntu ubuntu  246 Jun 14 18:16 .bash_history
-rw-r--r-- 1 ubuntu ubuntu  220 Feb 25  2020 .bash_logout
-rw-r--r-- 1 ubuntu ubuntu 3771 Feb 25  2020 .bashrc
drwx------ 2 ubuntu ubuntu 4096 Jun 10 08:27 .cache/
-rw-r--r-- 1 ubuntu ubuntu  807 Feb 25  2020 .profile
-rw------- 1 ubuntu ubuntu   14 Aug  7 15:53 .python_history
drwx------ 2 ubuntu ubuntu 4096 Apr  2  2020 .ssh/
-rw-r--r-- 1 ubuntu ubuntu    0 Jun 10 08:28 .sudo_as_admin_successful
drwx------ 2 ubuntu ubuntu 4096 Aug  7 16:07 ca/
ubuntu@ubuntu:~$ cd ca
ubuntu@ubuntu:~/ca$ ll
total 28
drwx------ 2 ubuntu ubuntu 4096 Aug  7 16:07 ./
drwxr-xr-x 5 ubuntu ubuntu 4096 Aug  7 16:07 ../
lrwxrwxrwx 1 ubuntu ubuntu   27 Aug  7 16:07 easyrsa -> /usr/share/easy-rsa/easyrsa*
-rw-r--r-- 1 ubuntu ubuntu 4651 Aug  7 16:07 openssl-easyrsa.cnf
-rw-r--r-- 1 ubuntu ubuntu 8576 Aug  7 16:07 vars
lrwxrwxrwx 1 ubuntu ubuntu   30 Aug  7 16:07 x509-types -> /usr/share/easy-rsa/x509-types/
ubuntu@ubuntu:~/ca$ cat vars
# Easy-RSA 3 parameter settings
# NOTE: If you installed Easy-RSA from your distro's package manager, don't edit
# this file in place -- instead, you should copy the entire easy-rsa directory
# to another location so future upgrades don't wipe out your changes.
# HOW TO USE THIS FILE
#
# vars.example contains built-in examples to Easy-RSA settings. You MUST name
# this file 'vars' if you want it to be used as a configuration file. If you do
# not, it WILL NOT be automatically read when you call easyrsa commands.
#
# It is not necessary to use this config file unless you wish to change
# operational defaults. These defaults should be fine for many uses without the
# need to copy and edit the 'vars' file.
#
# All of the editable settings are shown commented and start with the command
# 'set_var' -- this means any set_var command that is uncommented has been
# modified by the user. If you're happy with a default, there is no need to
# define the value to its default.
# NOTES FOR WINDOWS USERS
#
# Paths for Windows  *MUST* use forward slashes, or optionally double-esscaped
# backslashes (single forward slashes are recommended.) This means your path to
# the openssl binary might look like this:
# "C:/Program Files/OpenSSL-Win32/bin/openssl.exe"
# A little housekeeping: DON'T EDIT THIS SECTION
# 
# Easy-RSA 3.x doesn't source into the environment directly.
# Complain if a user tries to do this:
if [ -z "$EASYRSA_CALLER" ]; then
	echo "You appear to be sourcing an Easy-RSA 'vars' file." >&2
	echo "This is no longer necessary and is disallowed. See the section called" >&2
	echo "'How to use this file' near the top comments for more details." >&2
	return 1
fi
# DO YOUR EDITS BELOW THIS POINT
# This variable is used as the base location of configuration files needed by
# easyrsa.  More specific variables for specific files (e.g., EASYRSA_SSL_CONF)
# may override this default.
#
# The default value of this variable is the location of the easyrsa script
# itself, which is also where the configuration files are located in the
# easy-rsa tree.
#set_var EASYRSA	"${0%/*}"
# If your OpenSSL command is not in the system PATH, you will need to define the
# path to it here. Normally this means a full path to the executable, otherwise
# you could have left it undefined here and the shown default would be used.
#
# Windows users, remember to use paths with forward-slashes (or escaped
# back-slashes.) Windows users should declare the full path to the openssl
# binary here if it is not in their system PATH.
#set_var EASYRSA_OPENSSL	"openssl"
#
# This sample is in Windows syntax -- edit it for your path if not using PATH:
#set_var EASYRSA_OPENSSL	"C:/Program Files/OpenSSL-Win32/bin/openssl.exe"
# Edit this variable to point to your soon-to-be-created key directory.  By
# default, this will be "$PWD/pki" (i.e. the "pki" subdirectory of the
# directory you are currently in).
#
# WARNING: init-pki will do a rm -rf on this directory so make sure you define
# it correctly! (Interactive mode will prompt before acting.)
#set_var EASYRSA_PKI		"$PWD/pki"
# Define X509 DN mode.
# This is used to adjust what elements are included in the Subject field as the DN
# (this is the "Distinguished Name.")
# Note that in cn_only mode the Organizational fields further below aren't used.
#
# Choices are:
#   cn_only  - use just a CN value
#   org      - use the "traditional" Country/Province/City/Org/OU/email/CN format
#set_var EASYRSA_DN	"cn_only"
# Organizational fields (used with 'org' mode and ignored in 'cn_only' mode.)
# These are the default values for fields which will be placed in the
# certificate.  Don't leave any of these fields blank, although interactively
# you may omit any specific field by typing the "." symbol (not valid for
# email.)
#set_var EASYRSA_REQ_COUNTRY	"US"
#set_var EASYRSA_REQ_PROVINCE	"California"
#set_var EASYRSA_REQ_CITY	"San Francisco"
#set_var EASYRSA_REQ_ORG	"Copyleft Certificate Co"
#set_var EASYRSA_REQ_EMAIL	"me@example.net"
#set_var EASYRSA_REQ_OU		"My Organizational Unit"
# Choose a size in bits for your keypairs. The recommended value is 2048.  Using
# 2048-bit keys is considered more than sufficient for many years into the
# future. Larger keysizes will slow down TLS negotiation and make key/DH param
# generation take much longer. Values up to 4096 should be accepted by most
# software. Only used when the crypto alg is rsa (see below.)
#set_var EASYRSA_KEY_SIZE	2048
# The default crypto mode is rsa; ec can enable elliptic curve support.
# Note that not all software supports ECC, so use care when enabling it.
# Choices for crypto alg are: (each in lower-case)
#  * rsa
#  * ec
#set_var EASYRSA_ALGO		rsa
# Define the named curve, used in ec mode only:
#set_var EASYRSA_CURVE		secp384r1
# In how many days should the root CA key expire?
#set_var EASYRSA_CA_EXPIRE	3650
# In how many days should certificates expire?
#set_var EASYRSA_CERT_EXPIRE	1080
# How many days until the next CRL publish date?  Note that the CRL can still be
# parsed after this timeframe passes. It is only used for an expected next
# publication date.
# How many days before its expiration date a certificate is allowed to be
# renewed?
#set_var EASYRSA_CERT_RENEW	30
#set_var EASYRSA_CRL_DAYS	180
# Support deprecated "Netscape" extensions? (choices "yes" or "no".) The default
# is "no" to discourage use of deprecated extensions. If you require this
# feature to use with --ns-cert-type, set this to "yes" here. This support
# should be replaced with the more modern --remote-cert-tls feature.  If you do
# not use --ns-cert-type in your configs, it is safe (and recommended) to leave
# this defined to "no".  When set to "yes", server-signed certs get the
# nsCertType=server attribute, and also get any NS_COMMENT defined below in the
# nsComment field.
#set_var EASYRSA_NS_SUPPORT	"no"
# When NS_SUPPORT is set to "yes", this field is added as the nsComment field.
# Set this blank to omit it. With NS_SUPPORT set to "no" this field is ignored.
#set_var EASYRSA_NS_COMMENT	"Easy-RSA Generated Certificate"
# A temp file used to stage cert extensions during signing. The default should
# be fine for most users; however, some users might want an alternative under a
# RAM-based FS, such as /dev/shm or /tmp on some systems.
#set_var EASYRSA_TEMP_FILE	"$EASYRSA_PKI/extensions.temp"
# !!
# NOTE: ADVANCED OPTIONS BELOW THIS POINT
# PLAY WITH THEM AT YOUR OWN RISK
# !!
# Broken shell command aliases: If you have a largely broken shell that is
# missing any of these POSIX-required commands used by Easy-RSA, you will need
# to define an alias to the proper path for the command.  The symptom will be
# some form of a 'command not found' error from your shell. This means your
# shell is BROKEN, but you can hack around it here if you really need. These
# shown values are not defaults: it is up to you to know what you're doing if
# you touch these.
#
#alias awk="/alt/bin/awk"
#alias cat="/alt/bin/cat"
# X509 extensions directory:
# If you want to customize the X509 extensions used, set the directory to look
# for extensions here. Each cert type you sign must have a matching filename,
# and an optional file named 'COMMON' is included first when present. Note that
# when undefined here, default behaviour is to look in $EASYRSA_PKI first, then
# fallback to $EASYRSA for the 'x509-types' dir.  You may override this
# detection with an explicit dir here.
#
#set_var EASYRSA_EXT_DIR	"$EASYRSA/x509-types"
# OpenSSL config file:
# If you need to use a specific openssl config file, you can reference it here.
# Normally this file is auto-detected from a file named openssl-easyrsa.cnf from the
# EASYRSA_PKI or EASYRSA dir (in that order.) NOTE that this file is Easy-RSA
# specific and you cannot just use a standard config file, so this is an
# advanced feature.
#set_var EASYRSA_SSL_CONF	"$EASYRSA/openssl-easyrsa.cnf"
# Default CN:
# This is best left alone. Interactively you will set this manually, and BATCH
# callers are expected to set this themselves.
#set_var EASYRSA_REQ_CN		"ChangeMe"
# Cryptographic digest to use.
# Do not change this default unless you understand the security implications.
# Valid choices include: md5, sha1, sha256, sha224, sha384, sha512
#set_var EASYRSA_DIGEST		"sha256"
# Batch mode. Leave this disabled unless you intend to call Easy-RSA explicitly
# in batch mode without any user input, confirmation on dangerous operations,
# or most output. Setting this to any non-blank string enables batch mode.
#set_var EASYRSA_BATCH		""
ubuntu@ubuntu:~/ca$ cat vars | less
ubuntu@ubuntu:~/ca$ vim vars
ubuntu@ubuntu:~/ca$ ll
total 28
drwx------ 2 ubuntu ubuntu 4096 Aug  7 20:28 ./
drwxr-xr-x 5 ubuntu ubuntu 4096 Aug  7 20:28 ../
lrwxrwxrwx 1 ubuntu ubuntu   27 Aug  7 16:07 easyrsa -> /usr/share/easy-rsa/easyrsa*
-rw-r--r-- 1 ubuntu ubuntu 4651 Aug  7 16:07 openssl-easyrsa.cnf
-rw-r--r-- 1 ubuntu ubuntu 8528 Aug  7 20:28 vars
lrwxrwxrwx 1 ubuntu ubuntu   30 Aug  7 16:07 x509-types -> /usr/share/easy-rsa/x509-types/
ubuntu@ubuntu:~/ca$ cat init
cat: init: No such file or directory
ubuntu@ubuntu:~/ca$ cat easyrsa 
#!/bin/sh
# Easy-RSA 3 -- A Shell-based CA Utility
#
# Copyright (C) 2018 by the Open-Source OpenVPN development community.
# A full list of contributors can be found in the ChangeLog.
#
# This code released under version 2 of the GNU GPL; see COPYING and the
# Licensing/ directory of this project for full licensing details.
# Help/usage output to stdout
usage() {
	# command help:
	print "
Easy-RSA 3 usage and overview
USAGE: easyrsa [options] COMMAND [command-options]
A list of commands is shown below. To get detailed usage and help for a
command, run:
  ./easyrsa help COMMAND
For a listing of options that can be supplied before the command, use:
  ./easyrsa help options
Here is the list of commands available with a short syntax reminder. Use the
'help' command above to get full usage details.
  init-pki
  build-ca [ cmd-opts ]
  gen-dh
  gen-req <filename_base> [ cmd-opts ]
  sign-req <type> <filename_base>
  build-client-full <filename_base> [ cmd-opts ]
  build-server-full <filename_base> [ cmd-opts ]
  revoke <filename_base> [cmd-opts]
  renew <filename_base> [cmd-opts]
  build-serverClient-full <filename_base> [ cmd-opts ]
  gen-crl
  update-db
  show-req <filename_base> [ cmd-opts ]
  show-cert <filename_base> [ cmd-opts ]
  show-ca [ cmd-opts ]
  import-req <request_file_path> <short_basename>
  export-p7 <filename_base> [ cmd-opts ]
  export-p12 <filename_base> [ cmd-opts ]
  set-rsa-pass <filename_base> [ cmd-opts ]
  set-ec-pass <filename_base> [ cmd-opts ]
"
	# collect/show dir status:
	err_source="Not defined: vars autodetect failed and no value provided"
	work_dir="${EASYRSA:-$err_source}"
	pki_dir="${EASYRSA_PKI:-$err_source}"
	print "\
DIRECTORY STATUS (commands would take effect on these locations)
  EASYRSA: $work_dir
      PKI: $pki_dir
"
} # => usage()
# Detailed command help
# When called with no args, calls usage(), otherwise shows help for a command
cmd_help() {
	text=""
	opts=""
	case "$1" in
		init-pki|clean-all) text="
  init-pki [ cmd-opts ]
      Removes & re-initializes the PKI dir for a clean PKI" ;;
		build-ca) text="
  build-ca [ cmd-opts ]
      Creates a new CA"
      			opts="
        nopass  - do not encrypt the CA key (default is encrypted)
        subca   - create a sub-CA keypair and request (default is a root CA)" ;;
		gen-dh) text="
  gen-dh
      Generates DH (Diffie-Hellman) parameters" ;;
		gen-req) text="
  gen-req <filename_base> [ cmd-opts ]
      Generate a standalone keypair and request (CSR)
      This request is suitable for sending to a remote CA for signing."
      			opts="
        nopass  - do not encrypt the private key (default is encrypted)" ;;
		sign|sign-req) text="
  sign-req <type> <filename_base>
      Sign a certificate request of the defined type. <type> must be a known
      type such as 'client', 'server', 'serverClient', or 'ca' (or a user-added type.)
      This request file must exist in the reqs/ dir and have a .req file
      extension. See import-req below for importing reqs from other sources." ;;
		build|build-client-full|build-server-full|build-serverClient-full) text="
  build-client-full <filename_base> [ cmd-opts ]
  build-server-full <filename_base> [ cmd-opts ]
  build-serverClient-full <filename_base> [ cmd-opts ]
      Generate a keypair and sign locally for a client and/or server
      This mode uses the <filename_base> as the X509 CN."
			opts="
        nopass  - do not encrypt the private key (default is encrypted)" ;;
		revoke) text="
  revoke <filename_base> [reason]
      Revoke a certificate specified by the filename_base, with an optional 
      revocation reason that is one of: 
        unspecified
        keyCompromise
        CACompromise
        affiliationChanged
        superseded
        cessationOfOperation
        certificateHold";;
		renew) text="
  renew <filename_base> [ cmd-opts ]
      Renew a certificate specified by the filename_base"
				opts="
        nopass  - do not encrypt the private key (default is encrypted)" ;;
		gen-crl) text="
  gen-crl
      Generate a CRL" ;;
		update-db) text="
  update-db
      Update the index.txt database
      This command will use the system time to update the status of issued
      certificates." ;;
      		show-req|show-cert) text="
  show-req  <filename_base> [ cmd-opts ]
  show-cert <filename_base> [ cmd-opts ]
      Shows details of the req or cert referenced by filename_base
      Human-readable output is shown, including any requested cert options when
      showing a request."
      			opts="
          full   - show full req/cert info, including pubkey/sig data" ;;
		show-ca) text="
  show-ca [ cmd-opts ]
      Shows details of the CA cert
      Human-readable output is shown."
			opts="
          full   - show full cert info, including pubkey/sig data" ;;
		import-req) text="
  import-req <request_file_path> <short_basename>
      Import a certificate request from a file
      This will copy the specified file into the reqs/ dir in
      preparation for signing.
      The <short_basename> is the filename base to create.
      Example usage:
        import-req /some/where/bob_request.req bob" ;;
		export-p12) text="
  export-p12 <filename_base> [ cmd-opts ]
      Export a PKCS#12 file with the keypair specified by <filename_base>"
			opts="
        noca  - do not include the ca.crt file in the PKCS12 output
        nokey - do not include the private key in the PKCS12 output" ;;
		export-p7) text="
  export-p7 <filename_base> [ cmd-opts ]
      Export a PKCS#7 file with the pubkey specified by <filename_base>"
			opts="
        noca  - do not include the ca.crt file in the PKCS7 output" ;;
		set-rsa-pass|set-ec-pass) text="
  set-rsa-pass <filename_base> [ cmd-opts ]
  set-ec-pass <filename_base> [ cmd-opts ]
      Set a new passphrase on an RSA or EC key for the listed <filename_base>."
                        opts="
        nopass - use no password and leave the key unencrypted
        file   - (advanced) treat the file as a raw path, not a short-name" ;;
		altname|subjectaltname|san) text="
  --subject-alt-name=SAN_FORMAT_STRING
      This global option adds a subjectAltName to the request or issued
      certificate. It MUST be in a valid format accepted by openssl or
      req/cert generation will fail. Note that including multiple such names
      requires them to be comma-separated; further invocations of this
      option will REPLACE the value.
      Examples of the SAN_FORMAT_STRING shown below:
        DNS:alternate.example.net
        DNS:primary.example.net,DNS:alternate.example.net
        IP:203.0.113.29
        email:alternate@example.net" ;;
		options)
			opt_usage ;;
		"")
			usage ;;
		*) text="
  Unknown command: '$1' (try without commands for a list of commands)" ;;
	esac
	# display the help text
	print "$text"
	[ -n "$opts" ] && print "
      cmd-opts is an optional set of command options from this list:
$opts"
} # => cmd_help()
# Options usage
opt_usage() {
	print "
Easy-RSA Global Option Flags
The following options may be provided before the command. Options specified
at runtime override env-vars and any 'vars' file in use. Unless noted,
non-empty values to options are mandatory.
General options:
--batch         : set automatic (no-prompts when possible) mode
--pki-dir=DIR   : declares the PKI directory
--vars=FILE     : define a specific 'vars' file to use for Easy-RSA config
Certificate & Request options: (these impact cert/req field values)
--days=#        : sets the signing validity to the specified number of days
--digest=ALG    : digest to use in the requests & certificates
--dn-mode=MODE  : DN mode to use (cn_only or org)
--keysize=#     : size in bits of keypair to generate
--req-cn=NAME   : default CN to use
--subca-len=#   : path length of signed sub-CA certs; must be >= 0 if used
--subject-alt-name : Add a subjectAltName. For more info and syntax, see:
                     ./easyrsa help altname
--use-algo=ALG  : crypto alg to use: choose rsa (default) or ec
--curve=NAME    : for elliptic curve, sets the named curve to use
--copy-ext      : Copy included request X509 extensions (namely subjAltName
Organizational DN options: (only used with the 'org' DN mode)
  (values may be blank for org DN options)
--req-c=CC        : country code (2-letters)
--req-st=NAME     : State/Province
--req-city=NAME   : City/Locality
--req-org=NAME    : Organization
--req-email=NAME  : Email addresses
--req-ou=NAME     : Organizational Unit
Deprecated features:
--ns-cert=YESNO       : yes or no to including deprecated NS extensions
--ns-comment=COMMENT  : NS comment to include (value may be blank)
"
} # => opt_usage()
# Wrapper around printf - clobber print since it's not POSIX anyway
# shellcheck disable=SC1117
print() { printf "%s\n" "$*"; }
# Exit fatally with a message to stderr
# present even with EASYRSA_BATCH as these are fatal problems
die() {
	print "
Easy-RSA error:
$1" 1>&2
	clean_temp;
	prog_exit "${2:-1}"
} # => die()
# non-fatal warning output
warn() {
	[ ! "$EASYRSA_BATCH" ] && \
		print "
$1" 1>&2
} # => warn()
# informational notices to stdout
notice() {
	[ ! "$EASYRSA_BATCH" ] && \
		print "
$1"
} # => notice()
# yes/no case-insensitive match (operates on stdin pipe)
# Returns 0 when input contains yes, 1 for no, 2 for no match
# If both strings are present, returns 1; first matching line returns.
awk_yesno() {
	#shellcheck disable=SC2016
	awkscript='
BEGIN {IGNORECASE=1; r=2}
{       if(match($0,"no")) {r=1; exit}
        if(match($0,"yes")) {r=0; exit}
} END {exit r}'
	awk "$awkscript"
} # => awk_yesno()
# intent confirmation helper func
# returns without prompting in EASYRSA_BATCH
confirm() {
	[ "$EASYRSA_BATCH" ] && return
	prompt="$1"
	value="$2"
	msg="$3"
	input=""
	print "
$msg
Type the word '$value' to continue, or any other input to abort."
	printf %s "  $prompt"
	#shellcheck disable=SC2162
	read input
	[ "$input" = "$value" ] && return
	notice "Aborting without confirmation."
	exit 9
} # => confirm()
# remove temp files
clean_temp() {
	for f in "$EASYRSA_TEMP_CONF" "$EASYRSA_TEMP_EXT" \
		"$EASYRSA_TEMP_FILE_2" "$EASYRSA_TEMP_FILE_3" "$EASYRSA_TEMP_FILE_4"
	do	[ -f "$f" ] && rm "$f" 2>/dev/null
	done
} # => clean_temp()
prog_exit() {
	ESTAT=0
	[ -n "$1" ] && ESTAT=$1
	(stty echo 2>/dev/null) || set -o echo
	echo "" # just to get a clean line
	exit "$ESTAT"
} # => prog_exit()
# Make LibreSSL safe config file from OpenSSL config file
make_ssl_config() {
sed \
       -e "s\`ENV::EASYRSA\`EASYRSA\`g" \
       -e "s\`\$dir\`$EASYRSA_PKI\`g" \
       -e "s\`\$EASYRSA_PKI\`$EASYRSA_PKI\`g" \
       -e "s\`\$EASYRSA_CERT_EXPIRE\`$EASYRSA_CERT_EXPIRE\`g" \
       -e "s\`\$EASYRSA_CRL_DAYS\`$EASYRSA_CRL_DAYS\`g" \
       -e "s\`\$EASYRSA_DIGEST\`$EASYRSA_DIGEST\`g" \
       -e "s\`\$EASYRSA_KEY_SIZE\`$EASYRSA_KEY_SIZE\`g" \
       -e "s\`\$EASYRSA_DIGEST\`$EASYRSA_DIGEST\`g" \
       -e "s\`\$EASYRSA_DN\`$EASYRSA_DN\`g" \
       -e "s\`\$EASYRSA_REQ_COUNTRY\`$EASYRSA_REQ_COUNTRY\`g" \
       -e "s\`\$EASYRSA_REQ_PROVINCE\`$EASYRSA_REQ_PROVINCE\`g" \
       -e "s\`\$EASYRSA_REQ_CITY\`$EASYRSA_REQ_CITY\`g" \
       -e "s\`\$EASYRSA_REQ_ORG\`$EASYRSA_REQ_ORG\`g" \
       -e "s\`\$EASYRSA_REQ_OU\`$EASYRSA_REQ_OU\`g" \
       -e "s\`\$EASYRSA_REQ_CN\`$EASYRSA_REQ_CN\`g" \
       -e "s\`\$EASYRSA_REQ_EMAIL\`$EASYRSA_REQ_EMAIL\`g" \
	"$EASYRSA_SSL_CONF" > "$EASYRSA_SAFE_CONF" || die "\
Failed to update $EASYRSA_SAFE_CONF"
} # => make_ssl_config()
vars_source_check() {
	# Check for defined EASYRSA_PKI
	[ -n "$EASYRSA_PKI" ] || die "\
EASYRSA_PKI env-var undefined"
} # => vars_source_check()
# Verify supplied curve exists and generate curve file if needed
verify_curve() {
	if ! "$EASYRSA_OPENSSL" ecparam -name "$EASYRSA_CURVE" > /dev/null; then
		die "\
Curve $EASYRSA_CURVE not found. Run openssl ecparam -list_curves to show a
list of supported curves."
	fi
	# Check that the ecparams dir exists
	[ -d "$EASYRSA_EC_DIR" ] || mkdir "$EASYRSA_EC_DIR" || die "\
Failed creating ecparams dir (permissions?) at:
$EASYRSA_EC_DIR"
	# Check that the required ecparams file exists
	out="$EASYRSA_EC_DIR/${EASYRSA_CURVE}.pem"
	[ -f "$out" ] && return 0
	"$EASYRSA_OPENSSL" ecparam -name "$EASYRSA_CURVE" -out "$out" || die "\
Failed to generate ecparam file (permissions?) when writing to:
$out"
	# Explicitly return success for caller
	return 0
}
verify_ssl_lib () {
	# make safessl-easyrsa.cnf
	make_ssl_config
	# Verify EASYRSA_OPENSSL command gives expected output
	if [ -z "$EASYRSA_SSL_OK" ]; then
		val="$("$EASYRSA_OPENSSL" version)"
		case "${val%% *}" in
			OpenSSL|LibreSSL)
				notice "\
Using SSL: $EASYRSA_OPENSSL $("$EASYRSA_OPENSSL" version)" ;;
			*) die "\
Missing or invalid OpenSSL
Expected to find openssl command at: $EASYRSA_OPENSSL" ;;
		esac
	fi
	EASYRSA_SSL_OK=1
	# Verify EASYRSA_SSL_CONF file exists
	[ -f "$EASYRSA_SSL_CONF" ] || die "\
The OpenSSL config file cannot be found.
Expected location: $EASYRSA_SSL_CONF"
} # => verify_ssl_lib ()
# Basic sanity-check of PKI init and complain if missing
verify_pki_init() {
	help_note="Run easyrsa without commands for usage and command help."
	# check that the pki dir exists
	vars_source_check
	[ -d "$EASYRSA_PKI" ] || die "\
EASYRSA_PKI does not exist (perhaps you need to run init-pki)?
Expected to find the EASYRSA_PKI at: $EASYRSA_PKI
$help_note"
	# verify expected dirs present:
	for i in private reqs; do
		[ -d "$EASYRSA_PKI/$i" ] || die "\
Missing expected directory: $i (perhaps you need to run init-pki?)
$help_note"
	done
	# verify ssl lib
	verify_ssl_lib
} # => verify_pki_init()
# Verify core CA files present
verify_ca_init() {
	help_note="Run without commands for usage and command help."
	# First check the PKI has been initialized
	verify_pki_init
	# verify expected files present:
	for i in serial index.txt ca.crt private/ca.key; do
		if [ ! -f "$EASYRSA_PKI/$i" ]; then
			[ "$1" = "test" ] && return 1
			die "\
Missing expected CA file: $i (perhaps you need to run build-ca?)
$help_note"
		fi
	done
	# When operating in 'test' mode, return success.
	# test callers don't care about CA-specific dir structure
	[ "$1" = "test" ] && return 0
	# verify expected CA-specific dirs:
	for i in issued certs_by_serial \
		 revoked/certs_by_serial revoked/private_by_serial revoked/reqs_by_serial \
		 renewed/certs_by_serial renewed/private_by_serial renewed/reqs_by_serial ;
	do
		[ -d "$EASYRSA_PKI/$i" ] || die "\
Missing expected CA dir: $i (perhaps you need to run build-ca?)
$help_note"
	done
	# explicitly return success for callers
	return 0
} # => verify_ca_init()
# init-pki backend:
init_pki() {
	# If EASYRSA_PKI exists, confirm before we rm -rf (skiped with EASYRSA_BATCH)
	if [ -e "$EASYRSA_PKI" ]; then
		confirm "Confirm removal: " "yes" "
WARNING!!!
You are about to remove the EASYRSA_PKI at: $EASYRSA_PKI
and initialize a fresh PKI here."
		# now remove it:
		rm -rf "$EASYRSA_PKI" || die "Removal of PKI dir failed. Check/correct errors above"
	fi
	# new dirs:
	for i in private reqs; do
		mkdir -p "$EASYRSA_PKI/$i" || die "Failed to create PKI file structure (permissions?)"
	done
	
	if [ ! -f "$EASYRSA_SSL_CONF" ] && [ -f "$EASYRSA/openssl-easyrsa.cnf" ];
	then
		cp "$EASYRSA/openssl-easyrsa.cnf" "$EASYRSA_SSL_CONF"
	fi
	notice "\
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: $EASYRSA_PKI
"
	return 0
} # => init_pki()
hide_read_pass()
{
	(stty -echo 2>/dev/null) || set +o echo
	read -r "$@"
	(stty echo 2>/dev/null) || set -o echo
} # => hide_read_pass()
# build-ca backend:
build_ca() {
	opts=""
	sub_ca=""
	nopass=""
	crypto="-aes256"
	crypto_opts=""
	while [ -n "$1" ]; do
		case "$1" in
			subca) sub_ca=1 ;;
			nopass) nopass=1 ;;
			*) warn "Ignoring unknown command option: '$1'" ;;
		esac
		shift
	done
	verify_pki_init
	[ "$EASYRSA_ALGO" = "ec" ] && verify_curve
	# setup for the simpler sub-CA situation and overwrite with root-CA if needed:
	out_file="$EASYRSA_PKI/reqs/ca.req"
	out_key="$EASYRSA_PKI/private/ca.key"
	if [ ! $sub_ca ]; then
		out_file="$EASYRSA_PKI/ca.crt"
		opts="$opts -x509 -days $EASYRSA_CA_EXPIRE "
	fi
	# Test for existing CA, and complain if already present
	if verify_ca_init test; then
		die "\
Unable to create a CA as you already seem to have one set up.
If you intended to start a new CA, run init-pki first."
	fi
	# If a private key exists here, a sub-ca was created but not signed.
	# Notify the user and require a signed ca.crt or a init-pki:
	[ -f "$out_key" ] && \
		die "\
A CA private key exists but no ca.crt is found in your PKI dir of:
$EASYRSA_PKI
Refusing to create a new CA keypair as this operation would overwrite your
current CA keypair. If you intended to start a new CA, run init-pki first."
	# create necessary files and dirs:
	err_file="Unable to create necessary PKI files (permissions?)"
	for i in issued certs_by_serial \
		 revoked/certs_by_serial revoked/private_by_serial revoked/reqs_by_serial \
		 renewed/certs_by_serial renewed/private_by_serial renewed/reqs_by_serial;
	do
		mkdir -p "$EASYRSA_PKI/$i" || die "$err_file"
	done
	printf "" > "$EASYRSA_PKI/index.txt" || die "$err_file"
	print "01" > "$EASYRSA_PKI/serial" || die "$err_file"
	# Default CN only when not in global EASYRSA_BATCH mode:
	# shellcheck disable=SC2015
	[ "$EASYRSA_BATCH" ] && opts="$opts -batch" || export EASYRSA_REQ_CN="Easy-RSA CA"
	out_key_tmp="$(mktemp "$out_key.XXXXXXXXXX")"; EASYRSA_TEMP_FILE_2="$out_key_tmp"
	out_file_tmp="$(mktemp "$out_file.XXXXXXXXXX")"; EASYRSA_TEMP_FILE_3="$out_file_tmp"
	# Get password from user if necessary
	if [ ! $nopass ]; then
		out_key_pass_tmp="$(mktemp)"; EASYRSA_TEMP_FILE_4="$out_key_pass_tmp"
		echo
		printf "Enter New CA Key Passphrase: "
		hide_read_pass kpass
		echo
		printf "Re-Enter New CA Key Passphrase: "
		hide_read_pass kpass2
		echo
		# shellcheck disable=2154
		if [ "$kpass" = "$kpass2" ];
		then
			printf "%s" "$kpass" > "$out_key_pass_tmp"
		else
			die "Passphrases do not match."
		fi
	fi
	# create the CA key using AES256
	[ ! $nopass ] && crypto_opts="$crypto -passout file:$out_key_pass_tmp"
	if [ "$EASYRSA_ALGO" = "rsa" ]; then
		#shellcheck disable=SC2086
		"$EASYRSA_OPENSSL" genrsa -out "$out_key_tmp" $crypto_opts "$EASYRSA_ALGO_PARAMS"
	elif [ "$EASYRSA_ALGO" = "ec" ]; then
		#shellcheck disable=SC2086
		"$EASYRSA_OPENSSL" ecparam -in "$EASYRSA_ALGO_PARAMS" -genkey | \
			"$EASYRSA_OPENSSL" ec -out "$out_key_tmp" $crypto_opts
	fi
	# make safessl-easyrsa.cnf
	make_ssl_config
	# create the CA keypair:
	[ ! $nopass ] && crypto_opts="-passin file:$out_key_pass_tmp"
	#shellcheck disable=SC2086
	"$EASYRSA_OPENSSL" req -utf8 -new -key "$out_key_tmp" \
		-config "$EASYRSA_SAFE_CONF" -keyout "$out_key_tmp" -out "$out_file_tmp" $crypto_opts $opts || \
		die "Failed to build the CA"
	mv "$out_key_tmp" "$out_key"; EASYRSA_TEMP_FILE_2=
	mv "$out_file_tmp" "$out_file"; EASYRSA_TEMP_FILE_3=
	[ -f "$out_key_pass_tmp" ] && rm "$out_key_pass_tmp" && EASYRSA_TEMP_FILE_4=
	# Success messages
	if [ $sub_ca ]; then
		notice "\
NOTE: Your sub-CA request is at $out_file
and now must be sent to your parent CA for signing. Place your resulting cert
at $EASYRSA_PKI/ca.crt prior to signing operations.
"
	else	notice "\
CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
$out_file
"
	fi
	return 0
} # => build_ca()
# gen-dh backend:
gen_dh() {
	verify_pki_init
	out_file="$EASYRSA_PKI/dh.pem"
	"$EASYRSA_OPENSSL" dhparam -out "$out_file" "$EASYRSA_KEY_SIZE" || \
		die "Failed to build DH params"
	notice "\
DH parameters of size $EASYRSA_KEY_SIZE created at $out_file
"
	return 0
} # => gen_dh()
# gen-req backend:
gen_req() {
	# pull filename base and use as default interactive CommonName:
	[ -n "$1" ] || die "\
Error: gen-req must have a file base as the first argument.
Run easyrsa without commands for usage and commands."
	key_out="$EASYRSA_PKI/private/$1.key"
	req_out="$EASYRSA_PKI/reqs/$1.req"
	[ ! "$EASYRSA_BATCH" ] && EASYRSA_REQ_CN="$1"
	shift
	# function opts support
	opts=
	while [ -n "$1" ]; do
		case "$1" in
			nopass) opts="$opts -nodes" ;;
			# batch flag supports internal callers needing silent operation
			batch) EASYRSA_BATCH=1 ;;
			*) warn "Ignoring unknown command option: '$1'" ;;
		esac
		shift
	done
	verify_pki_init
	[ "$EASYRSA_ALGO" = "ec" ] && verify_curve
	# don't wipe out an existing private key without confirmation
	[ -f "$key_out" ] && confirm "Confirm key overwrite: " "yes" "\
WARNING!!!
An existing private key was found at $key_out
Continuing with key generation will replace this key."
	# When EASYRSA_EXTRA_EXTS is defined, append it to openssl's [req] section:
	if [ -n "$EASYRSA_EXTRA_EXTS" ]; then
		# Setup & insert the extra ext data keyed by a magic line
		extra_exts="
req_extensions = req_extra
[ req_extra ]
$EASYRSA_EXTRA_EXTS"
		#shellcheck disable=SC2016
		awkscript='
{if ( match($0, "^#%EXTRA_EXTS%") )
	{ while ( getline<"/dev/stdin" ) {print} next }
 {print}
}'
		print "$extra_exts" | \
			awk "$awkscript" "$EASYRSA_SSL_CONF" \
			> "$EASYRSA_TEMP_CONF" \
			|| die "Copying SSL config to temp file failed"
		# Use this new SSL config for the rest of this function
		EASYRSA_SSL_CONF="$EASYRSA_TEMP_CONF"
	fi
	# make safessl-easyrsa.cnf
	make_ssl_config
	key_out_tmp="$(mktemp "$key_out.XXXXXXXXXX")"; EASYRSA_TEMP_FILE_2="$key_out_tmp"
	req_out_tmp="$(mktemp "$req_out.XXXXXXXXXX")"; EASYRSA_TEMP_FILE_3="$req_out_tmp"
	# generate request
	[ $EASYRSA_BATCH ] && opts="$opts -batch"
	# shellcheck disable=2086,2148
	"$EASYRSA_OPENSSL" req -utf8 -new -newkey "$EASYRSA_ALGO":"$EASYRSA_ALGO_PARAMS" \
		-config "$EASYRSA_SAFE_CONF" -keyout "$key_out_tmp" -out "$req_out_tmp" $opts \
		|| die "Failed to generate request"
	mv "$key_out_tmp" "$key_out"; EASYRSA_TEMP_FILE_2=
	mv "$req_out_tmp" "$req_out"; EASYRSA_TEMP_FILE_3=
	notice "\
Keypair and certificate request completed. Your files are:
req: $req_out
key: $key_out
"
	return 0
} # => gen_req()
# common signing backend
sign_req() {
	crt_type="$1"
	opts=""
	req_in="$EASYRSA_PKI/reqs/$2.req"
	crt_out="$EASYRSA_PKI/issued/$2.crt"
	# Randomize Serial number
	i=""
	serial=""
	check_serial=""
	for i in 1 2 3 4 5; do
		"$EASYRSA_OPENSSL" rand -hex -out "$EASYRSA_PKI/serial" 16
		serial="$(cat "$EASYRSA_PKI/serial")"
		check_serial="$("$EASYRSA_OPENSSL" ca -config "$EASYRSA_SSL_CONF" -status "$serial" 2>&1)"
		case "$check_serial" in
			*"not present in db"*) break ;;
			*) continue ;;
		esac
	done
	# Support batch by internal caller:
	[ "$3" = "batch" ] && EASYRSA_BATCH=1
	verify_ca_init
	# Check argument sanity:
	[ -n "$2" ] || die "\
Incorrect number of arguments provided to sign-req:
expected 2, got $# (see command help for usage)"
	# Cert type must exist under the EASYRSA_EXT_DIR
	[ -r "$EASYRSA_EXT_DIR/$crt_type" ] || die "\
Unknown cert type '$crt_type'"
	# Request file must exist
	[ -f "$req_in" ] || die "\
No request found for the input: '$2'
Expected to find the request at: $req_in"
	# Confirm input is a cert req
	verify_file req "$req_in" || die "\
The certificate request file is not in a valid X509 request format.
Offending file: $req_in"
	# Display the request subject in an easy-to-read format
	# Confirm the user wishes to sign this request
	confirm "Confirm request details: " "yes" "
You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.
Request subject, to be signed as a $crt_type certificate for $EASYRSA_CERT_EXPIRE days:
$(display_dn req "$req_in")
"	# => confirm end
	# Generate the extensions file for this cert:
	{
		# Append first any COMMON file (if present) then the cert-type extensions
		cat "$EASYRSA_EXT_DIR/COMMON"
		cat "$EASYRSA_EXT_DIR/$crt_type"
		# copy req extensions
		[ "$EASYRSA_CP_EXT" ] && print "copy_extensions = copy"
		# Support a dynamic CA path length when present:
		[ "$crt_type" = "ca" ] && [ -n "$EASYRSA_SUBCA_LEN" ] && \
			print "basicConstraints = CA:TRUE, pathlen:$EASYRSA_SUBCA_LEN"
		# Deprecated Netscape extension support, if enabled
		if print "$EASYRSA_NS_SUPPORT" | awk_yesno; then
			[ -n "$EASYRSA_NS_COMMENT" ] && \
				print "nsComment = \"$EASYRSA_NS_COMMENT\""
			case "$crt_type" in
				serverClient)	print "nsCertType = serverClient" ;;
				server)		print "nsCertType = server" ;;
				client)		print "nsCertType = client" ;;
				ca)		print "nsCertType = sslCA" ;;
			esac
		fi
		# If type is server and no subjectAltName was requested,
		# add one to the extensions file
		if [ "$crt_type" = 'server' ];
		then
			echo "$EASYRSA_EXTRA_EXTS" |
				grep -q subjectAltName ||
				default_server_san "$req_in"
		fi
		# Add any advanced extensions supplied by env-var:
		[ -n "$EASYRSA_EXTRA_EXTS" ] && print "$EASYRSA_EXTRA_EXTS"
		: # needed to keep die from inherting the above test
	} > "$EASYRSA_TEMP_EXT" || die "\
Failed to create temp extension file (bad permissions?) at:
$EASYRSA_TEMP_EXT"
	# make safessl-easyrsa.cnf
	make_ssl_config
	# sign request
	# shellcheck disable=SC2086
	crt_out_tmp="$(mktemp "$crt_out.XXXXXXXXXX")"; EASYRSA_TEMP_FILE_2="$crt_out_tmp"
	"$EASYRSA_OPENSSL" ca -utf8 -in "$req_in" -out "$crt_out_tmp" -config "$EASYRSA_SAFE_CONF" \
		-extfile "$EASYRSA_TEMP_EXT" -days "$EASYRSA_CERT_EXPIRE" -batch $opts \
		|| die "signing failed (openssl output above may have more detail)"
	mv "$crt_out_tmp" "$crt_out"; EASYRSA_TEMP_FILE_2=
	notice "\
Certificate created at: $crt_out
"
	return 0
} # => sign_req()
# common build backend
# used to generate+sign in 1 step
build_full() {
	verify_ca_init
	# pull filename base:
	[ -n "$2" ] || die "\
Error: didn't find a file base name as the first argument.
Run easyrsa without commands for usage and commands."
	crt_type="$1" name="$2"
	req_out="$EASYRSA_PKI/reqs/$2.req"
	key_out="$EASYRSA_PKI/private/$2.key"
	crt_out="$EASYRSA_PKI/issued/$2.crt"
	shift 2
	# function opts support
	req_opts=
	while [ -n "$1" ]; do
		case "$1" in
			nopass) req_opts="$req_opts nopass" ;;
			*) warn "Ignoring unknown command option: '$1'" ;;
		esac
		shift
	done
	# abort on existing req/key/crt files
	err_exists="\
file already exists. Aborting build to avoid overwriting this file.
If you wish to continue, please use a different name or remove the file.
Matching file found at: "
	[ -f "$req_out" ] && die "Request $err_exists $req_out"
	[ -f "$key_out" ] && die "Key $err_exists $key_out"
	[ -f "$crt_out" ] && die "Certificate $err_exists $crt_out"
	# create request
	EASYRSA_REQ_CN="$name"
	#shellcheck disable=SC2086
	gen_req "$name" batch $req_opts
	# Sign it
	sign_req "$crt_type" "$name" batch
} # => build_full()
# revoke backend
revoke() {
	verify_ca_init
	# pull filename base:
	[ -n "$1" ] || die "\
Error: didn't find a file base name as the first argument.
Run easyrsa without commands for usage and command help."
	crt_in="$EASYRSA_PKI/issued/$1.crt"
	opts=""
	if [ "$2" ]; then
		opts="$opts -crl_reason $2"
	fi
	
	verify_file x509 "$crt_in" || die "\
Unable to revoke as the input file is not a valid certificate. Unexpected
input in file: $crt_in"
	# confirm operation by displaying DN:
	confirm "Continue with revocation: " "yes" "
Please confirm you wish to revoke the certificate with the following subject:
$(display_dn x509 "$crt_in")
"	# => confirm end
	# referenced cert must exist:
	[ -f "$crt_in" ] || die "\
Unable to revoke as no certificate was found. Certificate was expected
at: $crt_in"
	# make safessl-easyrsa.cnf
	make_ssl_config
	# shellcheck disable=SC2086
	"$EASYRSA_OPENSSL" ca -utf8 -revoke "$crt_in" -config "$EASYRSA_SAFE_CONF" $opts || die "\
Failed to revoke certificate: revocation command failed."
	# move revoked files so we can reissue certificates with the same name
	move_revoked "$1"
	notice "\
IMPORTANT!!!
Revocation was successful. You must run gen-crl and upload a CRL to your
infrastructure in order to prevent the revoked cert from being accepted.
"	# => notice end
	return 0
} #= revoke()
# move-revoked
# moves revoked certificates to an alternative folder
# allows reissuing certificates with the same name
move_revoked() {
	verify_ca_init
	[ -n "$1" ] || die "\
Error: didn't find a file base name as the first argument.
Run easyrsa without commands for usage and command help."
	crt_in="$EASYRSA_PKI/issued/$1.crt"
	key_in="$EASYRSA_PKI/private/$1.key"
	req_in="$EASYRSA_PKI/reqs/$1.req"
	verify_file x509 "$crt_in" || die "\
Unable to move revoked input file. The file is not a valid certificate. Unexpected
input in file: $crt_in"
	verify_file req "$req_in" || die "\
Unable to move request. The file is not a valid request. Unexpected
input in file: $req_in"
	# get the serial number of the certificate -> serial=XXXX
	cert_serial="$("$EASYRSA_OPENSSL" x509 -in "$crt_in" -noout -serial)"
	# remove the serial= part -> we only need the XXXX part
	cert_serial=${cert_serial##*=}
	crt_by_serial="$EASYRSA_PKI/certs_by_serial/$cert_serial.pem"
	crt_by_serial_revoked="$EASYRSA_PKI/revoked/certs_by_serial/$cert_serial.crt"
	key_by_serial_revoked="$EASYRSA_PKI/revoked/private_by_serial/$cert_serial.key"
	req_by_serial_revoked="$EASYRSA_PKI/revoked/reqs_by_serial/$cert_serial.req"
	# move crt, key and req file to revoked folders
	mv "$crt_in" "$crt_by_serial_revoked"
	mv "$req_in" "$req_by_serial_revoked"
	# only move the key if we have it
	if [ -e "$key_in" ]
	then
		mv "$key_in" "$key_by_serial_revoked"
	fi
	# move the rest of the files (p12, p7, ...)
	# shellcheck disable=SC2231
	for file in $EASYRSA_PKI/private/$1\.???
	do
		# get file extension
		file_ext="${file##*.}"
		[ -f "$file" ] && mv "$file" "$EASYRSA_PKI/revoked/private_by_serial/$cert_serial.$file_ext"
	done
	# remove the dublicate certificate in the certs_by_serial folder
	rm "$crt_by_serial"
	return 0
} #= move_revoked()
# renew backend
renew() {
	verify_ca_init
	# pull filename base:
	[ -n "$1" ] || die "\
Error: didn't find a file base name as the first argument.
Run easyrsa without commands for usage and command help."
	crt_in="$EASYRSA_PKI/issued/$1.crt"
	opts=""
	if [ "$2" ]; then
		opts="$2"
	fi
	verify_file x509 "$crt_in" || die "\
Unable to renew as the input file is not a valid certificate. Unexpected
input in file: $crt_in"
	# confirm operation by displaying DN:
	confirm "Continue with renew: " "yes" "
Please confirm you wish to renew the certificate with the following subject:
$(display_dn x509 "$crt_in")
"	# => confirm end
	# referenced cert must exist:
	[ -f "$crt_in" ] || die "\
Unable to renew as no certificate was found. Certificate was expected
at: $crt_in"
	# make safessl-easyrsa.cnf
	make_ssl_config
	# Check if old cert is expired or expires within 30 days
	expire_date=$(
		"$EASYRSA_OPENSSL" x509 -in "$crt_in" -noout -enddate |
		sed 's/^notAfter=//'
		)
        case $(uname) in
        	"Darwin"|*"BSD")
                	expire_date=$(date -j -f '%b %d %T %Y %Z' "$expire_date" +%s)
                	allow_renew_date=$(date -j -v"+${EASYRSA_CERT_RENEW}d" +%s)
                	;;
          	*)
                	# This works on Windows, too, since uname doesn't exist and this is catch-all
                	expire_date=$(date -d "$expire_date" +%s)
                	allow_renew_date=$(date -d "+${EASYRSA_CERT_RENEW}day" +%s)
                	;;
        esac
	[ "$expire_date" -lt "$allow_renew_date" ] || die "\
Certificate expires in more than $EASYRSA_CERT_RENEW days.
Renewal not allowed."
	# Extract certificate usage from old cert
	cert_ext_key_usage=$(
		"$EASYRSA_OPENSSL" x509 -in "$crt_in" -noout -text |
		sed -n "/X509v3 Extended Key Usage:/{n;s/^ *//g;p;}"
		)
	case $cert_ext_key_usage in
		"TLS Web Client Authentication")
			cert_type=client
			;;
		"TLS Web Server Authentication")
			cert_type=server
			;;
		"TLS Web Server Authentication, TLS Web Client Authentication")
			cert_type=serverClient
			;;
	esac
	# Use SAN from --subject-alt-name if set else use SAN from old cert
	echo "$EASYRSA_EXTRA_EXTS" | grep -q subjectAltName || \
	{
		san=$(
			"$EASYRSA_OPENSSL" x509 -in "$crt_in" -noout -text |
			sed -n "/X509v3 Subject Alternative Name:/{n;s/ //g;p;}"
			)
		[ -n "$san" ] && export EASYRSA_EXTRA_EXTS="\
$EASYRSA_EXTRA_EXTS
subjectAltName = $san"
	}
	# move renewed files so we can reissue certificate with the same name
	# FIXME: Modify revoke() to also work on the renewed certs subdir
	move_renewed "$1"
	# renew certificate
	# shellcheck disable=SC2086
	build_full $cert_type $1 $opts || die "\
Failed to renew certificate: renew command failed."
	notice "\
IMPORTANT!!!
Renew was successful.
You may want to revoke the old certificate once the new one has been deployed.
"	# => notice end
	return 0
} #= renew()
# move-renewed
# moves renewed certificates to an alternative folder
# allows reissuing certificates with the same name
move_renewed() {
	verify_ca_init
	[ -n "$1" ] || die "\
Error: didn't find a file base name as the first argument.
Run easyrsa without commands for usage and command help."
	crt_in="$EASYRSA_PKI/issued/$1.crt"
	key_in="$EASYRSA_PKI/private/$1.key"
	req_in="$EASYRSA_PKI/reqs/$1.req"
	verify_file x509 "$crt_in" || die "\
Unable to move renewed input file. The file is not a valid certificate. Unexpected
input in file: $crt_in"
	verify_file req "$req_in" || die "\
Unable to move request. The file is not a valid request. Unexpected
input in file: $req_in"
	# get the serial number of the certificate -> serial=XXXX
	cert_serial="$("$EASYRSA_OPENSSL" x509 -in "$crt_in" -noout -serial)"
	# remove the serial= part -> we only need the XXXX part
	cert_serial=${cert_serial##*=}
	crt_by_serial="$EASYRSA_PKI/certs_by_serial/$cert_serial.pem"
	crt_by_serial_renewed="$EASYRSA_PKI/renewed/certs_by_serial/$cert_serial.crt"
	key_by_serial_renewed="$EASYRSA_PKI/renewed/private_by_serial/$cert_serial.key"
	req_by_serial_renewed="$EASYRSA_PKI/renewed/reqs_by_serial/$cert_serial.req"
	# move crt, key and req file to renewed folders
	mv "$crt_in" "$crt_by_serial_renewed"
	mv "$req_in" "$req_by_serial_renewed"
	# only move the key if we have it
	if [ -e "$key_in" ]
	then
		mv "$key_in" "$key_by_serial_renewed"
	fi
	# move the rest of the files (p12, p7, ...)
	# shellcheck disable=SC2231
	for file in $EASYRSA_PKI/private/$1\.???
	do
		# get file extension
		file_ext="${file##*.}"
		[ -f "$file" ] && mv "$file" "$EASYRSA_PKI/renewed/private_by_serial/$cert_serial.$file_ext"
	done
	# remove the duplicate certificate in the certs_by_serial folder
	rm "$crt_by_serial"
	return 0
} #= move_renewed()
# gen-crl backend
gen_crl() {
	verify_ca_init
	# make safessl-easyrsa.cnf
	make_ssl_config
	out_file="$EASYRSA_PKI/crl.pem"
	out_file_tmp="$(mktemp "$out_file.XXXXXXXXXX")"; EASYRSA_TEMP_FILE_2="$out_file_tmp"
	"$EASYRSA_OPENSSL" ca -utf8 -gencrl -out "$out_file_tmp" -config "$EASYRSA_SAFE_CONF" || die "\
CRL Generation failed.
"
	mv "$out_file_tmp" "$out_file"; EASYRSA_TEMP_FILE_2=
	notice "\
An updated CRL has been created.
CRL file: $out_file
"
	return 0
} # => gen_crl()
# import-req backend
import_req() {
	verify_pki_init
	# pull passed paths
	in_req="$1" short_name="$2"
	out_req="$EASYRSA_PKI/reqs/$2.req" 
	[ -n "$short_name" ] || die "\
Unable to import: incorrect command syntax.
Run easyrsa without commands for usage and command help."
	verify_file req "$in_req" || die "\
The input file does not appear to be a certificate request. Aborting import.
Offending file: $in_req"
	# destination must not exist
	[ -f "$out_req" ] && die "\
Unable to import the request as the destination file already exists.
Please choose a different name for your imported request file.
Existing file at: $out_req"
	
	# now import it
	cp "$in_req" "$out_req"
	notice "\
The request has been successfully imported with a short name of: $short_name
You may now use this name to perform signing operations on this request.
"
	return 0
} # => import_req()
# export pkcs#12 or pkcs#7
export_pkcs() {
	pkcs_type="$1"
	shift
	[ -n "$1" ] || die "\
Unable to export p12: incorrect command syntax.
Run easyrsa without commands for usage and command help."
	short_name="$1"
	crt_in="$EASYRSA_PKI/issued/$1.crt"
	key_in="$EASYRSA_PKI/private/$1.key"
	crt_ca="$EASYRSA_PKI/ca.crt"
	shift
	verify_pki_init
	# opts support
	want_ca=1
	want_key=1
	while [ -n "$1" ]; do
		case "$1" in
			noca) want_ca="" ;;
			nokey) want_key="" ;;
			*) warn "Ignoring unknown command option: '$1'" ;;
		esac
		shift
	done
	pkcs_opts=
	if [ $want_ca ]; then
		verify_file x509 "$crt_ca" || die "\
Unable to include CA cert in the $pkcs_type output (missing file, or use noca option.)
Missing file expected at: $crt_ca"
		pkcs_opts="$pkcs_opts -certfile $crt_ca"
	fi
	# input files must exist
	verify_file x509 "$crt_in" || die "\
Unable to export $pkcs_type for short name '$short_name' without the certificate.
Missing cert expected at: $crt_in"
	case "$pkcs_type" in
	p12)
		pkcs_out="$EASYRSA_PKI/private/$short_name.p12"
		if [ $want_key ]; then
			[ -f "$key_in" ] || die "\
Unable to export p12 for short name '$short_name' without the key
(if you want a p12 without the private key, use nokey option.)
Missing key expected at: $key_in"
		else
			pkcs_opts="$pkcs_opts -nokeys"
		fi
		# export the p12:
		# shellcheck disable=SC2086
		"$EASYRSA_OPENSSL" pkcs12 -in "$crt_in" -inkey "$key_in" -export \
			-out "$pkcs_out" $pkcs_opts || die "\
Export of p12 failed: see above for related openssl errors."
	;;
	p7)
		pkcs_out="$EASYRSA_PKI/issued/$short_name.p7b"
		# export the p7:
		# shellcheck disable=SC2086
		"$EASYRSA_OPENSSL" crl2pkcs7 -nocrl -certfile "$crt_in" \
			-out "$pkcs_out" $pkcs_opts || die "\
Export of p7 failed: see above for related openssl errors."
	;;
esac
	notice "\
Successful export of $pkcs_type file. Your exported file is at the following
location: $pkcs_out
"
	return 0
} # => export_pkcs()
# set-pass backend
set_pass() {
	verify_pki_init
	# key type, supplied internally from frontend command call (rsa/ec)
	key_type="$1"
	# values supplied by the user:
	raw_file="$2"
	file="$EASYRSA_PKI/private/$raw_file.key"
	[ -n "$raw_file" ] || die "\
Missing argument to 'set-$key_type-pass' command: no name/file supplied.
See help output for usage details."
	# parse command options
	shift 2
	crypto="-aes256"
	while [ -n "$1" ]; do
		case "$1" in
			nopass)	crypto="" ;;
			file)	file="$raw_file" ;;
			*)	warn "Ignoring unknown command option: '$1'" ;;
		esac
		shift
	done
	[ -f "$file" ] || die "\
Missing private key: expected to find the private key component at:
$file"
	notice "\
If the key is currently encrypted you must supply the decryption passphrase.
${crypto:+You will then enter a new PEM passphrase for this key.$NL}"
	EASYRSA_TEMP_FILE_2="$file.temp"
	"$EASYRSA_OPENSSL" "$key_type" -in "$file" -out "$EASYRSA_TEMP_FILE_2" $crypto || die "\
Failed to change the private key passphrase. See above for possible openssl
error messages."
	mv "$EASYRSA_TEMP_FILE_2" "$file" || die "\
Failed to change the private key passphrase. See above for error messages."
	notice "Key passphrase successfully changed"
	
} # => set_pass()
# update-db backend
update_db() {
	verify_ca_init
	"$EASYRSA_OPENSSL" ca -utf8 -updatedb -config "$EASYRSA_SSL_CONF" || die "\
Failed to perform update-db: see above for related openssl errors."
	return 0
} # => update_db()
# display cert DN info on a req/X509, passed by full pathname
display_dn() {
	format="$1" path="$2"
	print "$("$EASYRSA_OPENSSL" "$format" -in "$path" -noout -subject -nameopt multiline)"
} # => display_dn()
# generate default SAN from req/X509, passed by full pathname
default_server_san() {
	path="$1"
	cn=$(
		"$EASYRSA_OPENSSL" req -in "$path" -noout -subject -nameopt sep_multiline |
		awk -F'=' '/^  *CN=/{print $2}'
		)
	echo "$cn" | grep -E -q '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'
	#shellcheck disable=SC2181
	if [ $? -eq 0 ]; then
		print "subjectAltName = IP:$cn"
	else
		print "subjectAltName = DNS:$cn"
	fi
} # => default_server_san()
# verify a file seems to be a valid req/X509
verify_file() {
	format="$1" 
	path="$2"
	"$EASYRSA_OPENSSL" "$format" -in "$path" -noout 2>/dev/null || return 1
	return 0
} # => verify_file()
# show-* command backend
# Prints req/cert details in a readable format
show() {
	type="$1" 
	name="$2" 
	in_file=""
	format=""
	[ -n "$name" ] || die "\
Missing expected filename_base argument.
Run easyrsa without commands for usage help."
	shift 2
	# opts support
	opts="-${type}opt no_pubkey,no_sigdump"
	while [ -n "$1" ]; do
		case "$1" in
			full) 
				opts=""
				;;
			*) 
				warn "Ignoring unknown command option: '$1'" 
				;;
		esac
		shift
	done
	# Determine cert/req type
	if [ "$type" = "cert" ]; then
		verify_ca_init
		in_file="$EASYRSA_PKI/issued/${name}.crt"
		format="x509"
	else
		verify_pki_init
		in_file="$EASYRSA_PKI/reqs/${name}.req"
		format="req"
	fi
	# Verify file exists and is of the correct type
	[ -f "$in_file" ] || die "\
No such $type file with a basename of '$name' is present.
Expected to find this file at:
$in_file"
	verify_file $format "$in_file" || die "\
This file is not a valid $type file:
$in_file"
	notice "\
Showing $type details for '$name'.
This file is stored at:
$in_file
"
	"$EASYRSA_OPENSSL" $format -in "$in_file" -noout -text\
		-nameopt multiline $opts || die "\
OpenSSL failure to process the input"
} # => show()
# show-ca command backend
# Prints CA cert details in a readable format
show_ca() {
	# opts support
	opts="-certopt no_pubkey,no_sigdump"
	while [ -n "$1" ]; do
		case "$1" in
			full) opts= ;;
			*) warn "Ignoring unknown command option: '$1'" ;;
		esac
		shift
	done
	verify_ca_init
	in_file="$EASYRSA_PKI/ca.crt"
	format="x509"
	# Verify file exists and is of the correct type
	[ -f "$in_file" ] || die "\
No such $type file with a basename of '$name' is present.
Expected to find this file at:
$in_file"
	verify_file $format "$in_file" || die "\
This file is not a valid $type file:
$in_file"
	notice "\
Showing $type details for 'ca'.
This file is stored at:
$in_file
"
	"$EASYRSA_OPENSSL" $format -in "$in_file" -noout -text\
		-nameopt multiline $opts || die "\
OpenSSL failure to process the input"
} # => show_ca()
# vars setup
# Here sourcing of 'vars' if present occurs. If not present, defaults are used
# to support running without a sourced config format
vars_setup() {
	# Try to locate a 'vars' file in order of location preference.
	# If one is found, source it
	vars=
	# set up program path
	prog_vars="${0%/*}/vars"
	# set up PKI path
	pki_vars="${EASYRSA_PKI:-$PWD/pki}/vars"
	# command-line path:
	if [ -f "$EASYRSA_VARS_FILE" ]; then
		vars="$EASYRSA_VARS_FILE"
	# PKI location, if present:
	elif [ -f "$pki_vars" ]; then
		vars="$pki_vars"
	# EASYRSA, if defined:
	elif [ -n "$EASYRSA" ] && [ -f "$EASYRSA/vars" ]; then
		vars="$EASYRSA/vars"
	# program location:
	elif [ -f "$prog_vars" ]; then
		vars="$prog_vars"
	fi
	
	# If a vars file was located, source it
	# If $EASYRSA_NO_VARS is defined (not blank) this is skipped
	if [ -z "$EASYRSA_NO_VARS" ] && [ -n "$vars" ]; then
		#shellcheck disable=SC2034
		EASYRSA_CALLER=1 
		# shellcheck disable=SC1090
		. "$vars"
		notice "\
Note: using Easy-RSA configuration from: $vars"
	fi
	
	# Set defaults, preferring existing env-vars if present
	set_var EASYRSA		"${0%/*}"
	set_var EASYRSA_OPENSSL	openssl
	set_var EASYRSA_PKI	"$PWD/pki"
	set_var EASYRSA_DN	cn_only
	set_var EASYRSA_REQ_COUNTRY	"US"
	set_var EASYRSA_REQ_PROVINCE	"California"
	set_var EASYRSA_REQ_CITY	"San Francisco"
	set_var EASYRSA_REQ_ORG		"Copyleft Certificate Co"
	set_var EASYRSA_REQ_EMAIL	me@example.net
	set_var EASYRSA_REQ_OU		"My Organizational Unit"
	set_var EASYRSA_ALGO		rsa
	set_var EASYRSA_KEY_SIZE	2048
	set_var EASYRSA_CURVE		secp384r1
	set_var EASYRSA_EC_DIR		"$EASYRSA_PKI/ecparams"
	set_var EASYRSA_CA_EXPIRE	3650
	set_var EASYRSA_CERT_EXPIRE	1080 # new default of 36 months	
	set_var EASYRSA_CERT_RENEW	30
	set_var EASYRSA_CRL_DAYS	180
	set_var EASYRSA_NS_SUPPORT	no
	set_var EASYRSA_NS_COMMENT	"Easy-RSA (v3.0.6) Generated Certificate"
	set_var EASYRSA_TEMP_CONF	"$EASYRSA_PKI/openssl-easyrsa.temp"
	set_var EASYRSA_TEMP_EXT	"$EASYRSA_PKI/extensions.temp"
	set_var EASYRSA_TEMP_FILE_2	""
	set_var EASYRSA_TEMP_FILE_3	""
	set_var EASYRSA_REQ_CN		ChangeMe
	set_var EASYRSA_DIGEST		sha256
	set_var EASYRSA_SSL_CONF	"$EASYRSA_PKI/openssl-easyrsa.cnf"
	set_var EASYRSA_SAFE_CONF	"$EASYRSA_PKI/safessl-easyrsa.cnf"
	# Same as above for the x509-types extensions dir
	if [ -d "$EASYRSA_PKI/x509-types" ]; then
		set_var EASYRSA_EXT_DIR		"$EASYRSA_PKI/x509-types"
	else	
		#TODO: This should be removed.  Not really suitable for packaging.
		set_var EASYRSA_EXT_DIR		"$EASYRSA/x509-types"
	fi
	# EASYRSA_ALGO_PARAMS must be set depending on selected algo
	if [ "ec" = "$EASYRSA_ALGO" ]; then
		EASYRSA_ALGO_PARAMS="$EASYRSA_EC_DIR/${EASYRSA_CURVE}.pem"
	elif [ "rsa" = "$EASYRSA_ALGO" ]; then
		EASYRSA_ALGO_PARAMS="${EASYRSA_KEY_SIZE}"
	else
		die "Alg '$EASYRSA_ALGO' is invalid: must be 'rsa' or 'ec'"
	fi
	# Setting OPENSSL_CONF prevents bogus warnings (especially useful on win32)
	export OPENSSL_CONF="$EASYRSA_SAFE_CONF"
} # vars_setup()
# variable assignment by indirection when undefined; merely exports
# the variable when it is already defined (even if currently null)
# Sets $1 as the value contained in $2 and exports (may be blank)
set_var() {
	var=$1
	shift
	value="$*"
	eval "export $var=\"\${$var-$value}\""
} #=> set_var()
########################################
# Invocation entry point:
NL='
'
# Be secure with a restrictive umask
[ -z "$EASYRSA_NO_UMASK" ] && umask 077
# Parse options
while :; do
	# Separate option from value:
	opt="${1%%=*}"
	val="${1#*=}"
	empty_ok="" # Empty values are not allowed unless excepted
	case "$opt" in
	--days)
		export EASYRSA_CERT_EXPIRE="$val"
		export EASYRSA_CA_EXPIRE="$val"
		export EASYRSA_CRL_DAYS="$val"
		;;
	--pki-dir)
		export EASYRSA_PKI="$val" ;;
	--use-algo)
		export EASYRSA_ALGO="$val" ;;
	--keysize)
		export EASYRSA_KEY_SIZE="$val" ;;
	--curve)
		export EASYRSA_CURVE="$val" ;;
	--dn-mode)
		export EASYRSA_DN="$val" ;;
	--req-cn)
		export EASYRSA_REQ_CN="$val" ;;
	--digest)
		export EASYRSA_DIGEST="$val" ;;
	--req-c)
		empty_ok=1
		export EASYRSA_REQ_COUNTRY="$val" ;;
	--req-st)
		empty_ok=1
		export EASYRSA_REQ_PROVINCE="$val" ;;
	--req-city)
		empty_ok=1
		export EASYRSA_REQ_CITY="$val" ;;
	--req-org)
		empty_ok=1
		export EASYRSA_REQ_ORG="$val" ;;
	--req-email)
		empty_ok=1
		export EASYRSA_REQ_EMAIL="$val" ;;
	--req-ou)
		empty_ok=1
		export EASYRSA_REQ_OU="$val" ;;
	--ns-cert)
		export EASYRSA_NS_SUPPORT="$val" ;;
	--ns-comment)
		empty_ok=1
		export EASYRSA_NS_COMMENT="$val" ;;
	--batch)
		empty_ok=1
		export EASYRSA_BATCH=1 ;;
	--subca-len)
		export EASYRSA_SUBCA_LEN="$val" ;;
	--vars)
		export EASYRSA_VARS_FILE="$val" ;;
	--copy-ext)
		empty_ok=1
		export EASYRSA_CP_EXT=1 ;;
	--subject-alt-name)
		export EASYRSA_EXTRA_EXTS="\
$EASYRSA_EXTRA_EXTS
subjectAltName = $val" ;;
	*)
		break ;;
	esac
	# fatal error when no value was provided
	if [ ! $empty_ok ] && { [ "$val" = "$1" ] || [ -z "$val" ]; }; then
		die "Missing value to option: $opt"
	fi
	shift
done
# Intelligent env-var detection and auto-loading:
vars_setup
# Register clean_temp and prog_exit on SIGHUP, SIGINT, SIGQUIT, and SIGABRT
trap "clean_temp; prog_exit 1" 1 
trap "clean_temp; prog_exit 2" 2
trap "clean_temp; prog_exit 3" 3
trap "clean_temp; prog_exit 6" 6
trap "clean_temp; prog_exit 15" 15
# determine how we were called, then hand off to the function responsible
cmd="$1"
[ -n "$1" ] && shift # scrape off command
case "$cmd" in
	init-pki|clean-all)
		init_pki "$@"
		;;
	build-ca)
		build_ca "$@"
		;;
	gen-dh)
		gen_dh
		;;
	gen-req)
		gen_req "$@"
		;;
	sign|sign-req)
		sign_req "$@"
		;;
	build-client-full)
		build_full client "$@"
		;;
	build-server-full)
		build_full server "$@"
		;;
	build-serverClient-full)
		build_full serverClient "$@"
		;;
	gen-crl)
		gen_crl
		;;
	revoke)
		revoke "$@"
		;;
	renew)
		renew "$@"
		;;
	import-req)
		import_req "$@"
		;;
	export-p12)
		export_pkcs p12 "$@"
		;;
	export-p7)
		export_pkcs p7 "$@"
		;;
	set-rsa-pass)
		set_pass rsa "$@"
		;;
	set-ec-pass)
		set_pass ec "$@"
		;;
	update-db)
		update_db
		;;
	show-req)
		show req "$@"
		;;
	show-cert)
		show cert "$@"
		;;
	show-ca)
		show_ca "$@"
		;;
	""|help|-h|--help|--usage)
		cmd_help "$1"
		exit 0
		;;
	*)
		die "Unknown command '$cmd'. Run without commands for usage help."
		;;
esac
# vim: ft=sh nu ai sw=8 ts=8 noet
ubuntu@ubuntu:~/ca$ cat easyrsa | less
ubuntu@ubuntu:~/ca$ easyrsa help init-pki
easyrsa: command not found
ubuntu@ubuntu:~/ca$ ./easyrsa help init-pki
Note: using Easy-RSA configuration from: ./vars
  init-pki [ cmd-opts ]
      Removes & re-initializes the PKI dir for a clean PKI
ubuntu@ubuntu:~/ca$ ./easyrsa init-pki
Note: using Easy-RSA configuration from: ./vars
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /home/ubuntu/ca/pki
ubuntu@ubuntu:~/ca$ ./easyrsa build-ca
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
Enter New CA Key Passphrase: 
Re-Enter New CA Key Passphrase: 
Generating RSA private key, 2048 bit long modulus (2 primes)
..........................+++++
...............+++++
e is 65537 (0x010001)
Can't load /home/ubuntu/ca/pki/.rnd into RNG
281473638455776:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:98:Filename=/home/ubuntu/ca/pki/.rnd
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:justin
CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/home/ubuntu/ca/pki/ca.crt
ubuntu@ubuntu:~/ca$ l
easyrsa@  openssl-easyrsa.cnf  pki/  vars  x509-types@
ubuntu@ubuntu:~/ca$ cd pko
-bash: cd: pko: No such file or directory
ubuntu@ubuntu:~/ca$ cd pki
ubuntu@ubuntu:~/ca/pki$ ll
total 60
drwx------ 8 ubuntu ubuntu 4096 Aug  7 21:16 ./
drwx------ 3 ubuntu ubuntu 4096 Aug  7 20:30 ../
-rw------- 1 ubuntu ubuntu 1024 Aug  7 21:16 .rnd
-rw------- 1 ubuntu ubuntu 1184 Aug  7 21:16 ca.crt
drwx------ 2 ubuntu ubuntu 4096 Aug  7 20:31 certs_by_serial/
-rw------- 1 ubuntu ubuntu    0 Aug  7 20:31 index.txt
drwx------ 2 ubuntu ubuntu 4096 Aug  7 20:31 issued/
-rw------- 1 ubuntu ubuntu 4651 Aug  7 20:30 openssl-easyrsa.cnf
drwx------ 2 ubuntu ubuntu 4096 Aug  7 21:16 private/
drwx------ 5 ubuntu ubuntu 4096 Aug  7 20:31 renewed/
drwx------ 2 ubuntu ubuntu 4096 Aug  7 20:30 reqs/
drwx------ 5 ubuntu ubuntu 4096 Aug  7 20:31 revoked/
-rw------- 1 ubuntu ubuntu 4581 Aug  7 21:15 safessl-easyrsa.cnf
-rw------- 1 ubuntu ubuntu    3 Aug  7 20:31 serial
ubuntu@ubuntu:~/ca/pki$ sudo apt install openvpn
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages were automatically installed and are no longer required:
  linux-headers-5.4.0-1036-raspi linux-image-5.4.0-1036-raspi
  linux-modules-5.4.0-1036-raspi linux-raspi-headers-5.4.0-1036
Use 'sudo apt autoremove' to remove them.
The following additional packages will be installed:
  libpkcs11-helper1
Suggested packages:
  resolvconf openvpn-systemd-resolved
The following NEW packages will be installed:
  libpkcs11-helper1 openvpn
0 upgraded, 2 newly installed, 0 to remove and 2 not upgraded.
Need to get 489 kB of archives.
After this operation, 1298 kB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Get:1 http://ports.ubuntu.com/ubuntu-ports focal/main arm64 libpkcs11-helper1 arm64 1.26-1 [41.2 kB]
Get:2 http://ports.ubuntu.com/ubuntu-ports focal-updates/main arm64 openvpn arm64 2.4.7-1ubuntu2.20.04.3 [448 kB]
Fetched 489 kB in 7s (70.1 kB/s)                                                   
Preconfiguring packages ...
Selecting previously unselected package libpkcs11-helper1:arm64.
(Reading database ... 133008 files and directories currently installed.)
Preparing to unpack .../libpkcs11-helper1_1.26-1_arm64.deb ...
Unpacking libpkcs11-helper1:arm64 (1.26-1) ...
Selecting previously unselected package openvpn.
Preparing to unpack .../openvpn_2.4.7-1ubuntu2.20.04.3_arm64.deb ...
Unpacking openvpn (2.4.7-1ubuntu2.20.04.3) ...
Setting up libpkcs11-helper1:arm64 (1.26-1) ...
Setting up openvpn (2.4.7-1ubuntu2.20.04.3) ...
 * Restarting virtual private network daemon.                                [ OK ] 
Created symlink /etc/systemd/system/multi-user.target.wants/openvpn.service → /lib/systemd/system/openvpn.service.
Processing triggers for systemd (245.4-4ubuntu3.11) ...
Processing triggers for man-db (2.9.1-1) ...
Processing triggers for libc-bin (2.31-0ubuntu9.2) ...
ubuntu@ubuntu:~/ca/pki$ cd ..
ubuntu@ubuntu:~/ca$ cd ..
ubuntu@ubuntu:~$ make-cadir ca2
ubuntu@ubuntu:~$ ll
total 48
drwxr-xr-x 6 ubuntu ubuntu 4096 Aug  7 21:23 ./
drwxr-xr-x 4 root   root   4096 Jun 14 18:15 ../
-rw------- 1 ubuntu ubuntu  246 Jun 14 18:16 .bash_history
-rw-r--r-- 1 ubuntu ubuntu  220 Feb 25  2020 .bash_logout
-rw-r--r-- 1 ubuntu ubuntu 3771 Feb 25  2020 .bashrc
drwx------ 2 ubuntu ubuntu 4096 Jun 10 08:27 .cache/
-rw-r--r-- 1 ubuntu ubuntu  807 Feb 25  2020 .profile
-rw------- 1 ubuntu ubuntu   14 Aug  7 15:53 .python_history
drwx------ 2 ubuntu ubuntu 4096 Apr  2  2020 .ssh/
-rw-r--r-- 1 ubuntu ubuntu    0 Jun 10 08:28 .sudo_as_admin_successful
-rw------- 1 ubuntu ubuntu  950 Aug  7 20:28 .viminfo
drwx------ 3 ubuntu ubuntu 4096 Aug  7 20:30 ca/
drwx------ 2 ubuntu ubuntu 4096 Aug  7 21:23 ca2/
ubuntu@ubuntu:~$ cd ca2
ubuntu@ubuntu:~/ca2$ vim ./vars
ubuntu@ubuntu:~/ca2$ ./easyrsa init-pki
Note: using Easy-RSA configuration from: ./vars
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /home/ubuntu/ca2/pki
ubuntu@ubuntu:~/ca2$ ./easyrsa gen-req server nopass
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
Can't load /home/ubuntu/ca2/pki/.rnd into RNG
281472897886688:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:98:Filename=/home/ubuntu/ca2/pki/.rnd
Generating a RSA private key
......................................................................+++++
........................................+++++
writing new private key to '/home/ubuntu/ca2/pki/private/server.key.E0jvOn97cs'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [server]:
Keypair and certificate request completed. Your files are:
req: /home/ubuntu/ca2/pki/reqs/server.req
key: /home/ubuntu/ca2/pki/private/server.key
ubuntu@ubuntu:~/ca2$ ls /etc/openvpn
client  server  update-resolv-conf
ubuntu@ubuntu:~/ca2$ sudo mv pki/private/server.key /etc/open
opensc/  openvpn/ 
ubuntu@ubuntu:~/ca2$ sudo mv pki/private/server.key /etc/open
opensc/  openvpn/ 
ubuntu@ubuntu:~/ca2$ sudo mv pki/private/server.key /etc/openvpn
ubuntu@ubuntu:~/ca2$ ls /etc/openvpn
client  server  server.key  update-resolv-conf
ubuntu@ubuntu:~/ca2$ cd ..
ubuntu@ubuntu:~$ cd ca
ubuntu@ubuntu:~/ca$ ll
total 32
drwx------ 3 ubuntu ubuntu 4096 Aug  7 20:30 ./
drwxr-xr-x 6 ubuntu ubuntu 4096 Aug  7 21:24 ../
lrwxrwxrwx 1 ubuntu ubuntu   27 Aug  7 16:07 easyrsa -> /usr/share/easy-rsa/easyrsa*
-rw-r--r-- 1 ubuntu ubuntu 4651 Aug  7 16:07 openssl-easyrsa.cnf
drwx------ 8 ubuntu ubuntu 4096 Aug  7 21:16 pki/
-rw-r--r-- 1 ubuntu ubuntu 8528 Aug  7 20:28 vars
lrwxrwxrwx 1 ubuntu ubuntu   30 Aug  7 16:07 x509-types -> /usr/share/easy-rsa/x509-types/
ubuntu@ubuntu:~/ca$ ./easyrsa import-req ~/ca2/pki/reqs/server.req server
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
The request has been successfully imported with a short name of: server
You may now use this name to perform signing operations on this request.
ubuntu@ubuntu:~/ca$ ./easyrsa sign-req server server
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.
Request subject, to be signed as a server certificate for 1080 days:
subject=
    commonName                = server
Type the word 'yes' to continue, or any other input to abort.
  Confirm request details: yes
Using configuration from /home/ubuntu/ca/pki/safessl-easyrsa.cnf
Enter pass phrase for /home/ubuntu/ca/pki/private/ca.key:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'server'
Certificate is to be certified until Jul 22 16:29:21 2024 GMT (1080 days)
Write out database with 1 new entries
Data Base Updated
Certificate created at: /home/ubuntu/ca/pki/issued/server.crt
ubuntu@ubuntu:~/ca$ ls
easyrsa  openssl-easyrsa.cnf  pki  vars  x509-types
ubuntu@ubuntu:~/ca$ cd pki
ubuntu@ubuntu:~/ca/pki$ ll
total 76
drwx------ 8 ubuntu ubuntu 4096 Aug  8 00:29 ./
drwx------ 3 ubuntu ubuntu 4096 Aug  7 20:30 ../
-rw------- 1 ubuntu ubuntu 1024 Aug  8 00:29 .rnd
-rw------- 1 ubuntu ubuntu 1184 Aug  7 21:16 ca.crt
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:29 certs_by_serial/
-rw------- 1 ubuntu ubuntu  536 Aug  8 00:29 extensions.temp
-rw------- 1 ubuntu ubuntu   69 Aug  8 00:29 index.txt
-rw------- 1 ubuntu ubuntu   20 Aug  8 00:29 index.txt.attr
-rw------- 1 ubuntu ubuntu    0 Aug  7 20:31 index.txt.old
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:29 issued/
-rw------- 1 ubuntu ubuntu 4651 Aug  7 20:30 openssl-easyrsa.cnf
drwx------ 2 ubuntu ubuntu 4096 Aug  7 21:16 private/
drwx------ 5 ubuntu ubuntu 4096 Aug  7 20:31 renewed/
drwx------ 2 ubuntu ubuntu 4096 Aug  7 23:19 reqs/
drwx------ 5 ubuntu ubuntu 4096 Aug  7 20:31 revoked/
-rw------- 1 ubuntu ubuntu 4575 Aug  8 00:29 safessl-easyrsa.cnf
-rw------- 1 ubuntu ubuntu   33 Aug  8 00:29 serial
-rw------- 1 ubuntu ubuntu   33 Aug  8 00:29 serial.old
ubuntu@ubuntu:~/ca/pki$ cd reqs
ubuntu@ubuntu:~/ca/pki/reqs$ ll
total 12
drwx------ 2 ubuntu ubuntu 4096 Aug  7 23:19 ./
drwx------ 8 ubuntu ubuntu 4096 Aug  8 00:29 ../
-rw------- 1 ubuntu ubuntu  887 Aug  7 23:19 server.req
ubuntu@ubuntu:~/ca/pki/reqs$ rm server.req
ubuntu@ubuntu:~/ca/pki/reqs$ cd ..
ubuntu@ubuntu:~/ca/pki$ cd issued/
ubuntu@ubuntu:~/ca/pki/issued$ ll
total 16
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:29 ./
drwx------ 8 ubuntu ubuntu 4096 Aug  8 00:29 ../
-rw------- 1 ubuntu ubuntu 4586 Aug  8 00:29 server.crt
ubuntu@ubuntu:~/ca/pki/issued$ mv server.crt /etc/openvpn
mv: cannot move 'server.crt' to '/etc/openvpn/server.crt': Permission denied
ubuntu@ubuntu:~/ca/pki/issued$ sudo mv server.crt /etc/openvpn
ubuntu@ubuntu:~/ca/pki/issued$ cd ..
ubuntu@ubuntu:~/ca/pki$ ll
total 76
drwx------ 8 ubuntu ubuntu 4096 Aug  8 00:29 ./
drwx------ 3 ubuntu ubuntu 4096 Aug  7 20:30 ../
-rw------- 1 ubuntu ubuntu 1024 Aug  8 00:29 .rnd
-rw------- 1 ubuntu ubuntu 1184 Aug  7 21:16 ca.crt
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:29 certs_by_serial/
-rw------- 1 ubuntu ubuntu  536 Aug  8 00:29 extensions.temp
-rw------- 1 ubuntu ubuntu   69 Aug  8 00:29 index.txt
-rw------- 1 ubuntu ubuntu   20 Aug  8 00:29 index.txt.attr
-rw------- 1 ubuntu ubuntu    0 Aug  7 20:31 index.txt.old
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:31 issued/
-rw------- 1 ubuntu ubuntu 4651 Aug  7 20:30 openssl-easyrsa.cnf
drwx------ 2 ubuntu ubuntu 4096 Aug  7 21:16 private/
drwx------ 5 ubuntu ubuntu 4096 Aug  7 20:31 renewed/
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:30 reqs/
drwx------ 5 ubuntu ubuntu 4096 Aug  7 20:31 revoked/
-rw------- 1 ubuntu ubuntu 4575 Aug  8 00:29 safessl-easyrsa.cnf
-rw------- 1 ubuntu ubuntu   33 Aug  8 00:29 serial
-rw------- 1 ubuntu ubuntu   33 Aug  8 00:29 serial.old
ubuntu@ubuntu:~/ca/pki$ ll /etc/openvpn
total 32
drwxr-xr-x   4 root   root   4096 Aug  8 00:31 ./
drwxr-xr-x 101 root   root   4096 Aug  7 21:19 ../
drwxr-xr-x   2 root   root   4096 Jul 20 03:26 client/
drwxr-xr-x   2 root   root   4096 Jul 20 03:26 server/
-rw-------   1 ubuntu ubuntu 4586 Aug  8 00:29 server.crt
-rw-------   1 ubuntu ubuntu 1704 Aug  7 21:24 server.key
-rwxr-xr-x   1 root   root   1468 Jul 20 03:26 update-resolv-conf*
ubuntu@ubuntu:~/ca/pki$ sudo mv ca.crt /etc/openvpn/
ubuntu@ubuntu:~/ca/pki$ ll /etc/openvpn
total 36
drwxr-xr-x   4 root   root   4096 Aug  8 00:31 ./
drwxr-xr-x 101 root   root   4096 Aug  7 21:19 ../
-rw-------   1 ubuntu ubuntu 1184 Aug  7 21:16 ca.crt
drwxr-xr-x   2 root   root   4096 Jul 20 03:26 client/
drwxr-xr-x   2 root   root   4096 Jul 20 03:26 server/
-rw-------   1 ubuntu ubuntu 4586 Aug  8 00:29 server.crt
-rw-------   1 ubuntu ubuntu 1704 Aug  7 21:24 server.key
-rwxr-xr-x   1 root   root   1468 Jul 20 03:26 update-resolv-conf*
ubuntu@ubuntu:~/ca/pki$ cd ..
ubuntu@ubuntu:~/ca$ ./easyrsa gen-db
Note: using Easy-RSA configuration from: ./vars
Easy-RSA error:
Unknown command 'gen-db'. Run without commands for usage help.
ubuntu@ubuntu:~/ca$ ./easyrsa gen-dh
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
................................................+.........................................................+........+.........................................................................................................+............................+.........................................+................................................................................................................................................................................................................................................................................................................................................................................................................................................................................+.......+...............................................................+.................................+....................................................................................................................................................................................................................................................+.......+.....................................................+.....................................................................................................................+.........................................................................................................................+....................................................................................+.........................................................................+.......+......................................................................+.............................................................................................................................................................+...............................+....+...............+....................+........................................................................................................................................................................+..................................................................................................................+.........................................................................................................................................................+......................................................+........................................+.........................+....................+........................................................................................................................................................................+.................................................+..................................................................................................................................................+......................................................................................................................+...........................................................+....+..........+.................................................................................................+.....................................................................................+.............+..............................................................+.................................................+................................................................................................................+..............................................................................+...+..............................................................................................+....................................................................................+.................................................................................................................................................................................................................+................+....................................+............................................................................................................................................................................................................................................................+........................................................+......................................................................................................................................+..............................................+........................................................................................................................................................++*++*++*++*
DH parameters of size 2048 created at /home/ubuntu/ca/pki/dh.pem
ubuntu@ubuntu:~/ca$ sudo mv pki/dh.pem /etc/openvpn/dh2048.pem
ubuntu@ubuntu:~/ca$ openvpn --genkey --secret ta.key
ubuntu@ubuntu:~/ca$ ll
total 36
drwx------ 3 ubuntu ubuntu 4096 Aug  8 00:35 ./
drwxr-xr-x 6 ubuntu ubuntu 4096 Aug  7 21:24 ../
lrwxrwxrwx 1 ubuntu ubuntu   27 Aug  7 16:07 easyrsa -> /usr/share/easy-rsa/easyrsa*
-rw-r--r-- 1 ubuntu ubuntu 4651 Aug  7 16:07 openssl-easyrsa.cnf
drwx------ 8 ubuntu ubuntu 4096 Aug  8 00:34 pki/
-rw------- 1 ubuntu ubuntu  636 Aug  8 00:35 ta.key
-rw-r--r-- 1 ubuntu ubuntu 8528 Aug  7 20:28 vars
lrwxrwxrwx 1 ubuntu ubuntu   30 Aug  7 16:07 x509-types -> /usr/share/easy-rsa/x509-types/
ubuntu@ubuntu:~/ca$ cat ta.key
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
f502828b60e55511e371346247fb1ad1
a07f329e4f972389f92057271114a3b5
ed6bce0bb8b849678baaa08568621e08
57073a4ebb04d965c8d5a2868c2faad7
46468fa3235b48a60df39c3951780e84
7628aa974f27bb4d159b6f66732a4de9
e21ac7c4cd270efaec66a594e613fb09
29b68d60144a60567cf7b01bcde3d52d
01e0ebe43d2d50dda188d1cd5535cea5
f6b08453bca7f641a4fd7aa5fdf17a82
8a351ac17c47a343b0ee18aa5cc452a5
65883c67eeb24bc3d2f2d5b893ff19cf
436c24af0f069d611115fe6c545c861e
982f43d29ce2e723d87542b41debb143
8c0a0e328ce603debed8ac61e7231529
3ea47d74dd2f00438440b049dbfa6db5
-----END OpenVPN Static key V1-----
ubuntu@ubuntu:~/ca$ sudo mv ta.key /etc/openvpn
ubuntu@ubuntu:~/ca$ man zcat
ubuntu@ubuntu:~/ca$ zcat /usr/share/doc/open
open-iscsi/          opensc-pkcs11/       openssh-server/      openssl/
opensc/              openssh-client/      openssh-sftp-server/ openvpn/
ubuntu@ubuntu:~/ca$ zcat /usr/share/doc/open
open-iscsi/          opensc-pkcs11/       openssh-server/      openssl/
opensc/              openssh-client/      openssh-sftp-server/ openvpn/
ubuntu@ubuntu:~/ca$ zcat /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | sudo tee /etc/openvpn/server.conf
#################################################
# Sample OpenVPN 2.0 config file for            #
# multi-client server.                          #
#                                               #
# This file is for the server side              #
# of a many-clients <-> one-server              #
# OpenVPN configuration.                        #
#                                               #
# OpenVPN also supports                         #
# single-machine <-> single-machine             #
# configurations (See the Examples page         #
# on the web site for more info).               #
#                                               #
# This config should work on Windows            #
# or Linux/BSD systems.  Remember on            #
# Windows to quote pathnames and use            #
# double backslashes, e.g.:                     #
# "C:\\Program Files\\OpenVPN\\config\\foo.key" #
#                                               #
# Comments are preceded with '#' or ';'         #
#################################################
# Which local IP address should OpenVPN
# listen on? (optional)
;local a.b.c.d
# Which TCP/UDP port should OpenVPN listen on?
# If you want to run multiple OpenVPN instances
# on the same machine, use a different port
# number for each one.  You will need to
# open up this port on your firewall.
port 1194
# TCP or UDP server?
;proto tcp
proto udp
# "dev tun" will create a routed IP tunnel,
# "dev tap" will create an ethernet tunnel.
# Use "dev tap0" if you are ethernet bridging
# and have precreated a tap0 virtual interface
# and bridged it with your ethernet interface.
# If you want to control access policies
# over the VPN, you must create firewall
# rules for the the TUN/TAP interface.
# On non-Windows systems, you can give
# an explicit unit number, such as tun0.
# On Windows, use "dev-node" for this.
# On most systems, the VPN will not function
# unless you partially or fully disable
# the firewall for the TUN/TAP interface.
;dev tap
dev tun
# Windows needs the TAP-Win32 adapter name
# from the Network Connections panel if you
# have more than one.  On XP SP2 or higher,
# you may need to selectively disable the
# Windows firewall for the TAP adapter.
# Non-Windows systems usually don't need this.
;dev-node MyTap
# SSL/TLS root certificate (ca), certificate
# (cert), and private key (key).  Each client
# and the server must have their own cert and
# key file.  The server and all clients will
# use the same ca file.
#
# See the "easy-rsa" directory for a series
# of scripts for generating RSA certificates
# and private keys.  Remember to use
# a unique Common Name for the server
# and each of the client certificates.
#
# Any X509 key management system can be used.
# OpenVPN can also use a PKCS #12 formatted key file
# (see "pkcs12" directive in man page).
ca ca.crt
cert server.crt
key server.key  # This file should be kept secret
# Diffie hellman parameters.
# Generate your own with:
#   openssl dhparam -out dh2048.pem 2048
dh dh2048.pem
# Network topology
# Should be subnet (addressing via IP)
# unless Windows clients v2.0.9 and lower have to
# be supported (then net30, i.e. a /30 per client)
# Defaults to net30 (not recommended)
;topology subnet
# Configure server mode and supply a VPN subnet
# for OpenVPN to draw client addresses from.
# The server will take 10.8.0.1 for itself,
# the rest will be made available to clients.
# Each client will be able to reach the server
# on 10.8.0.1. Comment this line out if you are
# ethernet bridging. See the man page for more info.
server 10.8.0.0 255.255.255.0
# Maintain a record of client <-> virtual IP address
# associations in this file.  If OpenVPN goes down or
# is restarted, reconnecting clients can be assigned
# the same virtual IP address from the pool that was
# previously assigned.
ifconfig-pool-persist /var/log/openvpn/ipp.txt
# Configure server mode for ethernet bridging.
# You must first use your OS's bridging capability
# to bridge the TAP interface with the ethernet
# NIC interface.  Then you must manually set the
# IP/netmask on the bridge interface, here we
# assume 10.8.0.4/255.255.255.0.  Finally we
# must set aside an IP range in this subnet
# (start=10.8.0.50 end=10.8.0.100) to allocate
# to connecting clients.  Leave this line commented
# out unless you are ethernet bridging.
;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100
# Configure server mode for ethernet bridging
# using a DHCP-proxy, where clients talk
# to the OpenVPN server-side DHCP server
# to receive their IP address allocation
# and DNS server addresses.  You must first use
# your OS's bridging capability to bridge the TAP
# interface with the ethernet NIC interface.
# Note: this mode only works on clients (such as
# Windows), where the client-side TAP adapter is
# bound to a DHCP client.
;server-bridge
# Push routes to the client to allow it
# to reach other private subnets behind
# the server.  Remember that these
# private subnets will also need
# to know to route the OpenVPN client
# address pool (10.8.0.0/255.255.255.0)
# back to the OpenVPN server.
;push "route 192.168.10.0 255.255.255.0"
;push "route 192.168.20.0 255.255.255.0"
# To assign specific IP addresses to specific
# clients or if a connecting client has a private
# subnet behind it that should also have VPN access,
# use the subdirectory "ccd" for client-specific
# configuration files (see man page for more info).
# EXAMPLE: Suppose the client
# having the certificate common name "Thelonious"
# also has a small subnet behind his connecting
# machine, such as 192.168.40.128/255.255.255.248.
# First, uncomment out these lines:
;client-config-dir ccd
;route 192.168.40.128 255.255.255.248
# Then create a file ccd/Thelonious with this line:
#   iroute 192.168.40.128 255.255.255.248
# This will allow Thelonious' private subnet to
# access the VPN.  This example will only work
# if you are routing, not bridging, i.e. you are
# using "dev tun" and "server" directives.
# EXAMPLE: Suppose you want to give
# Thelonious a fixed VPN IP address of 10.9.0.1.
# First uncomment out these lines:
;client-config-dir ccd
;route 10.9.0.0 255.255.255.252
# Then add this line to ccd/Thelonious:
#   ifconfig-push 10.9.0.1 10.9.0.2
# Suppose that you want to enable different
# firewall access policies for different groups
# of clients.  There are two methods:
# (1) Run multiple OpenVPN daemons, one for each
#     group, and firewall the TUN/TAP interface
#     for each group/daemon appropriately.
# (2) (Advanced) Create a script to dynamically
#     modify the firewall in response to access
#     from different clients.  See man
#     page for more info on learn-address script.
;learn-address ./script
# If enabled, this directive will configure
# all clients to redirect their default
# network gateway through the VPN, causing
# all IP traffic such as web browsing and
# and DNS lookups to go through the VPN
# (The OpenVPN server machine may need to NAT
# or bridge the TUN/TAP interface to the internet
# in order for this to work properly).
;push "redirect-gateway def1 bypass-dhcp"
# Certain Windows-specific network settings
# can be pushed to clients, such as DNS
# or WINS server addresses.  CAVEAT:
# http://openvpn.net/faq.html#dhcpcaveats
# The addresses below refer to the public
# DNS servers provided by opendns.com.
;push "dhcp-option DNS 208.67.222.222"
;push "dhcp-option DNS 208.67.220.220"
# Uncomment this directive to allow different
# clients to be able to "see" each other.
# By default, clients will only see the server.
# To force clients to only see the server, you
# will also need to appropriately firewall the
# server's TUN/TAP interface.
;client-to-client
# Uncomment this directive if multiple clients
# might connect with the same certificate/key
# files or common names.  This is recommended
# only for testing purposes.  For production use,
# each client should have its own certificate/key
# pair.
#
# IF YOU HAVE NOT GENERATED INDIVIDUAL
# CERTIFICATE/KEY PAIRS FOR EACH CLIENT,
# EACH HAVING ITS OWN UNIQUE "COMMON NAME",
# UNCOMMENT THIS LINE OUT.
;duplicate-cn
# The keepalive directive causes ping-like
# messages to be sent back and forth over
# the link so that each side knows when
# the other side has gone down.
# Ping every 10 seconds, assume that remote
# peer is down if no ping received during
# a 120 second time period.
keepalive 10 120
# For extra security beyond that provided
# by SSL/TLS, create an "HMAC firewall"
# to help block DoS attacks and UDP port flooding.
#
# Generate with:
#   openvpn --genkey --secret ta.key
#
# The server and each client must have
# a copy of this key.
# The second parameter should be '0'
# on the server and '1' on the clients.
tls-auth ta.key 0 # This file is secret
# Select a cryptographic cipher.
# This config item must be copied to
# the client config file as well.
# Note that v2.4 client/server will automatically
# negotiate AES-256-GCM in TLS mode.
# See also the ncp-cipher option in the manpage
cipher AES-256-CBC
# Enable compression on the VPN link and push the
# option to the client (v2.4+ only, for earlier
# versions see below)
;compress lz4-v2
;push "compress lz4-v2"
# For compression compatible with older clients use comp-lzo
# If you enable it here, you must also
# enable it in the client config file.
;comp-lzo
# The maximum number of concurrently connected
# clients we want to allow.
;max-clients 100
# It's a good idea to reduce the OpenVPN
# daemon's privileges after initialization.
#
# You can uncomment this out on
# non-Windows systems.
;user nobody
;group nogroup
# The persist options will try to avoid
# accessing certain resources on restart
# that may no longer be accessible because
# of the privilege downgrade.
persist-key
persist-tun
# Output a short status file showing
# current connections, truncated
# and rewritten every minute.
status /var/log/openvpn/openvpn-status.log
# By default, log messages will go to the syslog (or
# on Windows, if running as a service, they will go to
# the "\Program Files\OpenVPN\log" directory).
# Use log or log-append to override this default.
# "log" will truncate the log file on OpenVPN startup,
# while "log-append" will append to it.  Use one
# or the other (but not both).
;log         /var/log/openvpn/openvpn.log
;log-append  /var/log/openvpn/openvpn.log
# Set the appropriate level of log
# file verbosity.
#
# 0 is silent, except for fatal errors
# 4 is reasonable for general usage
# 5 and 6 can help to debug connection problems
# 9 is extremely verbose
verb 3
# Silence repeating messages.  At most 20
# sequential messages of the same message
# category will be output to the log.
;mute 20
# Notify the client that when the server restarts so it
# can automatically reconnect.
explicit-exit-notify 1ubuntu@ubuntu:~/ca$ vim /etc/openvpn/server.conf
ubuntu@ubuntu:~/ca$ sudo vim /etc/openvpn/server.conf
ubuntu@ubuntu:~/ca$ ll /etc/openvpn
total 56
drwxr-xr-x   4 root   root    4096 Aug  8 00:42 ./
drwxr-xr-x 101 root   root    4096 Aug  7 21:19 ../
-rw-------   1 ubuntu ubuntu  1184 Aug  7 21:16 ca.crt
drwxr-xr-x   2 root   root    4096 Jul 20 03:26 client/
-rw-------   1 ubuntu ubuntu   424 Aug  8 00:34 dh2048.pem
drwxr-xr-x   2 root   root    4096 Jul 20 03:26 server/
-rw-r--r--   1 root   root   10849 Aug  8 00:42 server.conf
-rw-------   1 ubuntu ubuntu  4586 Aug  8 00:29 server.crt
-rw-------   1 ubuntu ubuntu  1704 Aug  7 21:24 server.key
-rw-------   1 ubuntu ubuntu   636 Aug  8 00:35 ta.key
-rwxr-xr-x   1 root   root    1468 Jul 20 03:26 update-resolv-conf*
ubuntu@ubuntu:~/ca$ sudo chown -R root:root /etc/openvpn
ubuntu@ubuntu:~/ca$ vim /etc/sysctl.conf
ubuntu@ubuntu:~/ca$ sudo vim /etc/sysctl.conf
ubuntu@ubuntu:~/ca$ sudo sysctl -p
net.ipv4.ip_forward = 1
ubuntu@ubuntu:~/ca$ sudo vim /etc/default/ufw
ubuntu@ubuntu:~/ca$ sudo vim /etc/ufw/before.rules
ubuntu@ubuntu:~/ca$ sudo ufw allow openvpn
Rule added
Rule added (v6)
ubuntu@ubuntu:~/ca$ sudo ufw status
Status: active
To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere                  
443/tcp                    ALLOW       Anywhere                  
80/tcp                     ALLOW       Anywhere                  
1194                       ALLOW       Anywhere                  
22/tcp (v6)                ALLOW       Anywhere (v6)             
443/tcp (v6)               ALLOW       Anywhere (v6)             
80/tcp (v6)                ALLOW       Anywhere (v6)             
1194 (v6)                  ALLOW       Anywhere (v6)             
ubuntu@ubuntu:~/ca$ sudo ufw restart
ERROR: Invalid syntax
Usage: ufw COMMAND
Commands:
 enable                          enables the firewall
 disable                         disables the firewall
 default ARG                     set default policy
 logging LEVEL                   set logging to LEVEL
 allow ARGS                      add allow rule
 deny ARGS                       add deny rule
 reject ARGS                     add reject rule
 limit ARGS                      add limit rule
 delete RULE|NUM                 delete RULE
 insert NUM RULE                 insert RULE at NUM
 route RULE                      add route RULE
 route delete RULE|NUM           delete route RULE
 route insert NUM RULE           insert route RULE at NUM
 reload                          reload firewall
 reset                           reset firewall
 status                          show firewall status
 status numbered                 show firewall status as numbered list of RULES
 status verbose                  show verbose firewall status
 show ARG                        show firewall report
 version                         display version information
Application profile commands:
 app list                        list application profiles
 app info PROFILE                show information on PROFILE
 app update PROFILE              update PROFILE
 app default ARG                 set default application policy
ubuntu@ubuntu:~/ca$ sudo ufw reload
Firewall reloaded
ubuntu@ubuntu:~/ca$ sudo systemctl restart openvpn
ubuntu@ubuntu:~/ca$ sudo systemctl enable openvpn
Synchronizing state of openvpn.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable openvpn
ubuntu@ubuntu:~/ca$ cd ../ca2
ubuntu@ubuntu:~/ca2$ ./easyrsa gen-req client nopass
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
Generating a RSA private key
....................................+++++
..........................................................................+++++
writing new private key to '/home/ubuntu/ca2/pki/private/client.key.d3wrA8e9ft'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [client]:^C
ubuntu@ubuntu:~/ca2$ cd ..
ubuntu@ubuntu:~$ easyrsa
easyrsa: command not found
ubuntu@ubuntu:~$ make-cadir ca3
ubuntu@ubuntu:~$ cd ca3
ubuntu@ubuntu:~/ca3$ ./easyrsa gen-req client nopass
Note: using Easy-RSA configuration from: ./vars
Easy-RSA error:
EASYRSA_PKI does not exist (perhaps you need to run init-pki)?
Expected to find the EASYRSA_PKI at: /home/ubuntu/ca3/pki
Run easyrsa without commands for usage and command help.
ubuntu@ubuntu:~/ca3$ ./easyrsa init-pki
Note: using Easy-RSA configuration from: ./vars
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /home/ubuntu/ca3/pki
ubuntu@ubuntu:~/ca3$ ./easyrsa gen-req client nopass
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
Can't load /home/ubuntu/ca3/pki/.rnd into RNG
281473270442464:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:98:Filename=/home/ubuntu/ca3/pki/.rnd
Generating a RSA private key
............................................................................................................................................................+++++
...........................................................................................+++++
writing new private key to '/home/ubuntu/ca3/pki/private/client.key.dzoPTzPoW1'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [client]:
Keypair and certificate request completed. Your files are:
req: /home/ubuntu/ca3/pki/reqs/client.req
key: /home/ubuntu/ca3/pki/private/client.key
ubuntu@ubuntu:~/ca3$ cd ..
ubuntu@ubuntu:~$ cd ca2
ubuntu@ubuntu:~/ca2$ ll
total 32
drwx------ 3 ubuntu ubuntu 4096 Aug  7 21:24 ./
drwxr-xr-x 7 ubuntu ubuntu 4096 Aug  8 00:49 ../
lrwxrwxrwx 1 ubuntu ubuntu   27 Aug  7 21:23 easyrsa -> /usr/share/easy-rsa/easyrsa*
-rw-r--r-- 1 ubuntu ubuntu 4651 Aug  7 21:23 openssl-easyrsa.cnf
drwx------ 4 ubuntu ubuntu 4096 Aug  7 21:25 pki/
-rw-r--r-- 1 ubuntu ubuntu 8525 Aug  7 21:24 vars
lrwxrwxrwx 1 ubuntu ubuntu   30 Aug  7 21:23 x509-types -> /usr/share/easy-rsa/x509-types/
ubuntu@ubuntu:~/ca2$ ./easyrsa import-req ~/ca3/pki/reqs/client.req client
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
The request has been successfully imported with a short name of: client
You may now use this name to perform signing operations on this request.
ubuntu@ubuntu:~/ca2$ ./easyrsa sign-req client client
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
Easy-RSA error:
Missing expected CA file: index.txt (perhaps you need to run build-ca?)
Run easyrsa without commands for usage and command help.
ubuntu@ubuntu:~/ca2$ cd ..
ubuntu@ubuntu:~$ cd ca
ubuntu@ubuntu:~/ca$ ll
total 32
drwx------ 3 ubuntu ubuntu 4096 Aug  8 00:36 ./
drwxr-xr-x 7 ubuntu ubuntu 4096 Aug  8 00:49 ../
lrwxrwxrwx 1 ubuntu ubuntu   27 Aug  7 16:07 easyrsa -> /usr/share/easy-rsa/easyrsa*
-rw-r--r-- 1 ubuntu ubuntu 4651 Aug  7 16:07 openssl-easyrsa.cnf
drwx------ 8 ubuntu ubuntu 4096 Aug  8 00:34 pki/
-rw-r--r-- 1 ubuntu ubuntu 8528 Aug  7 20:28 vars
lrwxrwxrwx 1 ubuntu ubuntu   30 Aug  7 16:07 x509-types -> /usr/share/easy-rsa/x509-types/
ubuntu@ubuntu:~/ca$ ./easyrsa import-req ~/ca3/pki/reqs/client.req client
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
The request has been successfully imported with a short name of: client
You may now use this name to perform signing operations on this request.
ubuntu@ubuntu:~/ca$ ./easyrsa sign-req client client
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
Easy-RSA error:
Missing expected CA file: ca.crt (perhaps you need to run build-ca?)
Run easyrsa without commands for usage and command help.
ubuntu@ubuntu:~/ca$ ll
total 32
drwx------ 3 ubuntu ubuntu 4096 Aug  8 00:36 ./
drwxr-xr-x 7 ubuntu ubuntu 4096 Aug  8 00:49 ../
lrwxrwxrwx 1 ubuntu ubuntu   27 Aug  7 16:07 easyrsa -> /usr/share/easy-rsa/easyrsa*
-rw-r--r-- 1 ubuntu ubuntu 4651 Aug  7 16:07 openssl-easyrsa.cnf
drwx------ 8 ubuntu ubuntu 4096 Aug  8 00:34 pki/
-rw-r--r-- 1 ubuntu ubuntu 8528 Aug  7 20:28 vars
lrwxrwxrwx 1 ubuntu ubuntu   30 Aug  7 16:07 x509-types -> /usr/share/easy-rsa/x509-types/
ubuntu@ubuntu:~/ca$ ll /etc/openvpn
total 56
drwxr-xr-x   4 root root  4096 Aug  8 00:42 ./
drwxr-xr-x 101 root root  4096 Aug  8 00:43 ../
-rw-------   1 root root  1184 Aug  7 21:16 ca.crt
drwxr-xr-x   2 root root  4096 Jul 20 03:26 client/
-rw-------   1 root root   424 Aug  8 00:34 dh2048.pem
drwxr-xr-x   2 root root  4096 Jul 20 03:26 server/
-rw-r--r--   1 root root 10849 Aug  8 00:42 server.conf
-rw-------   1 root root  4586 Aug  8 00:29 server.crt
-rw-------   1 root root  1704 Aug  7 21:24 server.key
-rw-------   1 root root   636 Aug  8 00:35 ta.key
-rwxr-xr-x   1 root root  1468 Jul 20 03:26 update-resolv-conf*
ubuntu@ubuntu:~/ca$ sudo cp ca.crt ./
cp: cannot stat 'ca.crt': No such file or directory
ubuntu@ubuntu:~/ca$ sudo cp /etc/openvpn/ca.crt ./
ubuntu@ubuntu:~/ca$ ./easyrsa import-req ~/ca3/pki/reqs/client.req client
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
Easy-RSA error:
Unable to import the request as the destination file already exists.
Please choose a different name for your imported request file.
Existing file at: /home/ubuntu/ca/pki/reqs/client.req
ubuntu@ubuntu:~/ca$ ./easyrsa sign-req client client
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
Easy-RSA error:
Missing expected CA file: ca.crt (perhaps you need to run build-ca?)
Run easyrsa without commands for usage and command help.
ubuntu@ubuntu:~/ca$ ll
total 36
drwx------ 3 ubuntu ubuntu 4096 Aug  8 00:54 ./
drwxr-xr-x 7 ubuntu ubuntu 4096 Aug  8 00:49 ../
-rw------- 1 root   root   1184 Aug  8 00:54 ca.crt
lrwxrwxrwx 1 ubuntu ubuntu   27 Aug  7 16:07 easyrsa -> /usr/share/easy-rsa/easyrsa*
-rw-r--r-- 1 ubuntu ubuntu 4651 Aug  7 16:07 openssl-easyrsa.cnf
drwx------ 8 ubuntu ubuntu 4096 Aug  8 00:34 pki/
-rw-r--r-- 1 ubuntu ubuntu 8528 Aug  7 20:28 vars
lrwxrwxrwx 1 ubuntu ubuntu   30 Aug  7 16:07 x509-types -> /usr/share/easy-rsa/x509-types/
ubuntu@ubuntu:~/ca$ ll pki
total 68
drwx------ 8 ubuntu ubuntu 4096 Aug  8 00:34 ./
drwx------ 3 ubuntu ubuntu 4096 Aug  8 00:54 ../
-rw------- 1 ubuntu ubuntu 1024 Aug  8 00:54 .rnd
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:29 certs_by_serial/
-rw------- 1 ubuntu ubuntu   69 Aug  8 00:29 index.txt
-rw------- 1 ubuntu ubuntu   20 Aug  8 00:29 index.txt.attr
-rw------- 1 ubuntu ubuntu    0 Aug  7 20:31 index.txt.old
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:31 issued/
-rw------- 1 ubuntu ubuntu 4651 Aug  7 20:30 openssl-easyrsa.cnf
drwx------ 2 ubuntu ubuntu 4096 Aug  7 21:16 private/
drwx------ 5 ubuntu ubuntu 4096 Aug  7 20:31 renewed/
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:53 reqs/
drwx------ 5 ubuntu ubuntu 4096 Aug  7 20:31 revoked/
-rw------- 1 ubuntu ubuntu 4575 Aug  8 00:54 safessl-easyrsa.cnf
-rw------- 1 ubuntu ubuntu   33 Aug  8 00:54 serial
-rw------- 1 ubuntu ubuntu   33 Aug  8 00:29 serial.old
ubuntu@ubuntu:~/ca$ mv ca.crt pki/ca.crt
ubuntu@ubuntu:~/ca$ ./easyrsa sign-req client client
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.
Request subject, to be signed as a client certificate for 1080 days:
subject=
    commonName                = client
Type the word 'yes' to continue, or any other input to abort.
  Confirm request details: yes
Using configuration from /home/ubuntu/ca/pki/safessl-easyrsa.cnf
Enter pass phrase for /home/ubuntu/ca/pki/private/ca.key:
Can't open /home/ubuntu/ca/pki/ca.crt for reading, Permission denied
281473456122336:error:0200100D:system library:fopen:Permission denied:../crypto/bio/bss_file.c:69:fopen('/home/ubuntu/ca/pki/ca.crt','r')
281473456122336:error:2006D002:BIO routines:BIO_new_file:system lib:../crypto/bio/bss_file.c:78:
unable to load certificate
Easy-RSA error:
signing failed (openssl output above may have more detail)
ubuntu@ubuntu:~/ca$ ll pki
total 72
drwx------ 8 ubuntu ubuntu 4096 Aug  8 00:55 ./
drwx------ 3 ubuntu ubuntu 4096 Aug  8 00:55 ../
-rw------- 1 ubuntu ubuntu 1024 Aug  8 00:55 .rnd
-rw------- 1 root   root   1184 Aug  8 00:54 ca.crt
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:29 certs_by_serial/
-rw------- 1 ubuntu ubuntu   69 Aug  8 00:29 index.txt
-rw------- 1 ubuntu ubuntu   20 Aug  8 00:29 index.txt.attr
-rw------- 1 ubuntu ubuntu    0 Aug  7 20:31 index.txt.old
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:55 issued/
-rw------- 1 ubuntu ubuntu 4651 Aug  7 20:30 openssl-easyrsa.cnf
drwx------ 2 ubuntu ubuntu 4096 Aug  7 21:16 private/
drwx------ 5 ubuntu ubuntu 4096 Aug  7 20:31 renewed/
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:53 reqs/
drwx------ 5 ubuntu ubuntu 4096 Aug  7 20:31 revoked/
-rw------- 1 ubuntu ubuntu 4575 Aug  8 00:55 safessl-easyrsa.cnf
-rw------- 1 ubuntu ubuntu   33 Aug  8 00:55 serial
-rw------- 1 ubuntu ubuntu   33 Aug  8 00:29 serial.old
ubuntu@ubuntu:~/ca$ sudo chmod ubuntu:ubuntu pki/ca.crt
chmod: invalid mode: ‘ubuntu:ubuntu’
Try 'chmod --help' for more information.
ubuntu@ubuntu:~/ca$ sudo chown ubuntu:ubuntu pki/ca.crt
ubuntu@ubuntu:~/ca$ ./easyrsa sign-req client client
Note: using Easy-RSA configuration from: ./vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.
Request subject, to be signed as a client certificate for 1080 days:
subject=
    commonName                = client
Type the word 'yes' to continue, or any other input to abort.
  Confirm request details: yes
Using configuration from /home/ubuntu/ca/pki/safessl-easyrsa.cnf
Enter pass phrase for /home/ubuntu/ca/pki/private/ca.key:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'client'
Certificate is to be certified until Jul 22 16:56:19 2024 GMT (1080 days)
Write out database with 1 new entries
Data Base Updated
Certificate created at: /home/ubuntu/ca/pki/issued/client.crt
ubuntu@ubuntu:~/ca$ ll
total 32
drwx------ 3 ubuntu ubuntu 4096 Aug  8 00:55 ./
drwxr-xr-x 7 ubuntu ubuntu 4096 Aug  8 00:49 ../
lrwxrwxrwx 1 ubuntu ubuntu   27 Aug  7 16:07 easyrsa -> /usr/share/easy-rsa/easyrsa*
-rw-r--r-- 1 ubuntu ubuntu 4651 Aug  7 16:07 openssl-easyrsa.cnf
drwx------ 8 ubuntu ubuntu 4096 Aug  8 00:56 pki/
-rw-r--r-- 1 ubuntu ubuntu 8528 Aug  7 20:28 vars
lrwxrwxrwx 1 ubuntu ubuntu   30 Aug  7 16:07 x509-types -> /usr/share/easy-rsa/x509-types/
ubuntu@ubuntu:~/ca$ cd pki
ubuntu@ubuntu:~/ca/pki$ ll
total 84
drwx------ 8 ubuntu ubuntu 4096 Aug  8 00:56 ./
drwx------ 3 ubuntu ubuntu 4096 Aug  8 00:55 ../
-rw------- 1 ubuntu ubuntu 1024 Aug  8 00:56 .rnd
-rw------- 1 ubuntu ubuntu 1184 Aug  8 00:54 ca.crt
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:56 certs_by_serial/
-rw------- 1 ubuntu ubuntu  492 Aug  8 00:56 extensions.temp
-rw------- 1 ubuntu ubuntu  138 Aug  8 00:56 index.txt
-rw------- 1 ubuntu ubuntu   20 Aug  8 00:56 index.txt.attr
-rw------- 1 ubuntu ubuntu   20 Aug  8 00:29 index.txt.attr.old
-rw------- 1 ubuntu ubuntu   69 Aug  8 00:29 index.txt.old
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:56 issued/
-rw------- 1 ubuntu ubuntu 4651 Aug  7 20:30 openssl-easyrsa.cnf
drwx------ 2 ubuntu ubuntu 4096 Aug  7 21:16 private/
drwx------ 5 ubuntu ubuntu 4096 Aug  7 20:31 renewed/
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:53 reqs/
drwx------ 5 ubuntu ubuntu 4096 Aug  7 20:31 revoked/
-rw------- 1 ubuntu ubuntu 4575 Aug  8 00:56 safessl-easyrsa.cnf
-rw------- 1 ubuntu ubuntu   33 Aug  8 00:56 serial
-rw------- 1 ubuntu ubuntu   33 Aug  8 00:56 serial.old
ubuntu@ubuntu:~/ca/pki$ cd reqs
ubuntu@ubuntu:~/ca/pki/reqs$ ll
total 12
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:53 ./
drwx------ 8 ubuntu ubuntu 4096 Aug  8 00:56 ../
-rw------- 1 ubuntu ubuntu  887 Aug  8 00:53 client.req
ubuntu@ubuntu:~/ca/pki/reqs$ cat client.req 
-----BEGIN CERTIFICATE REQUEST-----
MIICVjCCAT4CAQAwETEPMA0GA1UEAwwGY2xpZW50MIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEArrfRrpTeCJQ65fyL72JVag95nESiOzGgcp0rntC/tUIg
ygBpDRqTt+R4t/25rzBBqHn5T3L/OTRwjqFvWgZceZ6OChIOczZw+lSXqcr+f4dH
7KtNSBgBDyhIaXnoXk8rjiQzJEL6o3qSTAY5r/g6YPhVuOs/AoTBTcRccEh4iRQT
VtmJH31yLLn8uJc4B4FeeqN+qKeVKxiOhc5I2qJ2BHp833eS3Ae9RjMJB9Sz3b+3
lCOli5APOD2lqzKSzCFvOCRKrDYMinKAx1zdv0uTZoV0DIQnf871zhiZS3ruAAYJ
Y/KBceR7AKmVmbi+p17U0dD2/yprtislwd8hOhD56QIDAQABoAAwDQYJKoZIhvcN
AQELBQADggEBAJ7KkBBW/eDp4gwTisi8jaK3bYLnegsGmKwVSjXjmbjISEQIaovP
2TdO/TH8qYOdWyMEhq8xtA9mddu4nj1i4wvg+Z9jx8gu3zkJhpHTasVKx7fZNcak
L3VoQ11u9n7hZ7DdXyL3WlGBZn0kc9n0qipEqmXvFqFV7LyZcpcQTrPiS7iOr3HT
hCB0PUBRaMMOW1EdQq61zsM6ZPTueYiaI9UjQAKN+KJjgsnidQr6nGZePVQmjSdI
ShQwUOiwV9Mn59n5re/kdLdDes3O60yk7tBYa6z/lWPK8hLZdTy5brQnBzF7lZ55
gRPLacTINnEb0HCyrrqn6igb8aBSxguNQDU=
-----END CERTIFICATE REQUEST-----
ubuntu@ubuntu:~/ca/pki/reqs$ rm client.req 
ubuntu@ubuntu:~/ca/pki/reqs$ cd ..
ubuntu@ubuntu:~/ca/pki$ cd issued/
ubuntu@ubuntu:~/ca/pki/issued$ ll
total 16
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:56 ./
drwx------ 8 ubuntu ubuntu 4096 Aug  8 00:56 ../
-rw------- 1 ubuntu ubuntu 4466 Aug  8 00:56 client.crt
ubuntu@ubuntu:~/ca/pki/issued$ ll
total 16
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:56 ./
drwx------ 8 ubuntu ubuntu 4096 Aug  8 00:56 ../
-rw------- 1 ubuntu ubuntu 4466 Aug  8 00:56 client.crt
ubuntu@ubuntu:~/ca/pki/issued$ cd 
ubuntu@ubuntu:~$ ll
total 52
drwxr-xr-x 7 ubuntu ubuntu 4096 Aug  8 00:49 ./
drwxr-xr-x 4 root   root   4096 Jun 14 18:15 ../
-rw------- 1 ubuntu ubuntu  246 Jun 14 18:16 .bash_history
-rw-r--r-- 1 ubuntu ubuntu  220 Feb 25  2020 .bash_logout
-rw-r--r-- 1 ubuntu ubuntu 3771 Feb 25  2020 .bashrc
drwx------ 2 ubuntu ubuntu 4096 Jun 10 08:27 .cache/
-rw-r--r-- 1 ubuntu ubuntu  807 Feb 25  2020 .profile
-rw------- 1 ubuntu ubuntu   14 Aug  7 15:53 .python_history
drwx------ 2 ubuntu ubuntu 4096 Apr  2  2020 .ssh/
-rw-r--r-- 1 ubuntu ubuntu    0 Jun 10 08:28 .sudo_as_admin_successful
-rw------- 1 ubuntu ubuntu 3854 Aug  8 00:43 .viminfo
drwx------ 3 ubuntu ubuntu 4096 Aug  8 00:55 ca/
drwx------ 3 ubuntu ubuntu 4096 Aug  7 21:24 ca2/
drwx------ 3 ubuntu ubuntu 4096 Aug  8 00:50 ca3/
ubuntu@ubuntu:~$ mkdir client
ubuntu@ubuntu:~$ cd ..
ubuntu@ubuntu:/home$ cd ~/c
-bash: cd: /home/ubuntu/c: No such file or directory
ubuntu@ubuntu:/home$ cd ~/ca
ubuntu@ubuntu:~/ca$ sudo cp pki/
.rnd                 index.txt.attr       private/             serial
ca.crt               index.txt.attr.old   renewed/             serial.old
certs_by_serial/     index.txt.old        reqs/                
extensions.temp      issued/              revoked/             
index.txt            openssl-easyrsa.cnf  safessl-easyrsa.cnf  
ubuntu@ubuntu:~/ca$ sudo cp pki/
.rnd                 index.txt.attr       private/             serial
ca.crt               index.txt.attr.old   renewed/             serial.old
certs_by_serial/     index.txt.old        reqs/                
extensions.temp      issued/              revoked/             
index.txt            openssl-easyrsa.cnf  safessl-easyrsa.cnf  
ubuntu@ubuntu:~/ca$ sudo cp pki/issued/client.crt ~/client/client.crt
ubuntu@ubuntu:~/ca$ cd pki
ubuntu@ubuntu:~/ca/pki$ ll
total 84
drwx------ 8 ubuntu ubuntu 4096 Aug  8 00:56 ./
drwx------ 3 ubuntu ubuntu 4096 Aug  8 00:55 ../
-rw------- 1 ubuntu ubuntu 1024 Aug  8 00:56 .rnd
-rw------- 1 ubuntu ubuntu 1184 Aug  8 00:54 ca.crt
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:56 certs_by_serial/
-rw------- 1 ubuntu ubuntu  492 Aug  8 00:56 extensions.temp
-rw------- 1 ubuntu ubuntu  138 Aug  8 00:56 index.txt
-rw------- 1 ubuntu ubuntu   20 Aug  8 00:56 index.txt.attr
-rw------- 1 ubuntu ubuntu   20 Aug  8 00:29 index.txt.attr.old
-rw------- 1 ubuntu ubuntu   69 Aug  8 00:29 index.txt.old
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:56 issued/
-rw------- 1 ubuntu ubuntu 4651 Aug  7 20:30 openssl-easyrsa.cnf
drwx------ 2 ubuntu ubuntu 4096 Aug  7 21:16 private/
drwx------ 5 ubuntu ubuntu 4096 Aug  7 20:31 renewed/
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:57 reqs/
drwx------ 5 ubuntu ubuntu 4096 Aug  7 20:31 revoked/
-rw------- 1 ubuntu ubuntu 4575 Aug  8 00:56 safessl-easyrsa.cnf
-rw------- 1 ubuntu ubuntu   33 Aug  8 00:56 serial
-rw------- 1 ubuntu ubuntu   33 Aug  8 00:56 serial.old
ubuntu@ubuntu:~/ca/pki$ cd private/
ubuntu@ubuntu:~/ca/pki/private$ ll
total 12
drwx------ 2 ubuntu ubuntu 4096 Aug  7 21:16 ./
drwx------ 8 ubuntu ubuntu 4096 Aug  8 00:56 ../
-rw------- 1 ubuntu ubuntu 1766 Aug  7 21:15 ca.key
ubuntu@ubuntu:~/ca/pki/private$ cd ~/ca3
ubuntu@ubuntu:~/ca3$ cd pki/private/
ubuntu@ubuntu:~/ca3/pki/private$ ll
total 12
drwx------ 2 ubuntu ubuntu 4096 Aug  8 00:50 ./
drwx------ 4 ubuntu ubuntu 4096 Aug  8 00:50 ../
-rw------- 1 ubuntu ubuntu 1704 Aug  8 00:50 client.key
ubuntu@ubuntu:~/ca3/pki/private$ cp client.key ~/client/
ubuntu@ubuntu:~/ca3/pki/private$ ll ~/client
total 20
drwxrwxr-x 2 ubuntu ubuntu 4096 Aug  8 00:59 ./
drwxr-xr-x 8 ubuntu ubuntu 4096 Aug  8 00:57 ../
-rw------- 1 root   root   4466 Aug  8 00:58 client.crt
-rw------- 1 ubuntu ubuntu 1704 Aug  8 00:59 client.key
ubuntu@ubuntu:~/ca3/pki/private$ cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client
ubuntu@ubuntu:~/ca3/pki/private$ cd ~/client
ubuntu@ubuntu:~/client$ ll
total 24
drwxrwxr-x 2 ubuntu ubuntu 4096 Aug  8 01:00 ./
drwxr-xr-x 8 ubuntu ubuntu 4096 Aug  8 00:57 ../
-rw-r--r-- 1 ubuntu ubuntu 3586 Aug  8 01:00 client.conf
-rw------- 1 root   root   4466 Aug  8 00:58 client.crt
-rw------- 1 ubuntu ubuntu 1704 Aug  8 00:59 client.key
ubuntu@ubuntu:~/client$ sudo vim client.conf
ubuntu@ubuntu:~/client$ sudo vim client.conf
ubuntu@ubuntu:~/client$ ll
total 24
drwxrwxr-x 2 ubuntu ubuntu 4096 Aug  8 01:03 ./
drwxr-xr-x 8 ubuntu ubuntu 4096 Aug  8 00:57 ../
-rw-r--r-- 1 ubuntu ubuntu 3672 Aug  8 01:03 client.conf
-rw------- 1 root   root   4466 Aug  8 00:58 client.crt
-rw------- 1 ubuntu ubuntu 1704 Aug  8 00:59 client.key
ubuntu@ubuntu:~/client$ cat client.crt
cat: client.crt: Permission denied
ubuntu@ubuntu:~/client$ sudo chown ubuntu:ubuntu client.crt
ubuntu@ubuntu:~/client$ cat client.crt
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            1d:ac:90:ee:b8:69:e4:76:da:15:e4:c7:ba:82:94:3c
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=justin
        Validity
            Not Before: Aug  7 16:56:19 2021 GMT
            Not After : Jul 22 16:56:19 2024 GMT
        Subject: CN=client
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:ae:b7:d1:ae:94:de:08:94:3a:e5:fc:8b:ef:62:
                    55:6a:0f:79:9c:44:a2:3b:31:a0:72:9d:2b:9e:d0:
                    bf:b5:42:20:ca:00:69:0d:1a:93:b7:e4:78:b7:fd:
                    b9:af:30:41:a8:79:f9:4f:72:ff:39:34:70:8e:a1:
                    6f:5a:06:5c:79:9e:8e:0a:12:0e:73:36:70:fa:54:
                    97:a9:ca:fe:7f:87:47:ec:ab:4d:48:18:01:0f:28:
                    48:69:79:e8:5e:4f:2b:8e:24:33:24:42:fa:a3:7a:
                    92:4c:06:39:af:f8:3a:60:f8:55:b8:eb:3f:02:84:
                    c1:4d:c4:5c:70:48:78:89:14:13:56:d9:89:1f:7d:
                    72:2c:b9:fc:b8:97:38:07:81:5e:7a:a3:7e:a8:a7:
                    95:2b:18:8e:85:ce:48:da:a2:76:04:7a:7c:df:77:
                    92:dc:07:bd:46:33:09:07:d4:b3:dd:bf:b7:94:23:
                    a5:8b:90:0f:38:3d:a5:ab:32:92:cc:21:6f:38:24:
                    4a:ac:36:0c:8a:72:80:c7:5c:dd:bf:4b:93:66:85:
                    74:0c:84:27:7f:ce:f5:ce:18:99:4b:7a:ee:00:06:
                    09:63:f2:81:71:e4:7b:00:a9:95:99:b8:be:a7:5e:
                    d4:d1:d0:f6:ff:2a:6b:b6:2b:25:c1:df:21:3a:10:
                    f9:e9
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            X509v3 Subject Key Identifier: 
                8B:FE:27:86:8F:C0:0F:12:AC:52:AE:18:65:EE:1A:DF:D0:6B:F2:E5
            X509v3 Authority Key Identifier: 
                keyid:E0:E6:9A:46:51:D4:EF:A9:47:F5:6B:22:65:11:F2:EB:EB:9B:27:2F
                DirName:/CN=justin
                serial:68:EE:68:FE:EF:93:A2:EE:07:4F:A3:03:07:A2:6B:64:0B:70:87:2D
            X509v3 Extended Key Usage: 
                TLS Web Client Authentication
            X509v3 Key Usage: 
                Digital Signature
    Signature Algorithm: sha256WithRSAEncryption
         50:97:bf:81:f0:7c:7b:5c:ef:c8:5b:e5:49:ca:87:a8:57:f5:
         87:b8:56:df:8a:e6:a5:f1:a4:e2:19:c5:f8:37:10:c9:be:a8:
         71:ac:23:94:73:6a:2d:de:9b:3b:40:b0:4c:1f:56:5c:7a:5f:
         e3:be:82:ec:be:73:10:57:40:37:e7:d7:87:e7:1a:28:f5:1b:
         48:1c:5c:ae:0e:2d:72:cc:43:e3:d6:2d:9f:1b:a1:5c:df:6c:
         d2:ed:5a:29:13:05:0d:2a:f1:06:e5:17:7e:85:5c:8a:0c:51:
         c0:dd:c1:1b:3f:6e:3d:c8:11:78:46:ce:5e:cf:24:35:8b:20:
         7f:21:26:70:8e:e2:7d:fb:37:11:f9:bf:f0:59:69:a0:42:46:
         0a:03:cb:96:57:48:45:9b:67:83:3e:9c:3d:6a:eb:80:f9:31:
         a1:89:71:11:c0:23:fe:96:bc:84:06:ac:e7:c6:6e:b6:b1:7d:
         fe:15:d0:08:30:06:70:59:a9:f0:20:32:4c:23:c4:2b:2f:a2:
         41:11:72:65:d5:98:8b:4d:b6:d7:0f:55:64:43:38:d3:c8:9f:
         a6:0e:66:f1:6e:76:6a:9d:d3:36:20:19:fc:2f:ea:be:f8:d8:
         d4:8d:50:9b:f0:87:f5:ad:98:e9:db:1a:1a:ec:13:ba:8d:28:
         aa:6c:6a:37
-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQHayQ7rhp5HbaFeTHuoKUPDANBgkqhkiG9w0BAQsFADAR
MQ8wDQYDVQQDDAZqdXN0aW4wHhcNMjEwODA3MTY1NjE5WhcNMjQwNzIyMTY1NjE5
WjARMQ8wDQYDVQQDDAZjbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQCut9GulN4IlDrl/IvvYlVqD3mcRKI7MaBynSue0L+1QiDKAGkNGpO35Hi3
/bmvMEGoeflPcv85NHCOoW9aBlx5no4KEg5zNnD6VJepyv5/h0fsq01IGAEPKEhp
eeheTyuOJDMkQvqjepJMBjmv+Dpg+FW46z8ChMFNxFxwSHiJFBNW2YkffXIsufy4
lzgHgV56o36op5UrGI6FzkjaonYEenzfd5LcB71GMwkH1LPdv7eUI6WLkA84PaWr
MpLMIW84JEqsNgyKcoDHXN2/S5NmhXQMhCd/zvXOGJlLeu4ABglj8oFx5HsAqZWZ
uL6nXtTR0Pb/Kmu2KyXB3yE6EPnpAgMBAAGjgZ0wgZowCQYDVR0TBAIwADAdBgNV
HQ4EFgQUi/4nho/ADxKsUq4YZe4a39Br8uUwTAYDVR0jBEUwQ4AU4OaaRlHU76lH
9WsiZRHy6+ubJy+hFaQTMBExDzANBgNVBAMMBmp1c3RpboIUaO5o/u+Tou4HT6MD
B6JrZAtwhy0wEwYDVR0lBAwwCgYIKwYBBQUHAwIwCwYDVR0PBAQDAgeAMA0GCSqG
SIb3DQEBCwUAA4IBAQBQl7+B8Hx7XO/IW+VJyoeoV/WHuFbfiual8aTiGcX4NxDJ
vqhxrCOUc2ot3ps7QLBMH1Zcel/jvoLsvnMQV0A359eH5xoo9RtIHFyuDi1yzEPj
1i2fG6Fc32zS7VopEwUNKvEG5Rd+hVyKDFHA3cEbP249yBF4Rs5ezyQ1iyB/ISZw
juJ9+zcR+b/wWWmgQkYKA8uWV0hFm2eDPpw9auuA+TGhiXERwCP+lryEBqznxm62
sX3+FdAIMAZwWanwIDJMI8QrL6JBEXJl1ZiLTbbXD1VkQzjTyJ+mDmbxbnZqndM2
IBn8L+q++NjUjVCb8If1rZjp2xoa7BO6jSiqbGo3
-----END CERTIFICATE-----
ubuntu@ubuntu:~/client$ sudo vim client.conf
ubuntu@ubuntu:~/client$ ll
total 28
drwxrwxr-x 2 ubuntu ubuntu 4096 Aug  8 01:05 ./
drwxr-xr-x 8 ubuntu ubuntu 4096 Aug  8 00:57 ../
-rw-r--r-- 1 ubuntu ubuntu 8138 Aug  8 01:05 client.conf
-rw------- 1 ubuntu ubuntu 4466 Aug  8 00:58 client.crt
-rw------- 1 ubuntu ubuntu 1704 Aug  8 00:59 client.key
ubuntu@ubuntu:~/client$ cat client.key
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCut9GulN4IlDrl
/IvvYlVqD3mcRKI7MaBynSue0L+1QiDKAGkNGpO35Hi3/bmvMEGoeflPcv85NHCO
oW9aBlx5no4KEg5zNnD6VJepyv5/h0fsq01IGAEPKEhpeeheTyuOJDMkQvqjepJM
Bjmv+Dpg+FW46z8ChMFNxFxwSHiJFBNW2YkffXIsufy4lzgHgV56o36op5UrGI6F
zkjaonYEenzfd5LcB71GMwkH1LPdv7eUI6WLkA84PaWrMpLMIW84JEqsNgyKcoDH
XN2/S5NmhXQMhCd/zvXOGJlLeu4ABglj8oFx5HsAqZWZuL6nXtTR0Pb/Kmu2KyXB
3yE6EPnpAgMBAAECggEAasbESqGIIE4WwL9a9e1urebPN4VqcCqgF+ud4O1KfAfx
6gHeMbfwVw42CJvzgvFG7yO8DaYF/Hvj3gci+i2xDlKsE9N9KUQ4P4S7O3Vnm6Cd
gDIghNLGsvC3cF6keB6CS9gruRmF+6rJBdU4JCbb5q9eFCkQ1QU07cX3iFeB8qNj
fgKWyQ68QZqC+Bflndnsc8aETB16SGAu5BkT6Rks1YQEvFT5cWI2AlD0DLaMMJle
Whpf2d8hinW2e9RAPVces7+KMLc6ngf5pXFiil03KN0LwCjrRI9FZr74v0arP9de
pWekgRPAaD3wKrwY0rPtuoA1OlRr+pNC+O4zjMF9QQKBgQDc/VNJOwWzADr/iOt/
5GGQrYhsG4TIoYFYHgGXveTfA6gz8GOwqgpO/DE0cxIMdI1qg7/E/sNHzKPavg4t
SPkpWfwSSlDs0Qb0cc93wsSQxP5PH1usLsPBafyOnbSTrqtcFfsK70G7FQ8CseG4
2IDixMZw9TlHtbDy49WJuO11TQKBgQDKZdwfjYFnEY56kxTj2F61gH0e25A8Jm1Q
M1Y3JRgO63Exib7jaEvFcVxsg4MDM3iDme9HvGLcEW55/2epiQqxIKrhLCuQitix
220VBKI0HWxSHugiQhIr/gThp8U2M5PnsbAelOOGwMpA1P7byLNZOQ4AnYC1dSSx
jKalNwOZDQKBgEznn89RSfd0MhPxezsjqExoB5zPqtMDWXbn4lgDTp3JsQR6OMcn
NbUtEJaXIQXSndAej2Mn4Z+f+LnMADUEOymH1jArSqRPTeNNpAyibDORSosQd5+h
GqC5mJmtCkWGuL2wLJAumSpY9sNSUiI4vgmsvv5aaJerBCxS22I1R/XVAoGADnf7
pXHLN2AE7HRJQQR9uMHnr+YISJSCqgIRfr2zG5XvMJhlQgJ5sDKrZcJ9AiSSz+2Y
MmugMZU5bZU5huAaGJF6RcCPmLSkSwqhoKgFJG6aCMDW3WQVwnlVRgBlU7uaLi0A
px8DqOVtT/cqBPIzCATRIHAh/FbUebDRVOw64J0CgYEA2+NbvnUi//Ooylnlt5C1
vnYuPR3MV6KMsQFjsn+aMZNGZPtGS3VGEICTDPAj4r78403zz8nyA43xL1iD4qxJ
Zj1F9PSRvpRnPHE7FD0WwMg88jNT0B71NLx6qBNGQMjoHPey6AsIVBrxI6UOtcOv
DqUq8Kph2SAayujtoimjJX8=
-----END PRIVATE KEY-----
ubuntu@ubuntu:~/client$ sudo vim client.conf
ubuntu@ubuntu:~/client$ sudo vim client.conf
ubuntu@ubuntu:~/client$ sudo cat /etc/openvpn/
ca.crt              server/             server.key          
client/             server.conf         ta.key              
dh2048.pem          server.crt          update-resolv-conf  
ubuntu@ubuntu:~/client$ sudo cat /etc/openvpn/ta.key
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
f502828b60e55511e371346247fb1ad1
a07f329e4f972389f92057271114a3b5
ed6bce0bb8b849678baaa08568621e08
57073a4ebb04d965c8d5a2868c2faad7
46468fa3235b48a60df39c3951780e84
7628aa974f27bb4d159b6f66732a4de9
e21ac7c4cd270efaec66a594e613fb09
29b68d60144a60567cf7b01bcde3d52d
01e0ebe43d2d50dda188d1cd5535cea5
f6b08453bca7f641a4fd7aa5fdf17a82
8a351ac17c47a343b0ee18aa5cc452a5
65883c67eeb24bc3d2f2d5b893ff19cf
436c24af0f069d611115fe6c545c861e
982f43d29ce2e723d87542b41debb143
8c0a0e328ce603debed8ac61e7231529
3ea47d74dd2f00438440b049dbfa6db5
-----END OpenVPN Static key V1-----
ubuntu@ubuntu:~/client$ sudo vim client.conf
ubuntu@ubuntu:~/client$ sudo cat /etc/openvpn/ca.crt
-----BEGIN CERTIFICATE-----
MIIDPDCCAiSgAwIBAgIUaO5o/u+Tou4HT6MDB6JrZAtwhy0wDQYJKoZIhvcNAQEL
BQAwETEPMA0GA1UEAwwGanVzdGluMB4XDTIxMDgwNzEzMTYxMloXDTMxMDgwNTEz
MTYxMlowETEPMA0GA1UEAwwGanVzdGluMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEArGCH8mgpTPgcNYp1blgAkHar1cNk6Plv1FxSHGq2WlxUmTQfFCYj
jfYLZ+mQILQ6Kis2N9mjG90i6WAvZMNTDjPnUz+3Wg6OKVEeCiChukcU+CCvL7rR
cSMAZj+Bwsa4SOPSwSe7npEQ/BixFkKsfgW0ne8q6x6aeA95w/Yxl3pxMr57UDcv
HIlWS7oRweFUCphKs/d2vfYpvG81GIVKK71uJk6phPg1uC35CmkhLUT7GEfyvdDy
Sf7t36FyMrWGk8VtbY31mfJ69zHfISYDoMrkeZZVaG3olijKQsDu9mPiJC2qshQD
+VfqrhHHsOqzKoQE04ORUC3iFPjZxDQYcQIDAQABo4GLMIGIMB0GA1UdDgQWBBTg
5ppGUdTvqUf1ayJlEfLr65snLzBMBgNVHSMERTBDgBTg5ppGUdTvqUf1ayJlEfLr
65snL6EVpBMwETEPMA0GA1UEAwwGanVzdGlughRo7mj+75Oi7gdPowMHomtkC3CH
LTAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA
Du2+5pFZ/0z6RSJvX0L/uTiMwMsEghxQIox6F3bBdRNyguKjlFJgVcXy1TmaasT1
0H6eSPa8vUxMcDuEtc/n5CmIW0uwcTmRRQBA4U+KaqqYxTYo7qk0O/nB3LANPmtw
pg5X1H5bJXu4o0GCrd4JoJG3lPctb7/AGIlKFOlNuOpPrrNOcVMFqm3vVxQhQPeV
dWPjEKSTxZ2v/w8v21oDzTXisF2Yhcx6xSA4mtYY42zCcx0D8Y8gAMWDxCYdktBx
xDwuk4BxmTzc9chydsmnAfMV/rZ8cWHYdjNdiK6sozZTyf1lq0xysLLfay/hjMsR
HTkOdQ856kjonjhS8amzfA==
-----END CERTIFICATE-----
ubuntu@ubuntu:~/client$ sudo vim client.conf
ubuntu@ubuntu:~/client$ mv client.conf client.ovpn
ubuntu@ubuntu:~/client$ exit
kb/internet/connectivity/openvpn.txt · Last modified: 16 months ago ( 4 July 2024) by justin
                
                