19

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 [it@mycompany.com]:

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:'it@mycompany.com'
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.

Jake Wilson
  • 8,494
  • 29
  • 94
  • 121

11 Answers11

22

try --batch flag

./build-key --batch client1
Tomot
  • 409
  • 4
  • 5
  • 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 – David Poxon Oct 16 '16 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. – James Firth Mar 07 '19 at 11:01
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
pjz
  • 10,497
  • 1
  • 31
  • 40
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      "vpn@example.com"
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
user394252
  • 51
  • 1
  • 1
2

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

  • 3
    expect is way overkill for this; easy-rsa is all shell scripts, so easily hackable. – pjz Aug 23 '10 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
    This worked for me. I like it the most because it doesn't require the user to understand the script. – AFP_555 Jan 22 '18 at 04: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 
Jenny D
  • 27,358
  • 21
  • 74
  • 110
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
rattkin
  • 11
  • 1
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}
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
JonathanDavidArndt
  • 1,414
  • 3
  • 20
  • 29
-2

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