1 |
#!/bin/bash |
2 |
# Author: Jan Vcelak <jvcelak@redhat.com> |
3 |
|
4 |
set -e |
5 |
|
6 |
# default options |
7 |
|
8 |
CERTDB_DIR=/etc/openldap/certs |
9 |
CERT_NAME="OpenLDAP Server" |
10 |
PASSWORD_FILE= |
11 |
HOSTNAME_FQDN="$(hostname --fqdn)" |
12 |
ALT_NAMES= |
13 |
ONCE=0 |
14 |
|
15 |
# internals |
16 |
|
17 |
RANDOM_SOURCE=/dev/urandom |
18 |
CERT_RANDOM_BYTES=256 |
19 |
CERT_KEY_TYPE=rsa |
20 |
CERT_KEY_SIZE=1024 |
21 |
CERT_VALID_MONTHS=12 |
22 |
|
23 |
# parse arguments |
24 |
|
25 |
usage() { |
26 |
printf "usage: generate-server-cert.sh [-d certdb-dir] [-n cert-name]\n" >&2 |
27 |
printf " [-p password-file] [-h hostnames]\n" >&2 |
28 |
printf " [-a dns-alt-names] [-o]\n" >&2 |
29 |
exit 1 |
30 |
} |
31 |
|
32 |
while getopts "d:n:p:h:a:o" opt; do |
33 |
case "$opt" in |
34 |
d) |
35 |
CERTDB_DIR="$OPTARG" |
36 |
;; |
37 |
n) |
38 |
CERT_NAME="$OPTARG" |
39 |
;; |
40 |
p) |
41 |
PASSWORD_FILE="$OPTARG" |
42 |
;; |
43 |
h) |
44 |
HOSTNAME_FQDN="$OPTARG" |
45 |
;; |
46 |
a) |
47 |
ALT_NAMES="$OPTARG" |
48 |
;; |
49 |
o) |
50 |
ONCE=1 |
51 |
;; |
52 |
\?) |
53 |
usage |
54 |
;; |
55 |
esac |
56 |
done |
57 |
|
58 |
[ "$OPTIND" -le "$#" ] && usage |
59 |
|
60 |
# generated options |
61 |
|
62 |
ONCE_FILE="$CERTDB_DIR/.slapd-leave" |
63 |
PASSWORD_FILE="${PASSWORD_FILE:-${CERTDB_DIR}/password}" |
64 |
ALT_NAMES="${ALT_NAMES:-${HOSTNAME_FQDN},localhost,localhost.localdomain}" |
65 |
|
66 |
# verify target location |
67 |
|
68 |
if [ "$ONCE" -eq 1 -a -f "$ONCE_FILE" ]; then |
69 |
printf "Skipping certificate generating, '%s' exists.\n" "$ONCE_FILE" >&2 |
70 |
exit 0 |
71 |
fi |
72 |
|
73 |
if ! certutil -d "$CERTDB_DIR" -U &>/dev/null; then |
74 |
printf "Directory '%s' is not a valid certificate database.\n" "$CERTDB_DIR" >&2 |
75 |
exit 1 |
76 |
fi |
77 |
|
78 |
printf "Creating new server certificate in '%s'.\n" "$CERTDB_DIR" >&2 |
79 |
|
80 |
if [ ! -r "$PASSWORD_FILE" ]; then |
81 |
printf "Password file '%s' is not readable.\n" "$PASSWORD_FILE" >&2 |
82 |
exit 1 |
83 |
fi |
84 |
|
85 |
if certutil -d "$CERTDB_DIR" -L -a -n "$CERT_NAME" &>/dev/null; then |
86 |
printf "Certificate '%s' already exists in the certificate database.\n" "$CERT_NAME" >&2 |
87 |
exit 1 |
88 |
fi |
89 |
|
90 |
# generate server certificate (self signed) |
91 |
|
92 |
|
93 |
CERT_RANDOM=$(mktemp) |
94 |
dd if=$RANDOM_SOURCE bs=$CERT_RANDOM_BYTES count=1 of=$CERT_RANDOM &>/dev/null |
95 |
|
96 |
certutil -d "$CERTDB_DIR" -f "$PASSWORD_FILE" -z "$CERT_RANDOM" \ |
97 |
-S -x -n "$CERT_NAME" \ |
98 |
-s "CN=$HOSTNAME_FQDN" \ |
99 |
-t TC,, \ |
100 |
-k $CERT_KEY_TYPE -g $CERT_KEY_SIZE \ |
101 |
-v $CERT_VALID_MONTHS \ |
102 |
-8 "$ALT_NAMES" \ |
103 |
&>/dev/null |
104 |
|
105 |
rm -f $CERT_RANDOM |
106 |
|
107 |
# tune permissions |
108 |
|
109 |
if [ "$(id -u)" -eq 0 ]; then |
110 |
chgrp ldap "$PASSWORD_FILE" |
111 |
chmod g+r "$PASSWORD_FILE" |
112 |
else |
113 |
printf "WARNING: The server requires read permissions on the password file in order to\n" >&2 |
114 |
printf " load it's private key from the certificate database.\n" >&2 |
115 |
fi |
116 |
|
117 |
touch "$ONCE_FILE" |
118 |
exit 0 |