#!/bin/sh # Copyright - negotiable # # VERBATUM_COPYRIGHT_HEADER_INCLUDE_NEGOTIABLE # Easy-TLS -- A Shell-based Easy-RSA extension utility to help manage # * OpenVPN specific TLS keys # * Easy-RSA based x509 security credentials # * Verified 'inline' combined OpenVPN node packages # # Copyright (C) 2020 Richard Bonhomme (Friday 13th of March 2020) # https://github.com/TinCanTech/easy-tls # tincantech@protonmail.com # All Rights reserved. # # This code is released under version 2 of the GNU GPL # See LICENSE of this project for full licensing details. # # Acknowledgement: # This utility is "written in the style of" and "borrows heavily from" Easy-RSA # # Easy-TLS is inspired by syzzer # See: https://github.com/OpenVPN/openvpn/blob/master/doc/tls-crypt-v2.txt # # VERBATUM_COPYRIGHT_HEADER_INCLUDE_NEGOTIABLE # # Easy-TLS requirements: # + Easy-RSA Version 3.0.8 # + OpenVPN Version 2.5 # Set the Easy-TLS version easytls_version () { unset -v EASYTLS_VERBOSE config_use || : print "Easy-TLS ${EASYTLS_VERSION} (${EASYTLS_STATUS})" } # => easytls_version () ############################################################################ # # EASYTLS HELP Section # # Help/usage output to stdout usage() { print " Easy-TLS usage and overview USAGE: easytls [options] COMMAND [command-options] A list of commands is shown below. To get detailed usage and help for a command, use: ./easytls help COMMAND For a listing of options that can be supplied before the command, use: ./easytls help options For a list of abbreviated command names, use: ./easytls help abb For a list of configurable options, use: ./easytls help config Here is the list of commands available with a short syntax reminder. Use the 'help' command above to get full usage details. build :Inter-active menu to build TLS keys inline :Inter-active menu to build Inline files remove :Inter-active menu to remove TLS keys and Inline files script :Inter-active menu to configure Server scripts selfsign :Inter-active menu to build and inline self-signed certificates init | init-tls no-ca cf | config | sss | self-sign-server (No-CA mode only) ssc | self-sign-client (No-CA mode only) | bta | build-tls-auth btc | build-tls-crypt bc2s | build-tls-crypt-v2-server bc2c | build-tls-crypt-v2-client | | ita | inline-tls-auth [ cmd-opts ] itc | inline-tls-crypt [ cmd-opts ] ic2 | inline-tls-crypt-v2 [ cmd-opts ] | bc2gc | build-tls-crypt-v2-group-client | ic2gc | inline-tls-crypt-v2-group-client | [ cmd-opts ] | s | status [ cmd-opts ] rk | remove-tlskey rgk | remove-group-tlskey ri | remove-inline rgi | remove-group-inline is | inline-show | inline-index-rebuild ix | inline-expire cx | cert-expire | d | disable (Or display the current disabled list) e | enable (Or display the current disabled list) | disabled-list-rehash sid | save-id ver | version | upgrade Easy-TLS also has a useful Howto and wiki with expanded help and examples: * https://github.com/TinCanTech/easy-tls/blob/master/easytls-howto-ii.md * https://github.com/TinCanTech/easy-tls/wiki" # 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}" tls_dir="${EASYTLS_PKI:-$err_source}" print " DIRECTORY STATUS (commands would take effect on these locations) EASYTLS: ${work_dir} PKI: ${pki_dir} TLS: ${tls_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|init-tls) text=" init-tls no-ca Removes & re-initializes the TLS-key directory. * Easy-RSA is also required to be initialised. - Specify a hash algorithm. Default SHA256 - Alternative SHA1 nc|noca|no-ca - Use Easy-TLS without an Easy-RSA CA Certificate Authority. * Use 'no-ca' to build self-signed certificates and fingerprints. If you have upgraded an old copy of Easy-TLS to the latest version then it may be possible to use 'easytls upgrade' or 'easytls rehash' to establish a functioning easytls data directory." ;; build|inline|remove|script|selfsign) text=" Inter-active menus to build, inline, remove and configure various Easy-TLS files" ;; bta|build-tls-auth) text=" build-tls-auth Create an OpenVPN TLS auth PSK (tls-auth.key)" ;; btc|build-tls-crypt) text=" build-tls-crypt Create an OpenVPN TLS crypt PSK (tls-crypt.key)" ;; btc2s|btv2s|btcv2s|build-tls-crypt-v2-server) text=" build-tls-crypt-v2-server Create an OpenVPN TLS crypt V2 Server key" ;; btc2c|btv2c|btcv2c|build-tls-crypt-v2-client) EASYTLS_github="https://github.com/TinCanTech/easy-tls/wiki" EASYTLS_url="15-=-Multiple-TLS-Crypt-V2-Keys-per-X509-Certificate" text=" build-tls-crypt-v2-client Create an OpenVPN TLS crypt V2 Client key The metadata can also be used to specify Hardware Addresses which this key is allowed to be used from. Use easytls-cryptv2-client-connect.sh to verify the HW-ADDR. Note: ALL scripts are required to successfully verify Hardware. Each X509 Client can have multiple TLS-Crypt-V2 keys by using option: -k|--subkey-name= This allows an unlimited number of keys, see the following wiki article for further details: ${EASYTLS_github}/${EASYTLS_url}" ;; bc2gs|btc2gs|btv2gs|btcv2gs|build-tls-crypt-v2-group-server) text=" build-tls-crypt-v2-group-server The Server Group name is simply a name for the key file." ;; bc2gc|btc2gc|btv2gc|btcv2gc|build-tls-crypt-v2-group-client) text=" build-tls-crypt-v2-group-client The Client Group name is simply a name for the key file." ;; rt|rtk|remove-tlskey) text=" remove-tlskey Remove a TLS-Crypt-V2 Client key and update the tlskey-index." ;; rgt|rgk|rgtk|remove-group-tlskey) text=" remove-group-tlskey Remove a TLS-Crypt-V2 GROUP Client key and update the tlskey-index." ;; sid|save-id) text=" save-id [ no options ] Save the CA-Identity to easytls/easytls-ca-identity.txt CA-Identity is the Hex ONLY value of the CA finger print. This can then by used by easytls-cryptv2-verify.sh as a time-saver by not needing to load OpenSSL to generate the CA fingerprint. Combining this with 'easytls-cryptv2-verify.sh --verify-via-index', OpenSSL binary never needs to be loaded by easytls-cryptv2-verify.sh See EasyTLS Howto for an example." ;; s|status) text=" status [ cmd-opts ] Compare Easy-RSA certificate(s) to Easy-TLS inline(s) status" opts=" val|valid - List only Easy-RSA valid certificates rev|revoked - List only Easy-RSA revoked certificates inl|inline - List only Easy-TLS inline files inv|invalid - List only Easy-TLS invalid inline files ren|renewed - List only Easy-RSA renewed certificates tls|tlskeys - List only Easy-TLS known TLS keys" ;; ita|inline-tls-auth) text=" inline-tls-auth [ cmd-opts ] Create a complete OpenVPN node package from Easy-RSA and Easy-TLS files for VPN node using the Easy-TLS TLS auth file '0' or '1' (key-direction is mandatory)" opts=" no-key - do not require an x509 key (default: key is required) add-dh - inline Diffie-Hellman parameters file (Server only) Default file is easyrsa3/pki/dh.pem To specify an alternative file use the --dh option" ;; itc|inline-tls-crypt) text=" inline-tls-crypt [ cmd-opts ] Create a complete OpenVPN node package from Easy-RSA and Easy-TLS files for VPN node using the Easy-TLS TLS crypt file" opts=" no-key - do not require an x509 key (default: key is required) add-dh - inline Diffie-Hellman parameters file (Server only) Default file is easyrsa3/pki/dh.pem To specify an alternative file use the --dh option" ;; itc2|itv2|itcv2|inline-tls-crypt-v2) text=" inline-tls-crypt-v2 [ cmd-opts ] Create a complete OpenVPN node package from Easy-RSA and Easy-TLS files for VPN node using the Easy-TLS TLS crypt v2 file" opts=" no-key - do not require an x509 key (default: key is required) add-dh - inline Diffie-Hellman parameters file (Server only) Default file is easyrsa3/pki/dh.pem To specify an alternative file use the --dh option no-md - Do not add public metadata details to inline file add-hw - Include hardware address in metadata details" ;; ic2gc|itv2gc|itcv2gc|inline-tls-crypt-v2-group-client) text=" inline-tls-crypt-v2-group-client [ cmd-opts ] Create a complete OpenVPN node package from Easy-RSA and Easy-TLS files for VPN node using the Easy-TLS GROUP key file" opts=" no-key - do not require an x509 key (default: key is required) add-dh - inline Diffie-Hellman parameters file (Server only) Default file is easyrsa3/pki/dh.pem To specify an alternative file use the --dh option no-md - Do not add public metadata details to inline file add-hw - Include hardware address in metadata details" ;; ri|ril|remove-inline) text=" remove-inline Delete .inline and update the inline-index When an Easy-RSA certificate is revoked then the inline file is invalid" ;; rgi|rgil|remove-group-inline) text=" remove-group-inline Delete -.inline and update the inline-index" ;; is|inline-show) text=" inline-show Copy .inline to stdout" ;; inline-index-rebuild) text=" inline-index-rebuild Rebuild easytls-index.txt If you need to do this then you may have found a bug, please raise an issue https://github.com/TinCanTech/easy-tls/issues" ;; ix|inline-expire) text=" inline-expire Display inline expiry Date for " opts=" If no is given then list all inline expiry Dates" ;; cx|cert-expire) text=" cert-expire | Display certificate expiry Date for " opts=" If is 'ca' then show ca.crt expiry If no is given then list all certificate expiry Dates" ;; d|disable) text=" d|disable Add serial number for to the disabled list for immediate use by the easytls-cryptv2-verify.sh script. This also supports --sub-key-name for clients with multiple keys. If no is given then show the disabled-list." ;; e|enable) text=" e|enable Remove serial number for from the disabled list for immediate use by the easytls-cryptv2-verify.sh script. This also supports --sub-key-name for clients with multiple keys. If no is given then show the disabled-list." ;; rehash) text=" rehash Rehash the master-hash if the current hash is corrupted. These test commands also exist: gmh|generate-master-hash - Generate your current Master Hash. vmh|verify-master-hash - Verify your current Master Hash. smh|save-master-hash - Save your current Master Hash." ;; sss|self-sign-server) text=" self-sign-server Build a self signed server certificate and key. Also see 'help options' for: -r|--ss-peer-fingerprint=" ;; ssc|self-sign-client) text=" self-sign-client Build a self signed client certificate and key. Also see 'help options' for: -r|--ss-peer-fingerprint=" ;; upgrade) text=" upgrade To upgrade from an older version of Easy-TLS which did not create the required folders and files. Very limited usage." ;; options) opt_usage ;; abb) opt_abbreviations ;; cf|cfg|config) opt_config ;; ver|version) text=" Show version information." ;; "") usage ;; *) text=" Unknown command: '${1}' (try without commands for a list of commands)" ;; esac # display the help text [ -z "${text}" ] || print "${text}" [ -z "${opts}" ] || print " cmd-opts is an optional set of command options from this list: ${opts}" easytls_verbose } # => cmd_help() # Options usage opt_usage() { print " Easy-TLS 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: -V Version --batch Set automatic (no-prompts when possible) mode. -v|--verbose Verbose output. -s|--silent Silence all message output except prompts. -p|--pki-dir= Declare the EasyRSA PKI directory. --vars='FILE' Define a specific 'vars' file to use for Easy-RSA config. --dh='FILE' Define an alternate Diffie-Hellman parameters file. -n|--no-auto-check For performance you can disable auto-check. -y|--why-disable-file-hash To temporarily disable file hash verification. -g|--custom-group= is an optional single word which will be used in .inline files and TLS-Crypt-V2 client key metadata to identify the group to which this TLS-Crypt-V2 client key belongs. Once set and used, the must not be changed. The is also matched in easytls-cryptv2-verify.sh by using the command line switch --c|custom-group=XYZ -k|--subkey|--sub-key-name= This allows for one single X509 client certificate to have multiple TLS-Crypt-V2 client keys associated with it. For example, the same X509 certificate can be used from different locations with unique TLS-Crypt-V2 client keys. -a|--ss-age= Self-signed certificate age. (Default: 3650 days) -w|--ss-password Prompt for a password to encrypt a self-signed key. -c|--ss-eccurve= Specify an alternate Elliptic Curve for a self-signed key. (Default: secp384r1) -r|--ss-peer-fingerprint= When inlining a self-signed client certificate, specify the commonName of the server certificate to share fingerprints of each node. The fingerprint of the server will be added to the client inline file and the fingerprint of the client will be added to the server inline file. -i|--inline When building a TLS Crypt V2 key, also build the Inline file. (Fix: This only accepts default options for inline-tls-crypt-v2) -t|--tmp-dir= Temp directory where server-scripts write data. Default: *nix /tmp/easytls Windows C:/Windows/Temp/easytls -b|--base-dir= Path to OpenVPN base directory. (Windows Only) Default: C:/Progra~1/OpenVPN -o|--ovpnbin-dir= Path to OpenVPN bin directory. (Windows Only) Default: C:/Progra~1/OpenVPN/bin -e|--ersabin-dir= Path to Easy-RSA3 bin directory. (Windows Only) Default: C:/Progra~1/Openvpn/easy-rsa/bin " } # => opt_usage() # Option abbreviations opt_abbreviations () { print " Easy-TLS abbreviations: config - cf | cfg init-tls - init build-tls-auth - bta build-tls-crypt - btc build-tls-crypt-v2-server - bc2s | btc2s | btv2s | btcv2s build-tls-crypt-v2-client - bc2c | btc2c | btv2c | btcv2c build-tls-crypt-v2-group-server - bc2gs | btc2gs | btcv2gs build-tls-crypt-v2-group-client - bc2gc | btc2gc | btcv2gc remove-tlskey - rt | rk | rtk save-id - sid status - s Easy-RSA valid certificates - val | valid Easy-RSA revoked certificates - rev | revoked Easy-TLS inline files - inl | inline Easy-TLS invalid inline files - inv | invalid Easy-RSA renewed certificates - ren | renewed Easy-TLS known TLS keys - tls | tlskeys inline-tls-auth - ita inline-tls-crypt - itc inline-tls-crypt-v2 - ic2 | itc2 | itv2 | itcv2 inline-tls-crypt-v2-group-client - ic2gc | itc2gc | itcv2gc remove-inline - ri | ril remove-group-inline - rgi | rgil inline-show - is inline-expire - ix cert-expire - cx disable - d enable - e rehash - No abbreviation self-sign-server - sss self-sign-client - ssc " } # => opt_abbreviations () # Option config opt_config () { print " Easy-TLS configurable options (Abbreviation|full option): cg|custom.group NAME Save the Custom Group NAME - NAME must be a single contiguous word. This group can be changed. Using easytls-cryptv2-verify.sh in your openvpn server, you can configure multiple group names to match. eg. 'Home Office Remote' td|tmp-dir Set server scripts temporary directory ac|auto.check on|off Always run auto-check Toggle auto.check on|off. co|custom.openvpn '/full/path/to/openvpn(.exe)' Save your custom openvpn binary location. EG: /usr/local/bin/openvpn Quotes are not required. EG: 'C:/Program Files/OpenVPN/mybin/openvpn.exe' Quotes are required for spaces. Back-slash is not support, use Forward-slash '/' ONLY. im|inline.metadata on|off Add metadata to inline file Toggle inline-file metadata on|off. ih|inline.hardware on|off Include metadata hardware-addresses in metadata for inline file Toggle inline-file hardware-address metadata on|off. addition (No short form) Add arbitrary item to config This only adds the