freeipa-letsencrypt.sh
5.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/bin/bash -e
#
# freeipa-letsencrypt.sh - script to setup Let's Encrypt's Certbot for FreeIPA
#
# Version 1.0, latest version, documentation and bugtracker available at:
# https://gitlab.lindenaar.net/scripts/freeipa
#
# Copyright (c) 2018 Frederik Lindenaar
#
# This script is free software: you can redistribute and/or modify it under the
# terms of version 3 of the GNU General Public License as published by the Free
# Software Foundation, or (at your option) any later version of the license.
#
# This script 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. If not, visit <http://www.gnu.org/licenses/> to download it.
# Sanity checks, ensure we have a valid Kerberos ticket, current host is a
# FreeIPA server, certbot is installed and that we can run priviliged commands
die() { echo $* >&2; exit 1; }
if ! klist -s; then
die no valid Kerberos ticket, please login to FreeIPA using kinit first
elif ! ipa server-show ${HOSTNAME:=$(hostname --fqdn)} > /dev/null; then
die this script should be run on an active IPA server
elif ! which certbot > /dev/null; then
die this script requires Certbot to be installed, please install that first
elif [ $(id -u) == 0 ]; then
unset SUDO
elif ! ${SUDO:=sudo} -v; then
die Error: this script must be run by root and $SUDO does not seem to work
else
$SUDO kinit -k
fi
# Set KRB5CCNAME to ensure the current ticket cache will be used
: ${KRB5CCNAME:=$(klist -l | head -3 | tail -1 | cut -d\ -f2-)}
# Set parameters
: ${CERTNAME:=$(ipa host-show $HOSTNAME --raw | fgrep "krbcanonicalname: host/" | cut -d/ -f2 | cut -d@ -f1)}
: ${DNSALTNAMES:=$(ipa host-show $HOSTNAME --raw | fgrep "krbprincipalname: host/" | cut -d/ -f2 | cut -d@ -f1 | paste -sd,)}
: ${EMAIL:=hostmaster@${HOSTNAME#*.}}
: ${SERVICE:=letsencrypt/$(ipa host-show $HOSTNAME --raw | fgrep "krbcanonicalname: host/" | cut -d/ -f2)}
# Ensure the user consents with changing his system.
if tty > /dev/null; then
cat << EOT
This script modifies this host's FreeIPA setup so that its web interface will
use a Let's Encrypt certificate and will automatically renew that when needed.
The following changes will be made for this:
1. Add Let's Encrypt Root and Intermediate CAs as trusted CAs
2. Create DNS Administrator role in FreeIPA that can edit any DNS Record
3. Create host service: $SERVICE
4. Allow letsencrypt host service to manage DNS entries
5. Register with Let's encrypt as: $EMAIL
6. Request a Let's Encrypt SSL certificate for: $CERTNAME
with DNS Alternative names: $DNSALTNAMES
7. install the Let's Encrypt certificate in apache as host SSL certificate,
storing renewal config in: /etc/letsencrypt/renewal/$HOSTNAME.conf
8. configure the Fedora Certbot renew timer so that certbot is run daily to
renew the certificate when needed.
EOT
while ! [[ "${REPLY:-}" =~ ^[YyNn]$ ]]; do
echo
read -rp "Please confirm these changes should be applied (y/n): " -n 1
done
echo
[[ "${REPLY}" =~ ^[Nn]$ ]] && die aborted
fi
echo
echo Download and importing Let\'s Encrypt certificates, this may take a while
declare -A LETSENCRYPTCERTS=(
[ISRGRootCAX1]=https://letsencrypt.org/certs/isrgrootx1.pem
[LetsEncryptX3]=https://letsencrypt.org/certs/letsencryptauthorityx3.pem
)
for certname in ${!LETSENCRYPTCERTS[@]}; do
certfile=$(mktemp -u ${TMPDIR:-/tmp}/$0.XXXXXXX.cert)
curl -s "${LETSENCRYPTCERTS[$certname]}" -o $certfile
$SUDO ipa-cacert-manage install $certfile -n "$certname" -t C,,
rm -f $certfile
done
$SUDO ipa-certupdate
echo
if ! ipa role-show "DNS Administrator" > /dev/null 2>&1; then
echo Creating DNS Administrator role
ipa role-add "DNS Administrator"
ipa role-add-privilege "DNS Administrator" --privileges="DNS Administrators"
else
echo DNS Administrator role already exists
fi
echo
if ! ipa service-show "$SERVICE" > /dev/null 2>&1; then
echo Add service user $SERVICE
ipa service-add "$SERVICE"
ipa role-add-member "DNS Administrator" --services="$SERVICE"
else
echo Service user $SERVICE already exists
fi
echo
if [ ! -f "${KEYTAB:=/etc/letsencrypt/keytab}" ]; then
echo creating keytab file $KEYTAB
$SUDO ipa-getkeytab -p "$SERVICE" -k "$KEYTAB"
else
echo not touching existing keytab file $KEYTAB
fi
echo
echo Requesting Let\'s Encrypt SSL certificate and setup renewals
$SUDO certbot certonly --expand --manual --preferred-challenges dns \
--manual-public-ip-logging-ok --agree-tos --email "${EMAIL}" \
--cert-name ${HOSTNAME} --domains "${DNSALTNAMES}" \
--pre-hook "kinit -k -t $KEYTAB \"$SERVICE\"" --post-hook "kdestroy" \
--manual-auth-hook "ipa dnsrecord-add ${DOMAIN:-\${CERTBOT_DOMAIN#*.\}}. _acme-challenge.\${CERTBOT_DOMAIN}. \"--txt-rec=\${CERTBOT_VALIDATION}\"; sleep 3" \
--manual-cleanup-hook "ipa dnsrecord-del ${DOMAIN:-\${CERTBOT_DOMAIN#*.\}}. _acme-challenge.\${CERTBOT_DOMAIN}. --del-all" \
--deploy-hook 'echo | ipa-server-certinstall --http "${RENEWED_LINEAGE}/fullchain.pem" "${RENEWED_LINEAGE}/privkey.pem" --dirman-password="" --pin="" && service httpd restart'
echo
echo Enabling Certbot package\'s renewal timer
$SUDO systemctl enable --now certbot-renew.timer
cat << EOT
FreeIPA was successfully setup to use a Let's Encrypt certificate for its web
interface. This certificate will be renewed automatically when needed.
EOT