fixed small issue in freeipa-dns (override check not working)
updated README - added clarification on password migration being limited adding first version of freeipa-letsencrypt.sh (fixes #1)
This commit is contained in:
59
README.md
59
README.md
@@ -24,6 +24,9 @@ This repository contains the following scripts:
|
||||
* [freeipa-dns.py](#freeipadns)
|
||||
is a script providing functionality not available in FreeIPA itself to
|
||||
migrate/synchronize and maintain DNS zones in FreeIPA
|
||||
* [freeipa-letsencrypt.sh](#freeipaletsencrypt)
|
||||
is a script to setup and configure Certbot and FreeIPA to request and renew
|
||||
use publicly verifiable Let's Encrypt certificate(s)
|
||||
|
||||
|
||||
<a name=users2freeipa>users2freeipa.py</a>
|
||||
@@ -60,6 +63,14 @@ This will also install the OpenDirectory-specific schema customization, create
|
||||
groups and copy group memberships, copy usuable passwords and ensure that all
|
||||
users have a password (storing generated passwords to ```passwords.txt```)
|
||||
|
||||
Please note that migrating existing passwords from LDAP has limitations, see
|
||||
[this](https://www.freeipa.org/page/NIS_accounts_migration_preserving_Passwords)
|
||||
page on migrating NIS passwords and [this](https://pagure.io/freeipa/issue/4732)
|
||||
issue reported with it. Bottom line is that (at this moment) password migration
|
||||
is flawed and always will require manual action from the user. For this reason
|
||||
the better alternative to set a random password and ask the user to reset the
|
||||
password using the FreeIPA portal makes more sense.
|
||||
|
||||
Before running a production user migration, it is important to have FreeIPA
|
||||
setup and configured correctly so that the right defaults are used for new
|
||||
users. Best is to start with a single user and add that as a stage user (please
|
||||
@@ -160,6 +171,54 @@ for available commands run ```freeipa-dns.py -h``` and to get an overview of
|
||||
the available options for each commmand run ```freeipa-dns.py <command> -h```
|
||||
|
||||
|
||||
<a name=freeipaletsencrypt>freeipa-letsencrypt.sh</a>
|
||||
----------------------------------------------------------------
|
||||
This script will ensure the necessary setup is in place so that Certbot (EFF's
|
||||
certificate request script for Let's Encrypt) will work with FreeIPA for DNS
|
||||
challenges and and instructs it to deploy new certificates for FreeIPA's web
|
||||
interface. Before writing this script I looked at available options, especially
|
||||
[freeipa-letsencrypt](https://github.com/freeipa/freeipa-letsencrypt) and [antevens'](https://github.com/antevens/letsencrypt-freeipa) implementation but
|
||||
decided to take a slightly different approach where Certbot does all the work
|
||||
and the setup script will only ensure that the environment is prepared and that
|
||||
Certbot is initially instructed correctly. This allows to fully tie-in with how
|
||||
Certbot handles renews and use the Certbot package's provided method to schedule
|
||||
these.
|
||||
|
||||
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.
|
||||
|
||||
The script is built to auto-configure but many of the defaults can be overridden
|
||||
by setting one of the following environment variables:
|
||||
|
||||
| Variable | Description | Default value |
|
||||
|-------------|------------------------------------|---------------------------|
|
||||
| CERTNAME | certificate hostname, | host's canonicalname (*) |
|
||||
| DNSALTNAMES | certificate DNS names | host's principalnames (*) |
|
||||
| DOMAIN | Let's Encrypt challenge DNS zone | {DNS name's domain} (**) |
|
||||
| EMAIL | administrator's e-mail address | hostmaster@{domain} |
|
||||
| HOSTNAME | FreeIPA server's hostname | `hostname --fqdn` |
|
||||
| KEYTAB | Let'sEncrypt service's keytab file | /etc/letsencrypt/keytab |
|
||||
| KRB5CCNAME | Kerberos5 cache to use for tickets | automatically determined |
|
||||
| REPLY | when 'y' skip user confirmation | "" |
|
||||
| SERVICE | FreeIPA service for Certbot to use | letsencrypt/canonicalname |
|
||||
| SUDO | command to become root (if needed) | sudo |
|
||||
| TMPDIR | Directory for temporary files | /tmp |
|
||||
|
||||
(*) obtained from the FreeIPA server record looked up based on ${HOSTNAME}
|
||||
(**) this allows to enforce the DNS zone, e.g. host.subdomain in mydomain.tld
|
||||
|
||||
When things change, the script can simply be run again.
|
||||
|
||||
<a name="license">License</a>
|
||||
-----------------------------
|
||||
These scripts, documentation & configration examples are free software: you can
|
||||
|
||||
@@ -378,7 +378,7 @@ def reverseptr(api, args):
|
||||
if currrev == recordname:
|
||||
logger.debug('no update for %s (%s) in %s',
|
||||
reventry, recordname, revzone)
|
||||
elif currrev and not args.overwrite:
|
||||
elif currrev and not args.override:
|
||||
logger.warn('not updating %s (%s) in %s pointing to'
|
||||
' %s', reventry, recordname, revzone, currrev)
|
||||
else:
|
||||
@@ -588,7 +588,7 @@ if __name__ == '__main__':
|
||||
args.func(api, args)
|
||||
exit(0)
|
||||
except DNSException as e:
|
||||
logger.critical("Domain %s cannot be downloaded,%s", domain, e)
|
||||
logger.critical("Domain cannot be downloaded: %s", e)
|
||||
except AuthenticationError:
|
||||
logger.critical("Unable to authenticate to FreeIPA, make sure you have a valid Kerberos ticket!")
|
||||
except PublicError as e:
|
||||
|
||||
128
freeipa-letsencrypt.sh
Executable file
128
freeipa-letsencrypt.sh
Executable file
@@ -0,0 +1,128 @@
|
||||
#!/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=${KRB5CCNAME:-$(klist -l | head -3 | tail -1 | 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:=letsencrypt/$(
|
||||
ipa host-show $HOSTNAME --raw | fgrep "krbcanonicalname: host/" | cut -d/ -f2)}
|
||||
4. Allow letsencrypt host service to manage DNS entries
|
||||
5. Register with Let's encrypt as: ${EMAIL:=hostmaster@${HOSTNAME#*.}}
|
||||
6. Request a Let's Encrypt SSL certificate for: ${CERTNAME:=$(ipa host-show $HOSTNAME --raw | fgrep "krbcanonicalname: host/" | cut -d/ -f2 | cut -d@ -f1)}
|
||||
with DNS Alternative names: ${DNSALTNAMES:=$(ipa host-show $HOSTNAME --raw | fgrep "krbprincipalname: host/" | cut -d/ -f2 | cut -d@ -f1 | paste -sd,)}
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user