Commit 63e71697e235b494630e073cdde40b4692adabc6

Authored by Frederik Lindenaar
1 parent 02d0b225

fixed issue in freeipa-letsencrypt.sh with setting variable defaults

added set-dns-source.sh
updated README.md accordingly
README.md
@@ -19,73 +19,29 @@ General Public License, see [below](#license) @@ -19,73 +19,29 @@ General Public License, see [below](#license)
19 Contents 19 Contents
20 ======== 20 ========
21 This repository contains the following scripts: 21 This repository contains the following scripts:
22 - * [users2freeipa.py](#users2freeipa)  
23 - is a migration script to transfer/synchronize LDAP users to/with FreeIPA  
24 * [freeipa-dns.py](#freeipadns) 22 * [freeipa-dns.py](#freeipadns)
25 is a script providing functionality not available in FreeIPA itself to 23 is a script providing functionality not available in FreeIPA itself to
26 migrate/synchronize and maintain DNS zones in FreeIPA 24 migrate/synchronize and maintain DNS zones in FreeIPA
27 * [freeipa-letsencrypt.sh](#freeipaletsencrypt) 25 * [freeipa-letsencrypt.sh](#freeipaletsencrypt)
28 is a script to setup and configure Certbot and FreeIPA to request and renew 26 is a script to setup and configure Certbot and FreeIPA to request and renew
29 use publicly verifiable Let's Encrypt certificate(s) 27 use publicly verifiable Let's Encrypt certificate(s)
30 -  
31 -  
32 -<a name=users2freeipa>users2freeipa.py</a>  
33 ----------------------------------------------  
34 -This script uses LDAP to obtain users from a MacOS Server (or other LDAP)  
35 -server and synchronizes the results with the users registered in FreeIPA.  
36 -Since it synchronizes data it is safe to run multiple times and users can be  
37 -imported also as stage users initially.  
38 -  
39 -The intent is to migrate user data and to not drag on a legacy setup. For  
40 -this reason, the script will create new user and group IDs and not copy homedir  
41 -and shell information by default. For the IDs, the legacy information can be  
42 -stored in an FreeIPA ID View so it remains available, other items can be copied  
43 -over using command line options. Passwords can be copied-over (if available in  
44 -a usable format), and the script also supports having FreeIPA generate random  
45 -passwords and store these in a file for further processing/sharing with users.  
46 -  
47 -Users can be copied from an existing (generic) LDAP database and a MacOS Server  
48 -OpenDirectory-flavor LDAP server. In this case, additional information (e.g.  
49 -Apple's generatedUID) will be copied over as well. Please note that this does  
50 -require customizing the FreeIPA LDAP schema, which the script will check for  
51 -and can install (option ```-U```). As the setup is modular it should be easy  
52 -to tweak or add other migrations.  
53 -  
54 -By default all users will be migrated/synchronized, but it is also possible to  
55 -limit this to specific user(s) or group(s) or specifically exclude specific  
56 -users or groups. An example to copy all users in the group ```workgroup```  
57 -except ```admin``` from an Apple MacOS OpenDirectory server:  
58 -~~~  
59 -./users2freeipa.py -v -O -U -c "Legacy LDAP" -g workgroup -x admin -G \  
60 - -P -p passwords.txt ldap://ldap.mydomain.tld  
61 -~~~  
62 -This will also install the OpenDirectory-specific schema customization, create  
63 -groups and copy group memberships, copy usuable passwords and ensure that all  
64 -users have a password (storing generated passwords to ```passwords.txt```)  
65 -  
66 -Please note that migrating existing passwords from LDAP has limitations, see  
67 -[this](https://www.freeipa.org/page/NIS_accounts_migration_preserving_Passwords)  
68 -page on migrating NIS passwords and [this](https://pagure.io/freeipa/issue/4732)  
69 -issue reported with it. Bottom line is that (at this moment) password migration  
70 -is flawed and always will require manual action from the user. For this reason  
71 -the better alternative to set a random password and ask the user to reset the  
72 -password using the FreeIPA portal makes more sense.  
73 -  
74 -Before running a production user migration, it is important to have FreeIPA  
75 -setup and configured correctly so that the right defaults are used for new  
76 -users. Best is to start with a single user and add that as a stage user (please  
77 -note that this will not yet assign userIDs, group memberships and a password  
78 -as FreeIPA does not yet support that) and use an ID View to store legacy data.  
79 -  
80 -For all available command-line options, run ```users2freeipa.py -h``` 28 + * [set-dns-source.sh](#setdnssource)
  29 + enforce the source address of outgoing DNS messages using firewalld as work
  30 + around for bind-dyndb-ldap plugin not supporting bind's ```notify-source```
  31 + * [users2freeipa.py](#users2freeipa)
  32 + is a migration script to transfer/synchronize LDAP users to/with FreeIPA
81 33
82 34
83 <a name=freeipadns>freeipa-dns.py</a> 35 <a name=freeipadns>freeipa-dns.py</a>
84 ----------------------------------------------------------------- 36 +-------------------------------------
85 This script provides functionality not provided by FreeIPA to migrate and/or 37 This script provides functionality not provided by FreeIPA to migrate and/or
86 synchronize / maintain DNS data in FreeIPA. Currently the following commands 38 synchronize / maintain DNS data in FreeIPA. Currently the following commands
87 are implemented: 39 are implemented:
88 - * axfr - import/synchronize a DNS zone in FreeIPA using a zone-xfer. 40 + * axfr - synchronize DNS zone(s) using a zone-xfer. Contrary to the suggested
  41 + [migration approach](https://docs.pagure.org/bind-dyndb-ldap/Migration.html)
  42 + this uses the FreeIPA API to migrate or synchronize DNS zones with FreeIPA
  43 + so it can also be used for running things in parallel or gradual migrations.
  44 +
89 for example, to migrate / synchronize fromain ```domain.tld``` from DNS 45 for example, to migrate / synchronize fromain ```domain.tld``` from DNS
90 server ```192.168.1.53``` without checking DNS overlap, issue the command: 46 server ```192.168.1.53``` without checking DNS overlap, issue the command:
91 47
@@ -172,7 +128,7 @@ the available options for each commmand run ```freeipa-dns.py &lt;command&gt; -h``` @@ -172,7 +128,7 @@ the available options for each commmand run ```freeipa-dns.py &lt;command&gt; -h```
172 128
173 129
174 <a name=freeipaletsencrypt>freeipa-letsencrypt.sh</a> 130 <a name=freeipaletsencrypt>freeipa-letsencrypt.sh</a>
175 ----------------------------------------------------------------- 131 +-----------------------------------------------------
176 This script will ensure the necessary setup is in place so that Certbot (EFF's 132 This script will ensure the necessary setup is in place so that Certbot (EFF's
177 certificate request script for Let's Encrypt) will work with FreeIPA for DNS 133 certificate request script for Let's Encrypt) will work with FreeIPA for DNS
178 challenges and and instructs it to deploy new certificates for FreeIPA's web 134 challenges and and instructs it to deploy new certificates for FreeIPA's web
@@ -202,9 +158,9 @@ by setting one of the following environment variables: @@ -202,9 +158,9 @@ by setting one of the following environment variables:
202 158
203 | Variable | Description | Default value | 159 | Variable | Description | Default value |
204 |-------------|------------------------------------|---------------------------| 160 |-------------|------------------------------------|---------------------------|
205 -| CERTNAME | certificate hostname, | host's canonicalname (*) |  
206 -| DNSALTNAMES | certificate DNS names | host's principalnames (*) |  
207 -| DOMAIN | Let's Encrypt challenge DNS zone | {DNS name's domain} (**) | 161 +| CERTNAME | certificate hostname, | host's canonicalname (1) |
  162 +| DNSALTNAMES | certificate DNS names | host's principalnames (1) |
  163 +| DOMAIN | Let's Encrypt challenge DNS zone | {DNS name's domain} (2) |
208 | EMAIL | administrator's e-mail address | hostmaster@{domain} | 164 | EMAIL | administrator's e-mail address | hostmaster@{domain} |
209 | HOSTNAME | FreeIPA server's hostname | `hostname --fqdn` | 165 | HOSTNAME | FreeIPA server's hostname | `hostname --fqdn` |
210 | KEYTAB | Let'sEncrypt service's keytab file | /etc/letsencrypt/keytab | 166 | KEYTAB | Let'sEncrypt service's keytab file | /etc/letsencrypt/keytab |
@@ -214,11 +170,86 @@ by setting one of the following environment variables: @@ -214,11 +170,86 @@ by setting one of the following environment variables:
214 | SUDO | command to become root (if needed) | sudo | 170 | SUDO | command to become root (if needed) | sudo |
215 | TMPDIR | Directory for temporary files | /tmp | 171 | TMPDIR | Directory for temporary files | /tmp |
216 172
217 -(*) obtained from the FreeIPA server record looked up based on ${HOSTNAME}  
218 -(**) this allows to enforce the DNS zone, e.g. host.subdomain in mydomain.tld 173 +(1) obtained from the FreeIPA server record looked up based on ${HOSTNAME}
  174 +(2) this allows to enforce the DNS zone, e.g. host.subdomain in mydomain.tld
219 175
220 When things change, the script can simply be run again. 176 When things change, the script can simply be run again.
221 177
  178 +
  179 +<a name=setdnssource>set-dns-source.sh</a>
  180 +------------------------------------------
  181 +FreeIPA's bind-dyndb-ldap plugin does not support bind's ```notify-source```
  182 +settings and simply uses the main address when sending DNS notifications. This
  183 +breaks multi-homed setups and, in case of IPv6, even causes bind to send NOTIFY
  184 +messages from the temporary IPv6 address, causing slave servers to reject them.
  185 +This script will setup Source NAT in firewalld to enforce the IPv4/IPv6 address
  186 +of outgoing DNS packets to ensure that DNS NOTIFYs messages will use the correct
  187 +source IPv4/IPv6 address. The IPv4/IPv6 address(es) to enforce should either be
  188 +provided in the environment or changed at the top of the script. In case an IPv4
  189 +address is provided, the script can figure out itself which device to use when
  190 +running it, if not this should be provided as well. To install run:
  191 +~~~
  192 +sudo IPV4ADDR=192.168.0.100 IPV6ADDR=none ./set-dns-source.sh install
  193 +~~~
  194 +to remove installed rules, run with the same parameters and parameter 'remove':
  195 +~~~
  196 +sudo IPV4ADDR=192.168.0.100 IPV6ADDR=none ./set-dns-source.sh remove
  197 +~~~
  198 +and to see custom rules run: ```sudo firewall-cmd --direct --get-all-rules```
  199 +
  200 +
  201 +
  202 +<a name=users2freeipa>users2freeipa.py</a>
  203 +------------------------------------------
  204 +This script uses LDAP to obtain users from a MacOS Server (or other LDAP)
  205 +server and synchronizes the results with the users registered in FreeIPA.
  206 +Since it synchronizes data it is safe to run multiple times and users can be
  207 +imported also as stage users initially.
  208 +
  209 +The intent is to migrate user data and to not drag on a legacy setup. For
  210 +this reason, the script will create new user and group IDs and not copy homedir
  211 +and shell information by default. For the IDs, the legacy information can be
  212 +stored in an FreeIPA ID View so it remains available, other items can be copied
  213 +over using command line options. Passwords can be copied-over (if available in
  214 +a usable format), and the script also supports having FreeIPA generate random
  215 +passwords and store these in a file for further processing/sharing with users.
  216 +
  217 +Users can be copied from an existing (generic) LDAP database and a MacOS Server
  218 +OpenDirectory-flavor LDAP server. In this case, additional information (e.g.
  219 +Apple's generatedUID) will be copied over as well. Please note that this does
  220 +require customizing the FreeIPA LDAP schema, which the script will check for
  221 +and can install (option ```-U```). As the setup is modular it should be easy
  222 +to tweak or add other migrations.
  223 +
  224 +By default all users will be migrated/synchronized, but it is also possible to
  225 +limit this to specific user(s) or group(s) or specifically exclude specific
  226 +users or groups. An example to copy all users in the group ```workgroup```
  227 +except ```admin``` from an Apple MacOS OpenDirectory server:
  228 +~~~
  229 +./users2freeipa.py -v -O -U -c "Legacy LDAP" -g workgroup -x admin -G \
  230 + -P -p passwords.txt ldap://ldap.mydomain.tld
  231 +~~~
  232 +This will also install the OpenDirectory-specific schema customization, create
  233 +groups and copy group memberships, copy usuable passwords and ensure that all
  234 +users have a password (storing generated passwords to ```passwords.txt```)
  235 +
  236 +Please note that migrating existing passwords from LDAP has limitations, see
  237 +[this](https://www.freeipa.org/page/NIS_accounts_migration_preserving_Passwords)
  238 +page on migrating NIS passwords and [this](https://pagure.io/freeipa/issue/4732)
  239 +issue reported with it. Bottom line is that (at this moment) password migration
  240 +is flawed and always will require manual action from the user. For this reason
  241 +the better alternative to set a random password and ask the user to reset the
  242 +password using the FreeIPA portal makes more sense.
  243 +
  244 +Before running a production user migration, it is important to have FreeIPA
  245 +setup and configured correctly so that the right defaults are used for new
  246 +users. Best is to start with a single user and add that as a stage user (please
  247 +note that this will not yet assign userIDs, group memberships and a password
  248 +as FreeIPA does not yet support that) and use an ID View to store legacy data.
  249 +
  250 +For all available command-line options, run ```users2freeipa.py -h```
  251 +
  252 +
222 <a name="license">License</a> 253 <a name="license">License</a>
223 ----------------------------- 254 -----------------------------
224 These scripts, documentation & configration examples are free software: you can 255 These scripts, documentation & configration examples are free software: you can
freeipa-letsencrypt.sh
@@ -36,7 +36,13 @@ else @@ -36,7 +36,13 @@ else
36 fi 36 fi
37 37
38 # Set KRB5CCNAME to ensure the current ticket cache will be used 38 # Set KRB5CCNAME to ensure the current ticket cache will be used
39 -KRB5CCNAME=${KRB5CCNAME:-$(klist -l | head -3 | tail -1 | cut -d\ -f2-)} 39 +: ${KRB5CCNAME:=$(klist -l | head -3 | tail -1 | cut -d\ -f2-)}
  40 +
  41 +# Set parameters
  42 +: ${CERTNAME:=$(ipa host-show $HOSTNAME --raw | fgrep "krbcanonicalname: host/" | cut -d/ -f2 | cut -d@ -f1)}
  43 +: ${DNSALTNAMES:=$(ipa host-show $HOSTNAME --raw | fgrep "krbprincipalname: host/" | cut -d/ -f2 | cut -d@ -f1 | paste -sd,)}
  44 +: ${EMAIL:=hostmaster@${HOSTNAME#*.}}
  45 +: ${SERVICE:=letsencrypt/$(ipa host-show $HOSTNAME --raw | fgrep "krbcanonicalname: host/" | cut -d/ -f2)}
40 46
41 # Ensure the user consents with changing his system. 47 # Ensure the user consents with changing his system.
42 if tty > /dev/null; then 48 if tty > /dev/null; then
@@ -46,12 +52,11 @@ use a Let&#39;s Encrypt certificate and will automatically renew that when needed. @@ -46,12 +52,11 @@ use a Let&#39;s Encrypt certificate and will automatically renew that when needed.
46 The following changes will be made for this: 52 The following changes will be made for this:
47 1. Add Let's Encrypt Root and Intermediate CAs as trusted CAs 53 1. Add Let's Encrypt Root and Intermediate CAs as trusted CAs
48 2. Create DNS Administrator role in FreeIPA that can edit any DNS Record 54 2. Create DNS Administrator role in FreeIPA that can edit any DNS Record
49 - 3. Create host service: ${SERVICE:=letsencrypt/$(  
50 -ipa host-show $HOSTNAME --raw | fgrep "krbcanonicalname: host/" | cut -d/ -f2)} 55 + 3. Create host service: $SERVICE
51 4. Allow letsencrypt host service to manage DNS entries 56 4. Allow letsencrypt host service to manage DNS entries
52 - 5. Register with Let's encrypt as: ${EMAIL:=hostmaster@${HOSTNAME#*.}}  
53 - 6. Request a Let's Encrypt SSL certificate for: ${CERTNAME:=$(ipa host-show $HOSTNAME --raw | fgrep "krbcanonicalname: host/" | cut -d/ -f2 | cut -d@ -f1)}  
54 - with DNS Alternative names: ${DNSALTNAMES:=$(ipa host-show $HOSTNAME --raw | fgrep "krbprincipalname: host/" | cut -d/ -f2 | cut -d@ -f1 | paste -sd,)} 57 + 5. Register with Let's encrypt as: $EMAIL
  58 + 6. Request a Let's Encrypt SSL certificate for: $CERTNAME
  59 + with DNS Alternative names: $DNSALTNAMES
55 7. install the Let's Encrypt certificate in apache as host SSL certificate, 60 7. install the Let's Encrypt certificate in apache as host SSL certificate,
56 storing renewal config in: /etc/letsencrypt/renewal/$HOSTNAME.conf 61 storing renewal config in: /etc/letsencrypt/renewal/$HOSTNAME.conf
57 8. configure the Fedora Certbot renew timer so that certbot is run daily to 62 8. configure the Fedora Certbot renew timer so that certbot is run daily to
@@ -121,7 +126,7 @@ $SUDO systemctl enable --now certbot-renew.timer @@ -121,7 +126,7 @@ $SUDO systemctl enable --now certbot-renew.timer
121 126
122 cat << EOT 127 cat << EOT
123 128
124 -FreeIPA was successfully setup to use a Let\'s Encrypt certificate for its web 129 +FreeIPA was successfully setup to use a Let's Encrypt certificate for its web
125 interface. This certificate will be renewed automatically when needed. 130 interface. This certificate will be renewed automatically when needed.
126 131
127 EOT 132 EOT
set-dns-source.sh 0 → 100755
  1 +#!/bin/bash -e
  2 +#
  3 +# set-dns-source.sh - Setup Source NAT in firewalld for outgoing DNS traffic
  4 +#
  5 +# Version 1.0, latest version, documentation and bugtracker available at:
  6 +# https://gitlab.lindenaar.net/scripts/freeipa
  7 +#
  8 +# Copyright (c) 2018 Frederik Lindenaar
  9 +#
  10 +# This script is free software: you can redistribute and/or modify it under the
  11 +# terms of version 3 of the GNU General Public License as published by the Free
  12 +# Software Foundation, or (at your option) any later version of the license.
  13 +#
  14 +# This script is distributed in the hope that it will be useful but WITHOUT ANY
  15 +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  16 +# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  17 +#
  18 +# You should have received a copy of the GNU General Public License along with
  19 +# this program. If not, visit <http://www.gnu.org/licenses/> to download it.
  20 +
  21 +case $1 in
  22 + install) CMD=add
  23 + ;;
  24 + remove) CMD=remove
  25 + ;;
  26 + *) echo "usage: $0 <install | remove>"
  27 + exit 1
  28 +esac
  29 +
  30 +IPV4ADDR=${IPV4ADDR:?Please provide an IPv4 address or set to 'none'}
  31 +IPV6ADDR=${IPV6ADDR:?Please provide an IPv6 address or set to 'none'}
  32 +
  33 +DEV=${DEV:=$( /usr/sbin/ip route | fgrep ${IPV4ADDR:?No IPv4 address provided, please set device manually} | cut -d\ -f3 )}
  34 +: ${DEV:?No route found for $IPV4ADDR, please check config or set device manually}
  35 +
  36 +# inspired by https://blog.sebastien.raveau.name/2009/04/per-process-routing.html
  37 +# and https://unix.stackexchange.com/questions/389756/how-to-use-snat-with-firewalld-vs-masq
  38 +
  39 +for PROTO in ipv4 ipv6; do
  40 + [ "$PROTO" == ipv6 ] && ADDR="$IPV6ADDR" || ADDR="$IPV4ADDR"
  41 + if [ -n "$ADDR" -a "$ADDR" != none ]; then
  42 + for MODE in "" --permanent; do
  43 + firewall-cmd $MODE --direct --$CMD-rule $PROTO mangle OUTPUT 0 -m owner --uid-owner named -j MARK --set-mark 53
  44 + firewall-cmd $MODE --direct --$CMD-rule $PROTO nat POSTROUTING 0 -o $DEV -m mark --mark 53 -j SNAT --to-source $ADDR
  45 + done
  46 + fi
  47 +done
  48 +