From: John Runyon Date: Mon, 23 Oct 2023 16:30:06 +0000 (-0600) Subject: init X-Git-Url: https://jfr.im/git/vpn-prov.git/commitdiff_plain/ac397a3900b6d85f0825f72cb32549822b7db714 init --- ac397a3900b6d85f0825f72cb32549822b7db714 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..edd16ac --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +easy-rsa/vars +easy-rsa/keys +config.php +ta.key +base.ovpn diff --git a/README.md b/README.md new file mode 100644 index 0000000..ec43625 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +## Provisioning PHP deployment +1. `cp config.php.example config.php` && `vim config.php` +1. `vim base.ovpn` and adjust to tastes +1. Copy `ta.key` from OpenVPN server into root folder. +1. `cd easy-rsa` +1. `cp vars.example vars` && `vim vars` + Set KEY_COUNTRY, KEY_PROVINCE, KEY_CITY, KEY_ORG, KEY_EMAIL to sane values +1. `mkdir keys && sudo chown keys` +1. Access /init.php to create the necessary files. + (This script is idempotent and won't re-do anything, so you can leave it in place afterwards) +1. `./build-ca` +1. `./build-key ` to test +1. `./build-key-server ` to create server keys + +To start fresh: `rm -rf easy-rsa/keys` + +Note: the instance of PHP which is running this tool, +should be running under a dedicated user account. +This ensures the security of the keys. + +Production instances should be used like an Apache Alias, i.e. `Alias /vpn-prov/ /var/www/vpn-prov/www/` + +## GPO Deployment +Edit install-openvpn.bat to adjust URLs to suit, create scheduled task in GPO to run it from a share. +Optionally create services in GPO to ensure the service is started even if user disabled it. diff --git a/base.ovpn.example b/base.ovpn.example new file mode 100644 index 0000000..711c5dd --- /dev/null +++ b/base.ovpn.example @@ -0,0 +1,20 @@ +client +dev tun0 +proto udp +remote example.com 13337 +comp-lzo +resolv-retry 30 +nobind +persist-key + +remote-cert-tls server + +log openvpn.log +verb 4 + +cipher AES-256-CBC +auth SHA512 + +script-security 2 + +key-direction 1 diff --git a/common.php b/common.php new file mode 100644 index 0000000..a767ea9 --- /dev/null +++ b/common.php @@ -0,0 +1,27 @@ += $val) { + global $ldap; + var_dump($s); + echo ldap_errno($ldap); + echo ldap_error($ldap); + ldap_get_option($ldap, LDAP_OPT_DIAGNOSTIC_MESSAGE, $val); + echo $val; + } + return $s; +} + +debug($ldap = ldap_connect(LDAP_URL)); +ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0); +ldap_set_option($ldap, LDAP_OPT_DEREF, LDAP_DEREF_SEARCHING); +ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3); +ldap_set_option($ldap, LDAP_OPT_TIMELIMIT, 25); +ldap_set_option($ldap, LDAP_OPT_NETWORK_TIMEOUT, 25); +debug(ldap_bind($ldap, LDAP_USER, LDAP_PASS)); + +define('VERSION', exec('git describe --long --all --dirty')); diff --git a/config.php.example b/config.php.example new file mode 100644 index 0000000..032109f --- /dev/null +++ b/config.php.example @@ -0,0 +1,5 @@ + " >&2 + exit 1 +fi + +cd "$(dirname "$(readlink -f "$0")")" +source ./easy-rsa/vars >&2 +KEY_OU="$1" KEY_CN="$2" ./easy-rsa/build-key >&2 + +cat < +$(cat ta.key) + + + +$(cat easy-rsa/keys/ca.crt) + + + +$(cat easy-rsa/keys/"$2".crt) + + + +$(cat easy-rsa/keys/"$2".key) + + +EOF + +if [ -f easy-rsa/keys/crl.pem ]; then + echo -ne "\n$(cat easy-rsa/keys/crl.pem)\n\n" +fi diff --git a/easy-rsa/README b/easy-rsa/README new file mode 100644 index 0000000..a48b1a3 --- /dev/null +++ b/easy-rsa/README @@ -0,0 +1 @@ +https://github.com/OpenVPN/easy-rsa/tree/v2.2.1/easy-rsa/2.0 diff --git a/easy-rsa/build-ca b/easy-rsa/build-ca new file mode 100755 index 0000000..520c4d3 --- /dev/null +++ b/easy-rsa/build-ca @@ -0,0 +1,8 @@ +#!/bin/sh + +# +# Build a root certificate +# + +export EASY_RSA="${EASY_RSA:-.}" +"$EASY_RSA/pkitool" --initca $* diff --git a/easy-rsa/build-dh b/easy-rsa/build-dh new file mode 100755 index 0000000..4beb127 --- /dev/null +++ b/easy-rsa/build-dh @@ -0,0 +1,11 @@ +#!/bin/sh + +# Build Diffie-Hellman parameters for the server side +# of an SSL/TLS connection. + +if [ -d $KEY_DIR ] && [ $KEY_SIZE ]; then + $OPENSSL dhparam -out ${KEY_DIR}/dh${KEY_SIZE}.pem ${KEY_SIZE} +else + echo 'Please source the vars script first (i.e. "source ./vars")' + echo 'Make sure you have edited it to reflect your configuration.' +fi diff --git a/easy-rsa/build-inter b/easy-rsa/build-inter new file mode 100755 index 0000000..0f299c3 --- /dev/null +++ b/easy-rsa/build-inter @@ -0,0 +1,7 @@ +#!/bin/sh + +# Make an intermediate CA certificate/private key pair using a locally generated +# root certificate. + +export EASY_RSA="${EASY_RSA:-.}" +"$EASY_RSA/pkitool" --inter $* diff --git a/easy-rsa/build-key b/easy-rsa/build-key new file mode 100755 index 0000000..98389f2 --- /dev/null +++ b/easy-rsa/build-key @@ -0,0 +1,7 @@ +#!/bin/sh + +# Make a certificate/private key pair using a locally generated +# root certificate. + +export EASY_RSA="${EASY_RSA:-.}" +"$EASY_RSA/pkitool" $* diff --git a/easy-rsa/build-key-pass b/easy-rsa/build-key-pass new file mode 100755 index 0000000..02a6530 --- /dev/null +++ b/easy-rsa/build-key-pass @@ -0,0 +1,7 @@ +#!/bin/sh + +# Similar to build-key, but protect the private key +# with a password. + +export EASY_RSA="${EASY_RSA:-.}" +"$EASY_RSA/pkitool" --pass $* diff --git a/easy-rsa/build-key-pkcs12 b/easy-rsa/build-key-pkcs12 new file mode 100755 index 0000000..df46870 --- /dev/null +++ b/easy-rsa/build-key-pkcs12 @@ -0,0 +1,8 @@ +#!/bin/sh + +# Make a certificate/private key pair using a locally generated +# root certificate and convert it to a PKCS #12 file including the +# the CA certificate as well. + +export EASY_RSA="${EASY_RSA:-.}" +"$EASY_RSA/pkitool" --pkcs12 $* diff --git a/easy-rsa/build-key-server b/easy-rsa/build-key-server new file mode 100755 index 0000000..d27aef4 --- /dev/null +++ b/easy-rsa/build-key-server @@ -0,0 +1,10 @@ +#!/bin/sh + +# Make a certificate/private key pair using a locally generated +# root certificate. +# +# Explicitly set nsCertType to server using the "server" +# extension in the openssl.cnf file. + +export EASY_RSA="${EASY_RSA:-.}" +KEY_EXPIRE="$KEY_EXPIRE_SERVER" "$EASY_RSA/pkitool" --server $* diff --git a/easy-rsa/build-req b/easy-rsa/build-req new file mode 100755 index 0000000..173de3f --- /dev/null +++ b/easy-rsa/build-req @@ -0,0 +1,7 @@ +#!/bin/sh + +# Build a certificate signing request and private key. Use this +# when your root certificate and key is not available locally. + +export EASY_RSA="${EASY_RSA:-.}" +"$EASY_RSA/pkitool" --csr $* diff --git a/easy-rsa/build-req-pass b/easy-rsa/build-req-pass new file mode 100755 index 0000000..2bb8513 --- /dev/null +++ b/easy-rsa/build-req-pass @@ -0,0 +1,7 @@ +#!/bin/sh + +# Like build-req, but protect your private key +# with a password. + +export EASY_RSA="${EASY_RSA:-.}" +"$EASY_RSA/pkitool" --csr --pass $* diff --git a/easy-rsa/inherit-inter b/easy-rsa/inherit-inter new file mode 100755 index 0000000..1fe3539 --- /dev/null +++ b/easy-rsa/inherit-inter @@ -0,0 +1,39 @@ +#!/bin/sh + +# Build a new PKI which is rooted on an intermediate certificate generated +# by ./build-inter or ./pkitool --inter from a parent PKI. The new PKI should +# have independent vars settings, and must use a different KEY_DIR directory +# from the parent. This tool can be used to generate arbitrary depth +# certificate chains. +# +# To build an intermediate CA, follow the same steps for a regular PKI but +# replace ./build-key or ./pkitool --initca with this script. + +# The EXPORT_CA file will contain the CA certificate chain and should be +# referenced by the OpenVPN "ca" directive in config files. The ca.crt file +# will only contain the local intermediate CA -- it's needed by the easy-rsa +# scripts but not by OpenVPN directly. +EXPORT_CA="export-ca.crt" + +if [ $# -ne 2 ]; then + echo "usage: $0 " + echo "parent-key-dir: the KEY_DIR directory of the parent PKI" + echo "common-name: the common name of the intermediate certificate in the parent PKI" + exit 1; +fi + +if [ "$KEY_DIR" ]; then + cp "$1/$2.crt" "$KEY_DIR/ca.crt" + cp "$1/$2.key" "$KEY_DIR/ca.key" + + if [ -e "$1/$EXPORT_CA" ]; then + PARENT_CA="$1/$EXPORT_CA" + else + PARENT_CA="$1/ca.crt" + fi + cp "$PARENT_CA" "$KEY_DIR/$EXPORT_CA" + cat "$KEY_DIR/ca.crt" >> "$KEY_DIR/$EXPORT_CA" +else + echo 'Please source the vars script first (i.e. "source ./vars")' + echo 'Make sure you have edited it to reflect your configuration.' +fi diff --git a/easy-rsa/list-crl b/easy-rsa/list-crl new file mode 100755 index 0000000..32c1143 --- /dev/null +++ b/easy-rsa/list-crl @@ -0,0 +1,13 @@ +#!/bin/sh + +# list revoked certificates + +CRL="${1:-crl.pem}" + +if [ "$KEY_DIR" ]; then + cd "$KEY_DIR" && \ + $OPENSSL crl -text -noout -in "$CRL" +else + echo 'Please source the vars script first (i.e. "source ./vars")' + echo 'Make sure you have edited it to reflect your configuration.' +fi diff --git a/easy-rsa/openssl.cnf b/easy-rsa/openssl.cnf new file mode 100644 index 0000000..8ef87ca --- /dev/null +++ b/easy-rsa/openssl.cnf @@ -0,0 +1,286 @@ +# For use with easy-rsa version 2.0 and OpenSSL 1.0.0* + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . +RANDFILE = $HOME/.rnd +openssl_conf = openssl_init + +[ openssl_init ] +# Extra OBJECT IDENTIFIER info: +#oid_file = $ENV::HOME/.oid +oid_section = new_oids +engines = engine_section + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] + +# We can add new OIDs in here for use by 'ca' and 'req'. +# Add a simple OID like this: +# testoid1=1.2.3.4 +# Or use config file substitution like this: +# testoid2=${testoid1}.5.6 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = $ENV::KEY_DIR # Where everything is kept +certs = $dir # Where the issued certs are kept +crl_dir = $dir # Where the issued crl are kept +database = $dir/index.txt # database index file. +new_certs_dir = $dir # default place for new certs. + +certificate = $dir/ca.crt # The CA certificate +serial = $dir/serial # The current serial number +crl = $dir/crl.pem # The current CRL +private_key = $dir/ca.key # The private key +RANDFILE = $dir/.rand # private random number file + +x509_extensions = usr_cert # The extentions to add to the cert + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crl_extensions = crl_ext + +default_days = 90 # how long to certify for +default_crl_days= 30 # how long before next CRL +default_md = sha256 # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_anything + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +name = optional +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +name = optional +emailAddress = optional + +#################################################################### +[ req ] +default_bits = $ENV::KEY_SIZE +default_keyfile = privkey.pem +default_md = sha256 +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extentions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation after 2004). +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +string_mask = nombstr + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = $ENV::KEY_COUNTRY +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = $ENV::KEY_PROVINCE + +localityName = Locality Name (eg, city) +localityName_default = $ENV::KEY_CITY + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = $ENV::KEY_ORG + +# we can do this but it is not needed normally :-) +#1.organizationName = Second Organization Name (eg, company) +#1.organizationName_default = World Wide Web Pty Ltd + +organizationalUnitName = Organizational Unit Name (eg, section) +#organizationalUnitName_default = + +commonName = Common Name (eg, your name or your server\'s hostname) +commonName_max = 64 + +name = Name +name_max = 64 + +emailAddress = Email Address +emailAddress_default = $ENV::KEY_EMAIL +emailAddress_max = 40 + +# JY -- added for batch mode +organizationalUnitName_default = $ENV::KEY_OU +commonName_default = $ENV::KEY_CN +name_default = $ENV::KEY_NAME + + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +challengePassword = A challenge password +challengePassword_min = 4 +challengePassword_max = 20 + +unstructuredName = An optional company name + +[ usr_cert ] + +# These extensions are added when 'ca' signs a request. + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +# nsCertType = server + +# For an object signing certificate this would be used. +# nsCertType = objsign + +# For normal client use this is typical +# nsCertType = client, email + +# and for everything including object signing: +# nsCertType = client, email, objsign + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "VPN-Prov Generated Certificate" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer:always +extendedKeyUsage=clientAuth +keyUsage = digitalSignature + + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy + +# Copy subject details +# issuerAltName=issuer:copy + +#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +[ server ] + +# JY ADDED -- Make a cert with nsCertType set to "server" +basicConstraints=CA:FALSE +nsCertType = server +nsComment = "VPN-Prov Generated Server Certificate" +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer:always +extendedKeyUsage=serverAuth +keyUsage = digitalSignature, keyEncipherment + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] + + +# Extensions for a typical CA + + +# PKIX recommendation. + +subjectKeyIdentifier=hash + +authorityKeyIdentifier=keyid:always,issuer:always + +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true +# So we do this instead. +basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. However since it will +# prevent it being used as an test self-signed certificate it is best +# left out by default. +# keyUsage = cRLSign, keyCertSign + +# Some might want this also +# nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +# subjectAltName=email:copy +# Copy issuer details +# issuerAltName=issuer:copy + +# DER hex encoding of an extension: beware experts only! +# obj=DER:02:03 +# Where 'obj' is a standard or added object +# You can even override a supported extension: +# basicConstraints= critical, DER:30:03:01:01:FF + +[ crl_ext ] + +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +# issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always,issuer:always + +[ engine_section ] +# +# If you are using PKCS#11 +# Install engine_pkcs11 of opensc (www.opensc.org) +# And uncomment the following +# verify that dynamic_path points to the correct location +# +#pkcs11 = pkcs11_section + +[ pkcs11_section ] +engine_id = pkcs11 +dynamic_path = /usr/lib/engines/engine_pkcs11.so +MODULE_PATH = $ENV::PKCS11_MODULE_PATH +PIN = $ENV::PKCS11_PIN +init = 0 diff --git a/easy-rsa/pkitool b/easy-rsa/pkitool new file mode 100755 index 0000000..b79e0de --- /dev/null +++ b/easy-rsa/pkitool @@ -0,0 +1,392 @@ +#!/bin/sh + +# OpenVPN -- An application to securely tunnel IP networks +# over a single TCP/UDP port, with support for SSL/TLS-based +# session authentication and key exchange, +# packet encryption, packet authentication, and +# packet compression. +# +# Copyright (C) 2002-2010 OpenVPN Technologies, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 +# as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING included with this +# distribution); if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# pkitool is a front-end for the openssl tool. + +# Calling scripts can set the certificate organizational +# unit with the KEY_OU environmental variable. + +# Calling scripts can also set the KEY_NAME environmental +# variable to set the "name" X509 subject field. + +PROGNAME=pkitool +VERSION=2.0 +DEBUG=0 + +die() +{ + local m="$1" + + echo "$m" >&2 + exit 1 +} + +need_vars() +{ + cat < root certificate (--ca) + ca.key -> root key, keep secure (not directly used by OpenVPN) + .crt files -> client/server certificates (--cert) + .key files -> private keys, keep secure (--key) + .csr files -> certificate signing request (not directly used by OpenVPN) + dh1024.pem or dh2048.pem -> Diffie Hellman parameters (--dh) + +Examples: + $PROGNAME --initca -> Build root certificate + $PROGNAME --initca --pass -> Build root certificate with password-protected key + $PROGNAME --server server1 -> Build "server1" certificate/key + $PROGNAME client1 -> Build "client1" certificate/key + $PROGNAME --pass client2 -> Build password-protected "client2" certificate/key + $PROGNAME --pkcs12 client3 -> Build "client3" certificate/key in PKCS#12 format + $PROGNAME --csr client4 -> Build "client4" CSR to be signed by another CA + $PROGNAME --sign client4 -> Sign "client4" CSR + $PROGNAME --inter interca -> Build an intermediate key-signing certificate/key + Also see ./inherit-inter script. + $PROGNAME --pkcs11 /usr/lib/pkcs11/lib1 0 010203 "client5 id" client5 + -> Build "client5" certificate/key in PKCS#11 token + +Typical usage for initial PKI setup. Build myserver, client1, and client2 cert/keys. +Protect client2 key with a password. Build DH parms. Generated files in ./keys : + [edit vars with your site-specific info] + source ./vars + ./clean-all + ./build-dh -> takes a long time, consider backgrounding + ./$PROGNAME --initca + ./$PROGNAME --server myserver + ./$PROGNAME client1 + ./$PROGNAME --pass client2 + +Typical usage for adding client cert to existing PKI: + source ./vars + ./$PROGNAME client-new +EOM +} + +# Set tool defaults +[ -n "$OPENSSL" ] || export OPENSSL="openssl" +[ -n "$PKCS11TOOL" ] || export PKCS11TOOL="pkcs11-tool" +[ -n "$GREP" ] || export GREP="grep" + +# Set defaults +DO_REQ="1" +REQ_EXT="" +DO_CA="1" +CA_EXT="" +DO_P12="0" +DO_P11="0" +DO_ROOT="0" +NODES_REQ="-nodes" +NODES_P12="" +BATCH="-batch" +CA="ca" +# must be set or errors of openssl.cnf +PKCS11_MODULE_PATH="dummy" +PKCS11_PIN="dummy" + +# Process options +while [ $# -gt 0 ]; do + case "$1" in + --keysize ) KEY_SIZE=$2 + shift;; + --server ) REQ_EXT="$REQ_EXT -extensions server" + CA_EXT="$CA_EXT -extensions server" ;; + --batch ) BATCH="-batch" ;; + --interact ) BATCH="" ;; + --inter ) CA_EXT="$CA_EXT -extensions v3_ca" ;; + --initca ) DO_ROOT="1" ;; + --pass ) NODES_REQ="" ;; + --csr ) DO_CA="0" ;; + --sign ) DO_REQ="0" ;; + --pkcs12 ) DO_P12="1" ;; + --pkcs11 ) DO_P11="1" + PKCS11_MODULE_PATH="$2" + PKCS11_SLOT="$3" + PKCS11_ID="$4" + PKCS11_LABEL="$5" + shift 4;; + + # standalone + --pkcs11-init) + PKCS11_MODULE_PATH="$2" + PKCS11_SLOT="$3" + PKCS11_LABEL="$4" + if [ -z "$PKCS11_LABEL" ]; then + die "Please specify library name, slot and label" + fi + $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --init-token --slot "$PKCS11_SLOT" \ + --label "$PKCS11_LABEL" && + $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --init-pin --slot "$PKCS11_SLOT" + exit $?;; + --pkcs11-slots) + PKCS11_MODULE_PATH="$2" + if [ -z "$PKCS11_MODULE_PATH" ]; then + die "Please specify library name" + fi + $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --list-slots + exit 0;; + --pkcs11-objects) + PKCS11_MODULE_PATH="$2" + PKCS11_SLOT="$3" + if [ -z "$PKCS11_SLOT" ]; then + die "Please specify library name and slot" + fi + $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --list-objects --login --slot "$PKCS11_SLOT" + exit 0;; + + --help|--usage) + usage + exit ;; + --version) + echo "$PROGNAME $VERSION" + exit ;; + # errors + --* ) die "$PROGNAME: unknown option: $1" ;; + * ) break ;; + esac + shift +done + +if ! [ -z "$BATCH" ]; then + if $OPENSSL version | grep 0.9.6 > /dev/null; then + die "Batch mode is unsupported in openssl<0.9.7" + fi +fi + +if [ $DO_P12 -eq 1 -a $DO_P11 -eq 1 ]; then + die "PKCS#11 and PKCS#12 cannot be specified together" +fi + +if [ $DO_P11 -eq 1 ]; then + if ! grep "^pkcs11.*=" "$KEY_CONFIG" > /dev/null; then + die "Please edit $KEY_CONFIG and setup PKCS#11 engine" + fi +fi + +# If we are generating pkcs12, only encrypt the final step +if [ $DO_P12 -eq 1 ]; then + NODES_P12="$NODES_REQ" + NODES_REQ="-nodes" +fi + +if [ $DO_P11 -eq 1 ]; then + if [ -z "$PKCS11_LABEL" ]; then + die "PKCS#11 arguments incomplete" + fi +fi + +# If undefined, set default key expiration intervals +if [ -z "$KEY_EXPIRE" ]; then + KEY_EXPIRE=3650 +fi +if [ -z "$CA_EXPIRE" ]; then + CA_EXPIRE=3650 +fi + +# Set organizational unit to empty string if undefined +if [ -z "$KEY_OU" ]; then + KEY_OU="" +fi + +# Set X509 Name string to empty string if undefined +if [ -z "$KEY_NAME" ]; then + KEY_NAME="" +fi + +# Set KEY_CN, FN +if [ $DO_ROOT -eq 1 ]; then + if [ -z "$KEY_CN" ]; then + if [ "$1" ]; then + KEY_CN="$1" + elif [ "$KEY_ORG" ]; then + KEY_CN="$KEY_ORG CA" + fi + fi + if [ $BATCH ] && [ "$KEY_CN" ]; then + echo "Using CA Common Name:" "$KEY_CN" + fi + FN="$KEY_CN" +elif [ $BATCH ] && [ "$KEY_CN" ]; then + echo "Using Common Name:" "$KEY_CN" + FN="$KEY_CN" + if [ "$1" ]; then + FN="$1" + fi +else + if [ $# -ne 1 ]; then + usage + exit 1 + else + KEY_CN="$1" + fi + FN="$KEY_CN" +fi + +export CA_EXPIRE KEY_EXPIRE KEY_OU KEY_NAME KEY_CN PKCS11_MODULE_PATH PKCS11_PIN + +# Show parameters (debugging) +if [ $DEBUG -eq 1 ]; then + echo DO_REQ $DO_REQ + echo REQ_EXT $REQ_EXT + echo DO_CA $DO_CA + echo CA_EXT $CA_EXT + echo NODES_REQ $NODES_REQ + echo NODES_P12 $NODES_P12 + echo DO_P12 $DO_P12 + echo KEY_CN $KEY_CN + echo BATCH $BATCH + echo DO_ROOT $DO_ROOT + echo KEY_EXPIRE $KEY_EXPIRE + echo CA_EXPIRE $CA_EXPIRE + echo KEY_OU $KEY_OU + echo KEY_NAME $KEY_NAME + echo DO_P11 $DO_P11 + echo PKCS11_MODULE_PATH $PKCS11_MODULE_PATH + echo PKCS11_SLOT $PKCS11_SLOT + echo PKCS11_ID $PKCS11_ID + echo PKCS11_LABEL $PKCS11_LABEL +fi + +# Make sure ./vars was sourced beforehand +if [ -d "$KEY_DIR" ] && [ "$KEY_CONFIG" ]; then + cd "$KEY_DIR" + + # Make sure $KEY_CONFIG points to the correct version + # of openssl.cnf + if $GREP -i 'easy-rsa version 2\.[0-9]' "$KEY_CONFIG" >/dev/null; then + : + else + echo "$PROGNAME: KEY_CONFIG (set by the ./vars script) is pointing to the wrong" + echo "version of openssl.cnf: $KEY_CONFIG" + echo "The correct version should have a comment that says: easy-rsa version 2.x"; + exit 1; + fi + + # Build root CA + if [ $DO_ROOT -eq 1 ]; then + $OPENSSL req $BATCH -days $CA_EXPIRE $NODES_REQ -new -newkey rsa:$KEY_SIZE \ + -x509 -keyout "$CA.key" -out "$CA.crt" -config "$KEY_CONFIG" && \ + chmod 0600 "$CA.key" + else + # Make sure CA key/cert is available + if [ $DO_CA -eq 1 ] || [ $DO_P12 -eq 1 ]; then + if [ ! -r "$CA.crt" ] || [ ! -r "$CA.key" ]; then + echo "$PROGNAME: Need a readable $CA.crt and $CA.key in $KEY_DIR" + echo "Try $PROGNAME --initca to build a root certificate/key." + exit 1 + fi + fi + + # Generate key for PKCS#11 token + PKCS11_ARGS= + if [ $DO_P11 -eq 1 ]; then + stty -echo + echo -n "User PIN: " + read -r PKCS11_PIN + stty echo + export PKCS11_PIN + + echo "Generating key pair on PKCS#11 token..." + $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --keypairgen \ + --login --pin "$PKCS11_PIN" \ + --key-type rsa:1024 \ + --slot "$PKCS11_SLOT" --id "$PKCS11_ID" --label "$PKCS11_LABEL" || exit 1 + PKCS11_ARGS="-engine pkcs11 -keyform engine -key $PKCS11_SLOT:$PKCS11_ID" + fi + + # Build cert/key + ( [ $DO_REQ -eq 0 ] || $OPENSSL req $BATCH -days $KEY_EXPIRE $NODES_REQ -new -newkey rsa:$KEY_SIZE \ + -keyout "$FN.key" -out "$FN.csr" $REQ_EXT -config "$KEY_CONFIG" $PKCS11_ARGS ) && \ + ( [ $DO_CA -eq 0 ] || $OPENSSL ca $BATCH -days $KEY_EXPIRE -out "$FN.crt" \ + -in "$FN.csr" $CA_EXT -config "$KEY_CONFIG" ) && \ + ( [ $DO_P12 -eq 0 ] || $OPENSSL pkcs12 -export -inkey "$FN.key" \ + -in "$FN.crt" -certfile "$CA.crt" -out "$FN.p12" $NODES_P12 ) && \ + ( [ $DO_CA -eq 0 -o $DO_P11 -eq 1 ] || chmod 0600 "$FN.key" ) && \ + ( [ $DO_P12 -eq 0 ] || chmod 0600 "$FN.p12" ) + + # Load certificate into PKCS#11 token + if [ $DO_P11 -eq 1 ]; then + $OPENSSL x509 -in "$FN.crt" -inform PEM -out "$FN.crt.der" -outform DER && \ + $PKCS11TOOL --module "$PKCS11_MODULE_PATH" --write-object "$FN.crt.der" --type cert \ + --login --pin "$PKCS11_PIN" \ + --slot "$PKCS11_SLOT" --id "$PKCS11_ID" --label "$PKCS11_LABEL" + [ -e "$FN.crt.der" ]; rm "$FN.crt.der" + fi + + fi + +# Need definitions +else + need_vars +fi diff --git a/easy-rsa/revoke-full b/easy-rsa/revoke-full new file mode 100755 index 0000000..439f6a0 --- /dev/null +++ b/easy-rsa/revoke-full @@ -0,0 +1,40 @@ +#!/bin/sh + +# revoke a certificate, regenerate CRL, +# and verify revocation + +CRL="crl.pem" +RT="revoke-test.pem" + +if [ $# -ne 1 ]; then + echo "usage: revoke-full "; + exit 1 +fi + +if [ "$KEY_DIR" ]; then + cd "$KEY_DIR" + rm -f "$RT" + + # set defaults + export KEY_CN="" + export KEY_OU="" + export KEY_NAME="" + + # revoke key and generate a new CRL + $OPENSSL ca -revoke "$1.crt" -config "$KEY_CONFIG" + + # generate a new CRL -- try to be compatible with + # intermediate PKIs + $OPENSSL ca -gencrl -out "$CRL" -config "$KEY_CONFIG" + if [ -e export-ca.crt ]; then + cat export-ca.crt "$CRL" >"$RT" + else + cat ca.crt "$CRL" >"$RT" + fi + + # verify the revocation + $OPENSSL verify -CAfile "$RT" -crl_check "$1.crt" +else + echo 'Please source the vars script first (i.e. "source ./vars")' + echo 'Make sure you have edited it to reflect your configuration.' +fi diff --git a/easy-rsa/sign-req b/easy-rsa/sign-req new file mode 100755 index 0000000..ade12b0 --- /dev/null +++ b/easy-rsa/sign-req @@ -0,0 +1,7 @@ +#!/bin/sh + +# Sign a certificate signing request (a .csr file) +# with a local root certificate and key. + +export EASY_RSA="${EASY_RSA:-.}" +"$EASY_RSA/pkitool" --sign $* diff --git a/easy-rsa/vars.example b/easy-rsa/vars.example new file mode 100644 index 0000000..0230bc4 --- /dev/null +++ b/easy-rsa/vars.example @@ -0,0 +1,79 @@ +# vim: ft=bash +# easy-rsa parameter settings + +# NOTE: If you installed from an RPM, +# don't edit this file in place in +# /usr/share/openvpn/easy-rsa -- +# instead, you should copy the whole +# easy-rsa directory to another location +# (such as /etc/openvpn) so that your +# edits will not be wiped out by a future +# OpenVPN package upgrade. + +# This variable should point to +# the top level of the easy-rsa +# tree. +export EASY_RSA="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" + +# +# This variable should point to +# the requested executables +# +export OPENSSL="openssl" +export PKCS11TOOL="pkcs11-tool" +export GREP="grep" + + +# This variable should point to +# the openssl.cnf file included +# with easy-rsa. +export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA` + +# Edit this variable to point to +# your soon-to-be-created key +# directory. +# +# WARNING: clean-all will do +# a rm -rf on this directory +# so make sure you define +# it correctly! +export KEY_DIR="$EASY_RSA/keys" + +# PKCS11 fixes +export PKCS11_MODULE_PATH="dummy" +export PKCS11_PIN="dummy" + +# Increase this to 2048 if you +# are paranoid. This will slow +# down TLS negotiation performance +# as well as the one-time DH parms +# generation process. +export KEY_SIZE=2048 + +# In how many days should the root CA key expire? +export CA_EXPIRE=3650 + +# In how many days should certificates expire? +export KEY_EXPIRE=90 +export KEY_EXPIRE_SERVER=3650 + +# These are the default values for fields +# which will be placed in the certificate. +# Don't leave any of these fields blank. +export KEY_COUNTRY="US" +export KEY_PROVINCE="" +export KEY_CITY="" +export KEY_ORG="" +export KEY_EMAIL="" +#export KEY_OU="" #XXX set by script + +# X509 Subject Field +export KEY_NAME="VPN-Prov" + +# PKCS11 Smart Card +# export PKCS11_MODULE_PATH="/usr/lib/changeme.so" +# export PKCS11_PIN=1234 + +# If you'd like to sign all keys with the same Common Name, uncomment the KEY_CN export below +# You will also need to make sure your OpenVPN server config has the duplicate-cn option set +#export KEY_CN="CommonName" # set by script, otherwise should be set by hand diff --git a/easy-rsa/whichopensslcnf b/easy-rsa/whichopensslcnf new file mode 100755 index 0000000..4c5f3c7 --- /dev/null +++ b/easy-rsa/whichopensslcnf @@ -0,0 +1,26 @@ +#!/bin/sh + +cnf="$1/openssl.cnf" + +if [ "$OPENSSL" ]; then + if $OPENSSL version | grep -E "0\.9\.6[[:alnum:]]?" > /dev/null; then + cnf="$1/openssl-0.9.6.cnf" + elif $OPENSSL version | grep -E "0\.9\.8[[:alnum:]]?" > /dev/null; then + cnf="$1/openssl-0.9.8.cnf" + elif $OPENSSL version | grep -E "1\.0\.[[:digit:]][[:alnum:]]?" > /dev/null; then + cnf="$1/openssl-1.0.0.cnf" + else + cnf="$1/openssl.cnf" + fi +fi + +echo $cnf + +if [ ! -r $cnf ]; then + echo "**************************************************************" >&2 + echo " No $cnf file could be found" >&2 + echo " Further invocations will fail" >&2 + echo "**************************************************************" >&2 +fi + +exit 0 diff --git a/gpresult.html b/gpresult.html new file mode 100755 index 0000000..e6e959d Binary files /dev/null and b/gpresult.html differ diff --git a/init-dirs.sh b/init-dirs.sh new file mode 100755 index 0000000..c22a8ae --- /dev/null +++ b/init-dirs.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +cd "$(dirname "$(readlink -f "$0")")" +source ./easy-rsa/vars + +if [ -n "$KEY_DIR" ]; then + if [ -O "$KEY_DIR" ]; then + chmod go-rwx "$KEY_DIR" + if [ ! -e "$KEY_DIR/index.txt" ]; then + echo "Building index.txt" + touch "$KEY_DIR/index.txt" + fi + if [ ! -e "$KEY_DIR/index.txt.attr" ]; then + echo "Building index.txt.attr" + echo "unique_subject = no" >"$KEY_DIR/index.txt.attr" + fi + if [ ! -e "$KEY_DIR/serial" ]; then + echo "Building serial" + echo 01 >"$KEY_DIR/serial" + fi + if [ ! -e "$KEY_DIR/ca.crt" -a ! -e "$KEY_DIR/ca.key" ]; then + echo "Building CA" + ./easy-rsa/build-ca + fi + else + echo "The key dir '$KEY_DIR' isn't owned by the right user ($USER)" + fi +else + echo 'Make sure you have edited easy-rsa/vars to reflect your configuration.' +fi diff --git a/install-openvpn.bat b/install-openvpn.bat new file mode 100755 index 0000000..2ba9883 --- /dev/null +++ b/install-openvpn.bat @@ -0,0 +1,10 @@ +mkdir "C:\Program Files\OpenVPN\config-auto" +curl -u : --negotiate -o "C:\Program Files\OpenVPN\config-auto\vpnprov-%COMPUTERNAME%.ovpn" "https://example.com/vpn-prov/create.php" + +start /wait msiexec /i \\server\share\OpenVPN-2.6.6-I001-amd64.msi /quiet /qn /norestart /log c:\windows\temp\openvpn.msi.log ADDLOCAL=OpenVPN.Service,Drivers.OvpnDco,OpenVPN,Drivers,Drivers.TAPWindows6,Drivers.Wintun + +sc config OpenVPNServiceInteractive start= disabled +sc stop OpenVPNServiceInteractive + +sc config OpenVPNService start= auto +sc start OpenVPNService diff --git a/www/create.php b/www/create.php new file mode 100644 index 0000000..d0f2e65 --- /dev/null +++ b/www/create.php @@ -0,0 +1,35 @@ +