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:
136
README.md
136
README.md
@@ -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
|
||||
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
|
||||
[GitLab instance](https://gitlab.lindenaar.net/scripts/freeipa)
|
||||
|
||||
Copyright (c) 2018 Frederik Lindenaar. free for distribution under the GNU
|
||||
General Public License, see [below](#license)
|
||||
Copyright (c) 2018 - 2019 Frederik Lindenaar. free for distribution under the
|
||||
GNU General Public License, see [below](#license)
|
||||
|
||||
Contents
|
||||
========
|
||||
@@ -30,6 +36,12 @@ This repository contains the following scripts:
|
||||
around for bind-dyndb-ldap plugin not supporting bind's ```notify-source```
|
||||
* [users2freeipa.py](#users2freeipa)
|
||||
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>
|
||||
@@ -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
|
||||
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
|
||||
[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
|
||||
@@ -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```
|
||||
|
||||
|
||||
<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 service’s 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>
|
||||
-----------------------------
|
||||
These scripts, documentation & configration examples are free software: you can
|
||||
|
||||
75
freeipa-samba-user.sh
Executable file
75
freeipa-samba-user.sh
Executable 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
83
freeipa-service-ntlm.sh
Executable 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
81
freeipa-service-password.sh
Executable 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
|
||||
|
||||
Reference in New Issue
Block a user