Archived
1
0

Added 3 additional scripts (refer to README.md for what they do)

- freeipa-samba-user.sh
  - freeipa-service-ntlm.sh
  - freeipa-service-password.sh
This commit is contained in:
2019-07-19 18:18:02 +02:00
parent 63e71697e2
commit 3470ed2dcf
4 changed files with 373 additions and 4 deletions

136
README.md
View File

@@ -10,11 +10,17 @@ between an existing situation and FreeIPA and are safe to run multiple times.
As side-effect, this also makes them suitable to support a gradual migration As side-effect, this also makes them suitable to support a gradual migration
over time (where a source system is still in production until final cut-over) over time (where a source system is still in production until final cut-over)
Please note that these scripts are intended to run on the FreeIPA server and
require a valid (admin) kerberos ticket, which can be obtained with:
```
kinit admin
```
The latest versions, documentation and a bug tracker are available on my The latest versions, documentation and a bug tracker are available on my
[GitLab instance](https://gitlab.lindenaar.net/scripts/freeipa) [GitLab instance](https://gitlab.lindenaar.net/scripts/freeipa)
Copyright (c) 2018 Frederik Lindenaar. free for distribution under the GNU Copyright (c) 2018 - 2019 Frederik Lindenaar. free for distribution under the
General Public License, see [below](#license) GNU General Public License, see [below](#license)
Contents Contents
======== ========
@@ -30,6 +36,12 @@ This repository contains the following scripts:
around for bind-dyndb-ldap plugin not supporting bind's ```notify-source``` around for bind-dyndb-ldap plugin not supporting bind's ```notify-source```
* [users2freeipa.py](#users2freeipa) * [users2freeipa.py](#users2freeipa)
is a migration script to transfer/synchronize LDAP users to/with FreeIPA is a migration script to transfer/synchronize LDAP users to/with FreeIPA
* [freeipa-service-password.sh](#freeipaservicepassword)
is a script to create a service account and (re)set it's password
* [freeipa-service-ntlm.sh](#freeipaservicentlm)
is a script to grant a service account access to NTLM password attributes
* [freeipa-samba-user.sh](freeipasambauser)
is a script to extend users to a sambaSAMAccount for Samba compatibility
<a name=freeipadns>freeipa-dns.py</a> <a name=freeipadns>freeipa-dns.py</a>
@@ -133,7 +145,8 @@ 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 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 challenges and and instructs it to deploy new certificates for FreeIPA's web
interface. Before writing this script I looked at available options, especially 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 [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 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 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 is initially instructed correctly. This allows to fully tie-in with how
@@ -250,6 +263,123 @@ as FreeIPA does not yet support that) and use an ID View to store legacy data.
For all available command-line options, run ```users2freeipa.py -h``` For all available command-line options, run ```users2freeipa.py -h```
<a name=freeipaservicepassword>freeipa-service-password.sh</a>
--------------------------------------------------------------
This script sets up a service under a host (creating both if needed) so that it
can use an LDAP simple bind for authentication. Although it is straightforward
to setup a host and service account in FreeIPA using the web interface, this
will not allow it to perform an LDAP simple bind (without requiring Kerberos).
For this, a direct change to the LDAP database is required to extend the service
principal object and make it an ```simpleSecurityObject``` with a password. This
script accepts a hostname and one or more services and should be run like:
~~~
./freeipa-service-password.sh <hostname> <service> [<service>]
~~~
As it always sets the password this script can be used for initial setup as well
as a reset of a service password. It performs the following actions:
* Creates the host in FreeIPA (if it does not exists)
When creating a new host it scans its SSH key and stores this in FreeIPA
* Creates each service under the host in FreeIPA (if it does not exists)
* (Re)sets each services LDAP password to a long generated random password
When done it prints the services bind DN and generated password for later use.
<a name=freeipaservicentlm>freeipa-service-ntlm.sh</a>
------------------------------------------------------
This script grants a service under a host access to the LDAP attributes required
to perform NLTM authentication. It sets up the necessary privilege, permission
and a role to grant the rights (if necessary) and then assigns the role to the
service on the host as specified on the command line. for this to work, Active
Directory domain trust support must have been enabled with the command:
~~~
sudo ipa-adtrust-install --add-sid
~~~
(the ```--addsid``` parameter is required to convert existing users).
Please note that for the necessary attributes to become available, users *must*
change their password after enabling Active Directoy domain support as FreeIPA
only maintains the necessary attributes after the user object has been modified.
Running this command will make the ```ipNTHash``` attribute available with the
necessary hash to perform NTLM authentication. Depending on whether the client
implementation supports mapping the attribute it is sufficient to configure it
to use this attribute or require to migrate users to the Samba schema with
[freeipa-samba-user.sh](freeipasambauser). To use the script execute:
~~~
./freeipa-service-ntlm.sh <hostname> <service> [<service>]
~~~
The specified service principals must already exist (they can be created using
[freeipa-service-password.sh](#freeipaservicepassword) or manually).
The script is built to auto-configure though some settings can be overridden by
setting one of the following environment variables:
| Variable | Description | Default value |
|-----------|-------------------------|----------------------------------------|
| HOST | Service host hostname | 1st command line parameter |
| HOSTNAME | FreeIPA server hostname | `hostname --fqdn` |
| PERM_NAME | Name of permission | Read Samba NTLM RC4 Password Hash attribute |
| PRIV_NAME | Name of privilege | Samba (NTLM) RC4 Password Hash Access |
| ROLE_NAME | Name of role | Samba/NTLM Authenticator |
The description of the privilege / role creates can be changed through:
| Variable | Default value |
|----------------|-------------------------------------------------------------|
|PRIV_DESCRIPTION|Perform Samba NTLM authentication using the RC4 password Hash|
|ROLE_DESCRIPTION|Perform Samba (NTLM) Authentication using the RC4 Password hash|
<a name=freeipasambauser>freeipa-samba-user.sh</a>
--------------------------------------------------
This script adds the ```sambaSAMAccount``` objectclass to specified users so
that they can with Samba / NTLM. For everything to work, the Samba server must
login with a service account that has a simple password (setup with
[freeipa-service-password.sh](#freeipaservicepassword)) with access to the NTLM
password attributes (setup with [freeipa-service-ntlm.sh](#freeipaservicentlm)).
This script was written to support integration with Synology DSM (see also this
[blog post](https://frederik.lindenaar.nl/2019/07/14/integrating-synology-ds-with-freeipa.html))
but should also work for other Samba servers (please raise an issue in case it
doesn't work). I found that FreeIPA will maintain and expose required attributes
for NTLM authentication (```sambaNTPassword``` and ```sambaPwdLastSet```) when
Active Directory domain trust support has been enabled with the command:
~~~
sudo ipa-adtrust-install --add-sid
~~~
(the ```--addsid``` parameter is required to convert existing users).
To use the script to migrate all users (except admin) run (the backslash is
needed to avoid shell expansion of * as parameter):
~~~
./freeipa-service-password.sh \*
~~~
Besides a single * the script also accepts the login of one or more users to
migrate as parameter. To explicitly migrate admin - excluded with * - run:
~~~
./freeipa-samba-user.sh admin
~~~
The script will only migrate users that are not yet a ```sambaSAMAccount``` so
it can be run safely multiple times or at set intervals from cron (additional
work is required to make that work though as it will need a valid Kerberos
ticket from a keytab file for that).
Please note that for the necessary attributes to become available, users *must*
change their password after being converted ```sambaSAMAccount``` as FreeIPA
only maintains the necessary attributes after the user object has been modified.
The script is built to auto-configure though some settings can be overridden by
setting one of the following environment variables:
| Variable | Description | Default value |
|-------------|------------------------------------|---------------------------|
| HOST | Service host hostname | 1st command line parameter|
| HOSTNAME | FreeIPA server's hostname | `hostname --fqdn` |
| SAMBADOMAIN | Samba (Windows) domain name | FreeIPA Kerberos realm |
<a name="license">License</a> <a name="license">License</a>
----------------------------- -----------------------------
These scripts, documentation & configration examples are free software: you can These scripts, documentation & configration examples are free software: you can

75
freeipa-samba-user.sh Executable file
View File

@@ -0,0 +1,75 @@
#!/bin/bash -e
#
# freeipa-samba-user.sh - extend existing user(s) with sambaSAMAccount
#
# Version 1.0, latest version, documentation and bugtracker available at:
# https://gitlab.lindenaar.net/scripts/freeipa
#
# Copyright (c) 2019 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.
die() { echo $* >&2; exit 1; }
# Exit if hostname not provided
if [ $# -lt 1 ]; then
die "Usage: `basename $0` <user> [<user> ...]"
fi
# Sanity checks, ensure we have a valid Kerberos ticket and run on FreeIPA server
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"
fi
# Generate the LDAP User filter, !admin if parameter is * else a list of users
if [ $# == 1 -a "$1" == "*" ]; then
USERFILTER='(!(uid=admin))'
else
USERS="$*"
USERFILTER="(|(uid=${USERS// /)(uid=}))"
fi
# Lookup the Samba Domain - equal to the Kerberos REALM by default
: ${SAMBADOMAIN:=$(ipa host-show $HOSTNAME --raw | fgrep "krbcanonicalname: host/" | cut -d@ -f2)}
# Lookup the users not yet converted and process each of them
declare -A params=( )
ldapsearch -QLLL "(&${USERFILTER}(objectClass=ipantuserattrs)(!(objectClass=sambaSamAccount)))" dn uid ipaNTSecurityIdentifier | while read key value; do
# If we're at an empty line it's the end of the record, perform the change
if [ -z "$key" ]; then
if ldapmodify -Q > /dev/null 2>&1 <<EOLDIF; then
dn: ${params[dn]}
changetype: modify
add: objectClass
objectClass: sambaSamAccount
-
add: sambaSID
sambaSID: ${params[ipaNTSecurityIdentifier]}
-
add: sambaAcctFlags
sambaAcctFlags: [U ]
-
add: sambaDomainName
sambaDomainName: ${SAMBADOMAIN}
EOLDIF
echo "successfully updated user ${params[uid]}"
else
die "failed to update user ${params[uid]}, aborting!"
fi
declare -A params=( )
else # we got another attibute, store it for later processing
params[${key/:/}]="$value"
fi
done

83
freeipa-service-ntlm.sh Executable file
View File

@@ -0,0 +1,83 @@
#!/bin/bash -e
#
# freeipa-service-ntlm.sh - grant host service access to NTLM Password Hash
#
# Version 1.0, latest version, documentation and bugtracker available at:
# https://gitlab.lindenaar.net/scripts/freeipa
#
# Copyright (c) 2019 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.
die() { echo $* >&2; exit 1; }
# Exit if hostname not provided
if [ $# -lt 2 ]; then
die "Usage: `basename $0` <hostname> <service> [<service> ...]"
fi
# Sanity checks, ensure we have a valid Kerberos ticket and run on FreeIPA server
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"
fi
# Set parameters
: ${HOST:=$1}
shift
: ${ROLE_NAME:=Samba/NTLM Authenticator}
: ${ROLE_DESCRIPTION:=Perform Samba (NTLM) Authentication using the RC4 Password hash}
: ${PRIV_NAME:=Samba (NTLM) RC4 Password Hash Access}
: ${PRIV_DESCRIPTION:=Perform Samba NTLM authentication using the RC4 password Hash}
: ${PERM_NAME:=Read Samba NTLM RC4 Password Hash attribute}
if ! ipa host-show "$HOST" > /dev/null 2>&1; then
die "host $HOST does not exist, aborting!"
fi
if ipa role-add "$ROLE_NAME" --desc="$ROLE_DESCRIPTION" > /dev/null 2>&1; then
echo created role $ROLE_NAME
if ipa privilege-add "$PRIV_NAME" --desc="$PRIV_DESCRIPTION" > /dev/null 2>&1; then
echo created privilege $PRIV_NAME
if ipa permission-add "$PERM_NAME" --attrs=sambaNTPassword --attrs=sambaPwdLastSet --attrs=sambaSID --attrs=sambaAcctFlags --attrs=sambaDomainName --type=user --right=read --right=compare > /dev/null 2>&1; then
echo created permission $PERM_NAME
else
echo permission $PERM_NAME exists
fi
if ! ipa privilege-add-permission "$PRIV_NAME" --permissions="$PERM_NAME" > /dev/null 2>&1; then
die "adding permission to privileges failed, aborting!"
fi
else
echo privilege $PRIV_NAME exists
fi
if ! ipa role-add-privilege "$ROLE_NAME" --privileges="$PRIV_NAME" > /dev/null 2>&1; then
die "adding privilege to role failed, aborting!"
fi
fi
for service in $*
do
if ipa service-show "$service/$HOST" > /dev/null 2>&1; then
if ipa role-add-member "$ROLE_NAME" --services="$service/$HOST" > /dev/null 2>&1; then
echo granted service $service/$HOST the role $ROLE_NAME
else
echo service $service/$HOST already had role $ROLE_NAME
fi
else
echo "service $service/$HOST does not exist, skipping"
fi
done

81
freeipa-service-password.sh Executable file
View File

@@ -0,0 +1,81 @@
#!/bin/bash -e
#
# freeipa-service-password.sh - add/set host service login password
#
# Version 1.0, latest version, documentation and bugtracker available at:
# https://gitlab.lindenaar.net/scripts/freeipa
#
# Copyright (c) 2019 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.
die() { echo $* >&2; exit 1; }
# Exit if hostname not provided
if [ $# -lt 2 ]; then
die "Usage: `basename $0` <hostname> <service> [<service> ...]"
fi
# Sanity checks, ensure we have a valid Kerberos ticket and run on FreeIPA server
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"
fi
# Set parameters from command line
: ${HOST:=$1}
shift
if ! ipa host-show "$HOST" > /dev/null 2>&1; then
echo Fetching information for $HOST
SSHKEYS=($(ssh-keyscan $HOST 2>/dev/null | cut -f2- -d\ | sed "s/\(.*\)/--sshpubkey='\1'/"))
echo Creating host $HOST
eval ipa host-add "$HOST" ${SSHKEYS[@]}
eval ipa host-add-principal "$HOST" $HOSTALIASES
else
echo host $HOST exists
fi
for service in $*
do
if ipa service-add "$service/$HOST" > /dev/null 2>&1; then
echo Created service $service/$HOST
else
echo service $service/$HOST exists
fi
service_binddn=$(ipa service-show "$service/$HOST" --raw --all | fgrep " dn: " | cut -f2 -d: | tr -d \ )
echo Service Bind DN: $service_binddn
service_bindpw=$(pwmake 128)
if ipa service-show "$service/$HOST" --all --raw | fgrep "objectClass:" | fgrep -q "simpleSecurityObject" > /dev/null 2>&1; then
echo resetting password to generated password: $service_bindpw
ldapmodify -Q > /dev/null 2>&1 <<EOLDIF
dn: $service_binddn
changetype: modify
replace: userPassword
userPassword: $service_bindpw
EOLDIF
else
echo Enabled login with generated password: $service_bindpw
ldapmodify -Q > /dev/null 2>&1 <<EOLDIF
dn: $service_binddn
changetype: modify
add: objectClass
objectClass: simpleSecurityObject
-
add: userPassword
userPassword: $service_bindpw
EOLDIF
fi
done