20

I have a lot of keys to generate for my clients VPN server. Whenever I use easy-rsa to generate the keys like this:

./build-key client1

There is some output with a series of questions. The questions all have default answers that are defined in the vars file.

Generating a 1024 bit RSA private key
............................................++++++
.......................++++++
writing new private key to 'client1.key'
-----
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.
-----
Country Name (2 letter code) [US]:
State or Province Name (full name) [CO]:
Locality Name (eg, city) [Denver]:
Organization Name (eg, company) [mycompany]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [client1]:
Email Address [[email protected]]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /etc/openvpn/easy-rsa/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'US'
stateOrProvinceName   :PRINTABLE:'CO'
localityName          :PRINTABLE:'Denver'
organizationName      :PRINTABLE:'mycompany'
commonName            :PRINTABLE:'client1'
emailAddress          :IA5STRING:'[email protected]'
Certificate is to be certified until Jan  3 20:16:04 2038 GMT (9999 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

All in all, I have to manually press the following keys:

ENTER
ENTER
ENTER
ENTER
ENTER
ENTER
ENTER
ENTER
y
ENTER
y
ENTER

Basically I'm just accepting all default answers and saying 'yes' to the final two questions. Are there any -force or -quiet flags or something that I can use with build-key? If not, are there are scripting or bash tricks I can use to just do this everytime? I can't find anything in any man pages about it.

11 Answers 11

14

If you look at the source of build-key, you'll find it's calling pkitool. I wrote a wrapper to bundle up the cilent's keys and the appropriate openvpn config files into a tarball I could then give to my users:

#!/bin/bash

client=$1

if [ x$client = x ]; then
    echo "Usage: $0 clientname"
    exit 1
fi

if [ ! -e keys/$client.key ]; then
    echo "Generating keys..."
    . vars
    ./pkitool $client
    echo "...keys generated." 
fi

tarball=./keys/$client.tgz

if [ ! -e $tarball ]; then
    echo "Creating tarball..."
    tmpdir=/tmp/client-tar.$$
    mkdir $tmpdir
    cp company.ovpn $tmpdir/company.ovpn
    cp keys/ca.crt $tmpdir 
    cp keys/$client.key $tmpdir/client.key
    cp keys/$client.crt $tmpdir/client.crt
    tar -C $tmpdir -czvf $tarball .
    rm -rf $tmpdir
    echo "...tarball created" 
else
    echo "Nothing to do, so nothing done. (keys/$client.tgz already exists)" 
fi
23

try --batch flag

./build-key --batch client1
2
  • I tried this, but the common name was the server address, not the name of they i wanted to generate, as is the behaviour without the --batch flag Oct 16, 2016 at 22:42
  • For me this is the answer to the question posed. This is how to automate key production for most standard configurations and suggest accepting this as the answer. Mar 7, 2019 at 11:01
5

The new version of EasyRSA comes as a single binary right now. To automate building a client key, you can now use "vars" file (just place it in the same directory as easyrsa binary):

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

set_var EASYRSA        "$PWD"
set_var EASYRSA_OPENSSL        "openssl"
set_var EASYRSA_PKI            "$EASYRSA/pki"
set_var EASYRSA_DN     "org"

set_var EASYRSA_REQ_COUNTRY    "Country"
set_var EASYRSA_REQ_PROVINCE   "Province"
set_var EASYRSA_REQ_CITY       "City"
set_var EASYRSA_REQ_ORG        "Org Ltd"
set_var EASYRSA_REQ_EMAIL      "[email protected]"
set_var EASYRSA_REQ_OU         "Infrastructure"

set_var EASYRSA_KEY_SIZE       2048

set_var EASYRSA_ALGO           rsa

set_var EASYRSA_CA_EXPIRE      3650
set_var EASYRSA_CERT_EXPIRE    365
set_var EASYRSA_CRL_DAYS       180

set_var EASYRSA_TEMP_FILE      "$EASYRSA_PKI/extensions.temp"

and use EasyRSA's binary:

./easyrsa build-client-full client1 nopass
2

The thing that comes to my mind the quickest is expect; it allows you to automate these sorts of command line interactions.

1
  • 3
    expect is way overkill for this; easy-rsa is all shell scripts, so easily hackable.
    – pjz
    Aug 23, 2010 at 17:53
2

I had the same problem.

The solution I found was :

echo -en "\n\n\n\n\n\n\n\ny\ny\n" | ./build-key client1

1
  • 1
    This worked for me. I like it the most because it doesn't require the user to understand the script.
    – AFP_555
    Jan 22, 2018 at 4:44
1

This is similar to what I use. Hope this helps someone, it took me hours to figure this out. Make sure you are executing in the directory easy-rsa, and don't forget to source ./vars

(echo -en "\n\n\n\n\n\n\n\n"; sleep 1; echo -en "\n"; sleep 1; echo -en "\n"; sleep 3; echo -en "yes"; echo -en "\n"; sleep 3; echo -en "yes"; echo -en "\n") | ./build-key $key_id 
1

I made a wrapper like pjz, but with bundling all necessary files into single .ovpn file, which can be used directly

#!/bin/bash
cd /etc/openvpn/easy-rsa/2.0
client=$1

if [ x$client = x ]; then
    echo "Usage: $0 clientname"
    exit 1
fi

if [ ! -e keys/$client.key ]; then
    echo "Generating keys..."
    . vars
    ./pkitool $client
    echo "...keys generated."
fi

bundle=./keys/$client.ovpn

if [ ! -e $bundle ]; then
    echo "Creating bundle..."
    cat keys/template.ovpn >> $bundle
    echo '' >> $bundle
    cat keys/ca.crt >> $bundle
    echo '' >> $bundle
    echo '' >> $bundle
    echo '' >> $bundle
    awk '/BEGIN CERTIFICATE/,0' keys/$client.crt >> $bundle
    echo '' >> $bundle
    echo '' >> $bundle
    echo '' >> $bundle
    cat keys/$client.key >> $bundle
    echo '' >> $bundle
    echo '' >> $bundle
    echo "...bundle created"
else
    echo "Nothing to do, so nothing done. (keys/$client.ovpn already exists)"
fi
0

I have just tried to do this very same thing, generating the openvpn users silently on freeBSD box.

This resulted in a new file, aptly named ./build-key-quiet

#!/bin/sh

# Make a certificate/private key pair using a locally generated
# root certificate.
# JP - automating my time away

cd /root/openvpn

client=$1

if [ x$client = x ];
    then
    echo "Usage: $0 clientname"
    exit 1
fi

if [ ! -e keys/$client.key ];
  then
    echo "Generating keys..."
    . ./vars
    ./pkitool $client
    echo "Great Success ...keys generated."
fi

echo 'Generating ovpn Files'
cd /root/clients
./make-client-config.sh $client
rm -rf /tmp/*.ovpn
cp /root/clients/files/$client.ovpn /tmp/
chmod 777 /root/clients/files/*.ovpn

echo "cleaning up /tmp/ of old ovpn files..."
echo "OVPN file generated and copied into /tmp/$client.ovpn"
0
(echo -en "\n\n\n\n\n\n\n\n"; sleep 1; echo -en "\n"; sleep 1; echo -en "\n"; sleep 3; echo -en "yes"; echo -en "\n"; sleep 3; echo -en "yes"; echo -en "\n") | ./build-key $key_id
0

I tried this, but the common name was the server address

U have to set KEY_CN before run pkitool

#!/bin/bash
$USER_NAME="$1"
source ./vars
KEY_CN=${USER_NAME}
export EASY_RSA="${EASY_RSA:-.}"
"$EASY_RSA/pkitool" ${USER_NAME}
-2

just edit the build-key file, and remove the --interact option easiest method I'm aware of

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .