Imported Upstream version 4.8.10
This commit is contained in:
176
doc/designs/adtrust/oneway-trust-with-shared-secret.md
Normal file
176
doc/designs/adtrust/oneway-trust-with-shared-secret.md
Normal file
@@ -0,0 +1,176 @@
|
||||
# One-way trust with shared secret
|
||||
|
||||
## Overview
|
||||
|
||||
FreeIPA does support trust to an Active Directory forest. The trust can be
|
||||
established using administrative credentials from the forest root domain or
|
||||
using a so-called shared secret. In the latter case no administrative access is
|
||||
given to the remote side of the trust and each administrator performs their
|
||||
configuration separately: FreeIPA administrator configures IPA side, Active
|
||||
Directory administrator adds IPA forest as a trusted one on the Active
|
||||
Directory side.
|
||||
|
||||
For trust to be active, one needs to validate it. Validation process includes a
|
||||
sequences of DCE RPC calls that force a domain controller on the trusted side
|
||||
to establish a so-called "secure channel" to a remote domain controller in the
|
||||
trusting domain. This is an administrative operation and requires
|
||||
administrative privileges to activate. If trust was established using a shared
|
||||
secret, IPA side will lack ability to initiate a validation process.
|
||||
|
||||
At the same time, FreeIPA 4.6 or earlier versions do not include functionality
|
||||
to allow a remote validation from Active Directory to happen before trust
|
||||
objects are created and SSSD can retrieve information from the Active Directory
|
||||
side. Unfortunately, the latter is not possible until trust is validated.
|
||||
|
||||
The purpose of this design is to extend FreeIPA setup to allow trust validation
|
||||
to be initiated from Windows UI in case a shared secret is used to create a
|
||||
trust agreement.
|
||||
|
||||
## Use Cases
|
||||
|
||||
As a FreeIPA administrator, I'd like to establish a trust between an Active
|
||||
Directory forest and a FreeIPA deployment using a shared secret. As FreeIPA
|
||||
administrator, I have no administrative access to Active Directory and would
|
||||
like to delegate the operation to create trust on Active Directory side to my
|
||||
counterpart in Active Directory forest.
|
||||
|
||||
|
||||
## How to Use
|
||||
|
||||
|
||||
1. Establish a one-way trust with a shared secret on IPA side:
|
||||
`ipa trust-add <ad-domain> --shared-secret`
|
||||
|
||||
2. On Windows side, open Active Directory Domain and Trusts tool
|
||||
* Open properties for the Windows forest
|
||||
* Choose 'Trusts' tab and press 'New trust' button there
|
||||
* Navigate through the trust wizard by entering:
|
||||
* IPA forest name, then 'next'
|
||||
* Choose 'Forest trust' on the Trust Type page
|
||||
* Choose 'One-way: incoming' on the Direction of Trust page
|
||||
* Choose 'This domain only' on the Sides of Trust page
|
||||
* Enter the same shared secret one was using in step (1) with 'ipa trust-add'
|
||||
* Complete trust wizard
|
||||
|
||||
3. Going back to the trust properties, one can now validate the trust from Windows side.
|
||||
|
||||
One limitation is that it is not possible to retrieve forest trust information
|
||||
about IPA realm by Active Directory domain controllers due to the fact that
|
||||
Samba configuration used by IPA does not support a remote query for this
|
||||
information. It is only available when Samba is used in Samba AD configuration.
|
||||
|
||||
TODO: check whether it is possible to force to set forest trust information
|
||||
from IPA side after both sides of trust are were configured.
|
||||
|
||||
## Design
|
||||
|
||||
There are two important parts of the solution. On IPA side, there is a module
|
||||
to allow Samba to look up trusted domains and user/group information in IPA
|
||||
LDAP. On the other side, there is support for POSIX identities of trusted
|
||||
domain objects in SSSD.
|
||||
|
||||
### FreeIPA module for Samba passdb interface
|
||||
|
||||
FreeIPA provides a special module for Samba, `ipasam`, that looks up
|
||||
information about trusted domains and user/group in FreeIPA LDAP. The module
|
||||
also maintains trust-related information when trust is created via DCE RPC
|
||||
interfaces.
|
||||
|
||||
When trust is created, `ipasam` module needs to create a set of Kerberos
|
||||
principals to allow Kerberos KDC to issue cross-realm ticket granting tickets.
|
||||
These principals will have the same keys as trusted domain objects on Active
|
||||
Directory level.
|
||||
|
||||
When a secure channel is established between two domain controllers from
|
||||
separate trusted domains, both DCs rely on the trusted domain object account
|
||||
credentials to be the same on both sides. However, since Samba has to perform
|
||||
SMB to POSIX translation when running in POSIX environment, it also needs to
|
||||
have a POSIX identity associated with the trusted domain object account.
|
||||
|
||||
As result, `ipasam` module needs to maintain POSIX attributes for the trusted
|
||||
domain object account, along with Kerberos principals associated with the
|
||||
trust.
|
||||
|
||||
### SSSD
|
||||
|
||||
When Windows successfully authenticates to Samba, Samba needs a POSIX identity
|
||||
to run `smbd` processes as the authenticated 'user'. `smbd` and `winbindd`
|
||||
processes use standard system calls to resolve authenticated user to a system
|
||||
one (`getpwnam_r()`) and if the call fails, whole Windows request is rejected.
|
||||
|
||||
Given that trusted domain object accounts are associated with the cross-realm
|
||||
Kerberos principals, they are located in a special subtree in FreeIPA LDAP:
|
||||
`cn=trusts,$SUFFIX`. However, SSSD does not look by default in this subtree for
|
||||
users. By default, SSSD configuration for user accounts looks in
|
||||
`cn=users,cn=accounts,$SUFFIX` for `id_provider = ipa` and will not be able to
|
||||
see trusted domain object accounts.
|
||||
|
||||
Thus, to allow Windows to successfully validate a one-way shared incoming trust
|
||||
to FreeIPA, SSSD needs to resolve trusted domain object accounts as POSIX users
|
||||
on IPA master side.
|
||||
|
||||
|
||||
## Implementation
|
||||
|
||||
### FreeIPA `ipasam` module
|
||||
|
||||
`ipasam` module needs to create and maintain POSIX identities of the trusted
|
||||
domain object accounts.
|
||||
|
||||
Following objects and their aliases are created and maintained by `ipasam`
|
||||
module. In the description below `REMOTE` means Kerberos realm of the Active
|
||||
Directory forest's root domain (e.g. `AD.EXAMPLE.COM`), `REMOTE-FLAT` is
|
||||
NetBIOS name of the Active Directory forest's root domain (e.g. `AD`).
|
||||
Correspondingly, `LOCAL` means FreeIPA Kerberos realm (e.g. `IPA.EXAMPLE.COM`)
|
||||
and `LOCAL-FLAT` is the NetBIOS name of the FreeIPA primary domain (e.g.
|
||||
`IPA`).
|
||||
|
||||
Principal | Description
|
||||
--------- | -----------
|
||||
krbtgt/REMOTE@LOCAL | Cross-realm principal representing Active Directory forest root domain
|
||||
REMOTE-FLAT$@LOCAL | Trusted domain object account for the Active Directory forest root domain
|
||||
krbtgt/REMOTE-FLAT@LOCAL | Alias to REMOTE-FLAT$ TDO
|
||||
krbtgt/LOCAL@REMOTE | Cross-realm principal representing IPA domain in Active Directory forest to allow crross-realm TGT issuance from IPA KDC side
|
||||
krbtgt/LOCAL-FLAT@REMOTE | Trusted domain object account for IPA domain in Active Directory forest
|
||||
LOCAL-FLAT$@REMOTE | Alias to krbtgt/LOCAL-FLAT@REMOTE
|
||||
|
||||
For inbound trust `ipasam` module creates following principals:
|
||||
* `krbtgt/LOCAL@REMOTE`, enabled by default
|
||||
* `krbtgt/LOCAL-FLAT@REMOTE`, used by SSSD to talk to Active Directory domain
|
||||
controllers, with canonical name set to `krbtgt/LOCAL-FLAT@REMOTE` because
|
||||
Kerberos KDC must use this salt when issuing tickets for this principal. The
|
||||
use of this principal is disabled on IPA side (IPA KDC does not issue tickets
|
||||
in this name) --- we only retrieve a keytab for the principal in SSSD. SSSD
|
||||
retrieves a keytab for this principal using `LOCAL-FLAT$@REMOTE` Principal
|
||||
name.
|
||||
|
||||
For outbound trust `ipasam` module creates following principals:
|
||||
* `krbtgt/REMOTE@LOCAL`, enabled by default.
|
||||
* `REMOTE-FLAT$@LOCAL`, enabled by default. Used by a remote AD DC to
|
||||
authenticate against Samba on IPA master. This principal will have POSIX
|
||||
identity associated.
|
||||
|
||||
|
||||
### SSSD
|
||||
|
||||
In IPA master mode, SSSD needs to start look into `cn=trusts,$SUFFIX` subtree
|
||||
in addition to `cn=users,cn=accounts,$SUFFIX` subtree to find trusted domain
|
||||
object accounts. This can be achieved either by explicitly adding a second
|
||||
search base to `ldap_search_user_base` option in the `[domain/...]` section or
|
||||
by automatically expanding a list of search bases when running in the IPA
|
||||
master mode. The latter is already implemented in SSSD 1.16.3 and 2.1.0 with
|
||||
https://pagure.io/SSSD/sssd/c/14faec9cd9437ef116ae054412d25ec2e820e409
|
||||
|
||||
|
||||
Feature Management
|
||||
------------------
|
||||
|
||||
We already allow to create a shared secret-based trust to Active Directory. No
|
||||
functional change is needed in either Web UI or CLI.
|
||||
|
||||
Upgrade
|
||||
-------
|
||||
|
||||
During upgrade POSIX identities need to be created for existing trust
|
||||
agreements.
|
||||
|
||||
326
doc/designs/adtrust/samba-domain-controller.md
Normal file
326
doc/designs/adtrust/samba-domain-controller.md
Normal file
@@ -0,0 +1,326 @@
|
||||
# Support domain controller for Samba file server as domain member on IPA client
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [Domain controller side configuration overview](#domain-controller-side-configuration-overview)
|
||||
* [Changes required on domain controller](#changes-required-on-domain-controller)
|
||||
* [Notes about unfinished Samba work](#notes-about-unfinished-samba-work)
|
||||
|
||||
|
||||
## Introduction
|
||||
|
||||
[Samba] is a free software that implements various aspects of SMB protocol and
|
||||
Active Directory infrastructure. Apart from the networking file system that SMB
|
||||
is well known for, Samba provides services to resolve user and group identities
|
||||
for resources accessible via SMB. SMB protocol identity model is based on a
|
||||
Windows NT concept of security identifiers (SIDs) and access control lists
|
||||
(ACLs) which is not directly compatible with a concept of identities employed
|
||||
in POSIX environment model. Thus, Samba suite serves as a translation layer
|
||||
between the two environments.
|
||||
|
||||
Active Directory is an extension of Windows NT identity model where identity
|
||||
information is stored in a database exposed to the world via a combination of
|
||||
LDAP and SMB protocols, with authentication provided with both password
|
||||
(NTLMSSP) and Kerberos methods. Systems in Active Directory are organized into
|
||||
logical groups, domains, where some nodes, domain controllers, are used to
|
||||
store domain-specific information and others, domain members, utilize the
|
||||
information via SMB, LDAP, and Kerberos protocols.
|
||||
|
||||
SMB protocol has a mechanism for encapsulating and channeling through itself
|
||||
other types of requests, expressed as an access to "files" over a specialized
|
||||
share `IPC$`. There are multiple interfaces provided by a typical domain
|
||||
controller and domain member servers, most well-known ones are LSA (local
|
||||
security authority, documented in [MS-LSAD] and [MS-LSAT]) and NETLOGON remote
|
||||
protocol (documented in [MS-NRPC]). LSA remote procedure calls are used, among
|
||||
other needs, for retrieving identity information about SIDs and their
|
||||
relationship to other objects. NETLOGON, as its name suggests, is utilized for
|
||||
authentication in a domain environment, across domains, and across forests of
|
||||
domains.
|
||||
|
||||
In a traditional domain member set up, the member machine has no possession of
|
||||
a particular user credentials. Instead, it relies on its own connection to its
|
||||
own domain controller to identify a user and to proxy a user's authentication
|
||||
to the domain controller of the domain a user belongs to. In case a user is
|
||||
performing a remote authentication using Kerberos, a remote system has to
|
||||
present a Kerberos ticket to the domain member's SMB service, like with any
|
||||
other Kerberos services.
|
||||
|
||||
To operate as a domain member in a FreeIPA domain, thus, Samba needs a FreeIPA
|
||||
master to be configured as a domain controller and a FreeIPA client needs to be
|
||||
configured in a specific way to allow Samba to talk to a domain controller. This
|
||||
document overviews a set of implementation tasks to achieve the domain
|
||||
controller operation.
|
||||
|
||||
## Domain controller side configuration overview
|
||||
|
||||
FreeIPA master can be configured to perform as a 'trust controller' with the
|
||||
help of `ipa-adtrust-intall` tool. The tool creates required subtrees and
|
||||
objects in LDAP, configures Samba to use an `ipasam` PASSDB module which knows
|
||||
how to deal with FreeIPA LDAP schema for Samba-specific attributes and supports
|
||||
storing and retrieving information about trusted domains from LDAP. The tool
|
||||
also makes sure certain 389-ds plugins provided by FreeIPA are enabled and
|
||||
initialized.
|
||||
|
||||
As a result of the configuration, Samba considers itself a domain controller
|
||||
for the traditional (Windows NT) domain type. Such traditional domain controller
|
||||
is not capable to serve as a fully-fledged Active Directory domain controller
|
||||
due to few important limitations:
|
||||
|
||||
- Samba traditional domain controller role is not implementing AD DC itself
|
||||
|
||||
- LDAP schema used by FreeIPA is different from Active Directory LDAP schema
|
||||
|
||||
- LDAP directory information tree (DIT) is different from what Active Directory
|
||||
clients expect from an AD DC
|
||||
|
||||
- No Global Catalog service is provided
|
||||
|
||||
Additionally, `ipasam` PASSDB module is not capable to create machine accounts
|
||||
for requests coming from Samba. This means `net rpc join` will not work when
|
||||
issued from FreeIPA domain members. Also, traditional (Windows NT) domain
|
||||
controller role in Samba is not able to create machine accounts on request from
|
||||
`net ads join`, a procedure to join machine to an Active Directory.
|
||||
|
||||
The limitations above are fine for FreeIPA environment because FreeIPA clients
|
||||
perform its own enrollment process via IPA API and a special LDAP control
|
||||
extension.
|
||||
|
||||
When a domain member establishes a secure channel connection to a domain
|
||||
controller, following is considered on the domain controller side:
|
||||
|
||||
- DCE RPC connection is negotiated and authenticated. As part of authentication,
|
||||
either NTLMSSP or Kerberos token is processed and converted into a local NT
|
||||
token.
|
||||
|
||||
- Local NT token represents a remote user (machine account) on the domain
|
||||
controller. The information includes POSIX attributes as well as NT attributes
|
||||
since Samba will spawn a process to handle the connection under local POSIX
|
||||
user identity. Each machine account, therefore, requires associated POSIX
|
||||
attributes.
|
||||
|
||||
- DCE RPC connection from a domain member is authenticated by use of mutually
|
||||
known secret, machine account credentials. Additionally, when Kerberos is in
|
||||
use, DCE RPC packets might be signed with the use of a service ticket to the
|
||||
domain controller's machine account (`host/...` principal in Kerberos) because
|
||||
on Windows systems all other service principals (SPNs) are presented as
|
||||
aliases to the machine account.
|
||||
|
||||
## Changes required on domain controller
|
||||
|
||||
Domain controller configuration is mostly covered already by the
|
||||
`ipa-adtrust-install` installation utility. The only missing part is to make
|
||||
sure Samba has access to the host keytab. The host keytab's content is copied
|
||||
during upgrade process and also is added during initial `ipa-adtrust-install`
|
||||
run.
|
||||
|
||||
The rest of the changes fall into specific parts of FreeIPA configuration.
|
||||
|
||||
### Changes to FreeIPA framework
|
||||
|
||||
A new command is added to the `ipa service` family, `ipa service-add-smb`. This
|
||||
command creates LDAP object that represents `cifs/...` service principal for the
|
||||
domain member. This LDAP object must have a number of attributes assigned that
|
||||
cannot be assigned past creation because otherwise object classes set on the
|
||||
object will not pass through constraint checks.
|
||||
|
||||
The SMB service object needs to have:
|
||||
- POSIX attributes
|
||||
- NT attributes, including `ipaNTSecurityIdentifier`
|
||||
|
||||
`ipaNTSecurityIdentifier` is filled in by the SID generation plugin at the
|
||||
object creation time for SMB service.
|
||||
|
||||
`ipaNTSecurityIdentifier` attribute is a part of `ipaNTUserAttrs` object class
|
||||
for users and SMB services. IPA groups also can contain the attribute via
|
||||
`ipaNTGroupAttrs` object class.
|
||||
|
||||
With the help of the `sidgen` plugin, ipaNTSecurityIdentifier attribute is only
|
||||
added when:
|
||||
- the object has POSIX attributes `uidNumber` and `gidNumber`
|
||||
- the values of those attributes are within 32-bit unsigned integer
|
||||
- the object has any of the following object classes: `ipaIDObject`,
|
||||
`posixAccount`, or `posixGroup`
|
||||
- the object has no `ipaNTSecurityIdentifier` attribute already.
|
||||
|
||||
`sidgen` plugin will add `ipaNTUserAttrs` object class for non-group objects and
|
||||
`ipaNTGroupAttr` for the group object type. A plugin is triggered at an object
|
||||
creation or via an LDAP task. One can trigger task run by running
|
||||
`ipa-adtrust-install --add-sids` on the trust controller.
|
||||
|
||||
LDAP object class `ipaNTUserAttrs` defines few other attributes. These
|
||||
attributes, called below 'SMB attributes', are required by the domain controller
|
||||
to define content of an NT token for an authenticated identity (user or a
|
||||
machine account).
|
||||
|
||||
SMB attributes are:
|
||||
- `ipaNTLogonScript`
|
||||
: Path to a script executed on a Windows system at logon
|
||||
- `ipaNTProfilePath`
|
||||
: Path to a user profile, in UNC format `\\server\share\`
|
||||
- `ipaNTHomeDirectory`
|
||||
: Path to a user's home directory, in UNC format `\\server\share`
|
||||
- `ipaNTHomeDirectoryDrive`
|
||||
: a letter `[A-Z]` for the drive to mount the home directory to on a Windows system
|
||||
|
||||
All SMB attributes require the presence of `ipaNTUserAttrs` object class in the
|
||||
user object LDAP entry. This object class cannot be added without
|
||||
`ipaNTSecurityIdentifier`. Adding SID requires to consume IDs from a range
|
||||
suitable for SIDs and this logic is recorded in the `sidgen` plugin. Thus, until
|
||||
SID is generated, no attributes can be set on the user entry.
|
||||
|
||||
As result of it, SMB attributes are not available at `ipa user-add` or
|
||||
`ipa stageuser-add` level. Instead, it is possible to modify a user object with
|
||||
`ipa user-mod` or `ipa stageuser-mod` commands:
|
||||
|
||||
```
|
||||
$ ipa user-mod --help
|
||||
Usage: ipa [global-options] user-mod LOGIN [options]
|
||||
|
||||
Modify a user.
|
||||
Options:
|
||||
...
|
||||
--smb-logon-script=STR SMB logon script path
|
||||
--smb-profile-path=STR SMB profile path
|
||||
--smb-home-dir=STR SMB Home Directory
|
||||
--smb-home-drive=['A:', 'B:', 'C:', 'D:', 'E:', 'F:', 'G:', 'H:', 'I:', 'J:', 'K:',
|
||||
'L:', 'M:', 'N:', 'O:', 'P:', 'Q:', 'R:', 'S:', 'T:', 'U:', 'V:',
|
||||
'W:', 'X:', 'Y:', 'Z:']
|
||||
SMB Home Directory Drive
|
||||
...
|
||||
|
||||
$ ipa stageuser-mod --help
|
||||
Usage: ipa [global-options] stageuser-mod LOGIN [options]
|
||||
|
||||
Modify a stage user.
|
||||
Options:
|
||||
...
|
||||
--smb-logon-script=STR SMB logon script path
|
||||
--smb-profile-path=STR SMB profile path
|
||||
--smb-home-dir=STR SMB Home Directory
|
||||
--smb-home-drive=['A:', 'B:', 'C:', 'D:', 'E:', 'F:', 'G:', 'H:', 'I:', 'J:', 'K:',
|
||||
'L:', 'M:', 'N:', 'O:', 'P:', 'Q:', 'R:', 'S:', 'T:', 'U:', 'V:',
|
||||
'W:', 'X:', 'Y:', 'Z:']
|
||||
SMB Home Directory Drive
|
||||
...
|
||||
```
|
||||
|
||||
Due to limitations on how SMB attributes can be added, Web UI shows the section
|
||||
"User attributes for SMB services" without any values for those users who have
|
||||
no SID assigned.
|
||||
|
||||
### Changes to LDAP storage
|
||||
|
||||
By default, POSIX attribute can only be searched by LDAP clients in
|
||||
`cn=users,cn=accounts,$basedn` and `cn=groups,cn=accounts,$basedn` subtrees.
|
||||
Since SMB service belongs to `cn=services,cn=accounts,$basedn` subtree, new ACI
|
||||
has to be added.
|
||||
|
||||
```
|
||||
'System: Read POSIX details of the SMB services': {
|
||||
'replaces_global_anonymous_aci': True,
|
||||
'ipapermbindruletype': 'all',
|
||||
'ipapermright': {'read', 'search', 'compare'},
|
||||
'ipapermdefaultattr': {
|
||||
'objectclass', 'cn', 'uid', 'gecos', 'gidnumber',
|
||||
'homedirectory', 'loginshell', 'uidnumber',
|
||||
'ipantsecurityidentifier',
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
SMB attributes for users are now accessible for self-modification and also
|
||||
readable by the members of `cn=adtrust agents,cn=sysaccounts,cn=etc,$basedn`
|
||||
group which contains, among others, service principals of the domain
|
||||
controllers.
|
||||
|
||||
### Changes to LDAP plugins
|
||||
|
||||
As mentioned above, both domain controller and domain member need to know common
|
||||
secret -- the machine account credential of the domain member. For the purpose
|
||||
of [MS-NRPC] section 3.1.4.3.1, it is enough to know RC4-HMAC hash. Given that
|
||||
there is general willingness to not allow access to RC4-HMAC key over Kerberos
|
||||
in contemporary systems, FreeIPA code was changed to explicitly allow generation
|
||||
of RC4-HMAC hash for SMB service only. For users in FreeIPA generation of
|
||||
RC4-HMAC will be disabled.
|
||||
|
||||
Combined with system-wide crypto policy changes in Fedora 30, it means that both
|
||||
in FIPS and non-FIPS environment RC4-HMAC will not be usable as a Kerberos
|
||||
encryption type unless an application explicitly specifies it and RC4-HMAC key
|
||||
exists in the principal's database entry in FreeIPA.
|
||||
|
||||
A consequence of it is that RC4-HMAC hash will not be usable for FreeRADIUS
|
||||
integration because the hashes will be missing from user entries.
|
||||
|
||||
### Changes to Kerberos KDC driver
|
||||
|
||||
Support for recognizing SMB service principals as machine accounts is added to
|
||||
Kerberos KDB driver. For SMB service principal an MS-PAC record is generated.
|
||||
|
||||
### Changes to Samba PASSDB driver
|
||||
|
||||
Support for resolving SIDs to user and group names is added. This is needed to
|
||||
allow Samba domain controller to resolve requests from Samba domain member
|
||||
servers for SID to ID conversion.
|
||||
|
||||
Support for recognizing machine accounts as `ACB_WSTRUS` entry type in PASSDB is
|
||||
added. This is needed to allow Samba domain members to login to Samba domain
|
||||
controller for LSA RPC and Netlogon operations.
|
||||
|
||||
Support is added to recognize machine account names (NetBIOS names plus '$'
|
||||
sign) as machines. Multivalued `uid` attribute in the LDAP object entry is now
|
||||
supported as SMB service objects will have both `cifs/...` and `NetBIOS$` names
|
||||
assigned to `uid` attribute. Samba looks up POSIX entries by using either
|
||||
Kerberos principal name or machine account name depending on a code flow in
|
||||
different parts of the SMB login processing, thus both needs to be supported.
|
||||
|
||||
## Notes about unfinished Samba work
|
||||
|
||||
Since changes on Samba side apply for both domain controller and domain member,
|
||||
unfinished work is reflected in a single place only.
|
||||
|
||||
Below is the current list, most of the entries on it are still open.
|
||||
|
||||
- Samba needs to implement 'net ads offlinejoin' call to allow setting
|
||||
up a machine account and SID without actually joining the machine via
|
||||
DCE RPC (for IPA or VAS or other join types).
|
||||
|
||||
See https://lists.samba.org/archive/samba-technical/2018-November/131274.html
|
||||
for one part that should explain failures with 'did we join?' message in the
|
||||
logs.
|
||||
|
||||
- windbindd daemon attempts to look up list of trusted domains from own domain
|
||||
controller. Samba domain controller, as used in FreeIPA does not implement
|
||||
`netr_DsrEnumerateDomainTrust` call. The situation here is the same as in
|
||||
https://lists.samba.org/archive/samba-technical/2019-May/133662.html which is
|
||||
another call we need to implement to allow Windows side operations.
|
||||
|
||||
```
|
||||
[2019/06/28 04:27:35.699042, 1, pid=31998, effective(0, 0), real(0, 0), class=rpc_cli] ../source3/rpc_client/cli_pipe.c:569(cli_pipe_validate_current_pdu)
|
||||
../source3/rpc_client/cli_pipe.c:569: RPC fault code DCERPC_NCA_S_OP_RNG_ERROR received from host master.ipa.test!
|
||||
[2019/06/28 04:27:35.699065, 10, pid=31998, effective(0, 0), real(0, 0), class=rpc_cli] ../source3/rpc_client/cli_pipe.c:979(rpc_api_pipe_got_pdu)
|
||||
rpc_api_pipe: got frag len of 32 at offset 0: NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE
|
||||
[2019/06/28 04:27:35.699159, 3, pid=31998, effective(0, 0), real(0, 0), class=winbind] ../source3/winbindd/winbindd_ads.c:1391(trusted_domains)
|
||||
ads: trusted_domains
|
||||
[2019/06/28 04:27:35.699191, 1, pid=31998, effective(0, 0), real(0, 0), class=rpc_parse] ../librpc/ndr/ndr.c:471(ndr_print_function_debug)
|
||||
netr_DsrEnumerateDomainTrusts: struct netr_DsrEnumerateDomainTrusts
|
||||
in: struct netr_DsrEnumerateDomainTrusts
|
||||
server_name : *
|
||||
server_name : 'master.ipa.test'
|
||||
trust_flags : 0x00000023 (35)
|
||||
1: NETR_TRUST_FLAG_IN_FOREST
|
||||
1: NETR_TRUST_FLAG_OUTBOUND
|
||||
0: NETR_TRUST_FLAG_TREEROOT
|
||||
0: NETR_TRUST_FLAG_PRIMARY
|
||||
0: NETR_TRUST_FLAG_NATIVE
|
||||
1: NETR_TRUST_FLAG_INBOUND
|
||||
0: NETR_TRUST_FLAG_MIT_KRB5
|
||||
0: NETR_TRUST_FLAG_AES
|
||||
```
|
||||
|
||||
[Samba]: https://www.samba.org/
|
||||
[MS-NRPC]: https://msdn.microsoft.com/en-us/library/cc237008.aspx
|
||||
[MS-LSAD]: https://msdn.microsoft.com/en-us/library/cc234225.aspx
|
||||
[MS-LSAT]: https://msdn.microsoft.com/en-us/library/cc234420.aspx
|
||||
|
||||
|
||||
433
doc/designs/adtrust/samba-domain-member.md
Normal file
433
doc/designs/adtrust/samba-domain-member.md
Normal file
@@ -0,0 +1,433 @@
|
||||
# Support Samba file server as a domain member on IPA client
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [Domain member configuration overview](#domain-member-configuration-overview)
|
||||
* [Domain controller side configuration overview](#domain-controller-side-configuration-overview)
|
||||
* [Changes required on domain member](#changes-required-on-domain-member)
|
||||
* [Example of using Samba file server on IPA client](#example-of-using-samba-file-server-on-ipa-client)
|
||||
|
||||
## Introduction
|
||||
|
||||
[Samba] is a free software that implements various aspects of SMB protocol and
|
||||
Active Directory infrastructure. Apart from the networking file system that SMB
|
||||
is well known for, Samba provides services to resolve user and group identities
|
||||
for resources accessible via SMB. SMB protocol identity model is based on a
|
||||
Windows NT concept of security identifiers (SIDs) and access control lists
|
||||
(ACLs) which is not directly compatible with a concept of identities employed
|
||||
in POSIX environment model. Thus, Samba suite serves as a translation layer
|
||||
between the two environments.
|
||||
|
||||
Active Directory is an extension of Windows NT identity model where identity
|
||||
information is stored in a database exposed to the world via a combination of
|
||||
LDAP and SMB protocols, with authentication provided with both password
|
||||
(NTLMSSP) and Kerberos methods. Systems in Active Directory are organized into
|
||||
logical groups, domains, where some nodes, domain controllers, are used to
|
||||
store domain-specific information and others, domain members, utilize the
|
||||
information via SMB, LDAP, and Kerberos protocols.
|
||||
|
||||
SMB protocol has a mechanism for encapsulating and channeling through itself
|
||||
other types of requests, expressed as an access to "files" over a specialized
|
||||
share `IPC$`. There are multiple interfaces provided by a typical domain
|
||||
controller and domain member servers, most well-known ones are LSA (local
|
||||
security authority, documented in [MS-LSAD] and [MS-LSAT]) and NETLOGON remote
|
||||
protocol (documented in [MS-NRPC]). LSA remote procedure calls are used, among
|
||||
other needs, for retrieving identity information about SIDs and their
|
||||
relationship to other objects. NETLOGON, as its name suggests, is utilized for
|
||||
authentication in a domain environment, across domains, and across forests of
|
||||
domains.
|
||||
|
||||
In a traditional domain member set up, the member machine has no possession of
|
||||
a particular user credentials. Instead, it relies on its own connection to its
|
||||
own domain controller to identify a user and to proxy a user's authentication
|
||||
to the domain controller of the domain a user belongs to. In case a user is
|
||||
performing a remote authentication using Kerberos, a remote system has to
|
||||
present a Kerberos ticket to the domain member's SMB service, like with any
|
||||
other Kerberos services.
|
||||
|
||||
To operate as a domain member in a FreeIPA domain, thus, Samba needs a FreeIPA
|
||||
master to be configured as a domain controller and a FreeIPA client needs to be
|
||||
configured in a specific way to allow Samba to talk to a domain controller.
|
||||
This document overviews a set of implementation tasks to achieve the domain
|
||||
member operation. Most of these tasks are related to FreeIPA components but
|
||||
some of changes required do belong to Samba itself.
|
||||
|
||||
## Domain member configuration overview
|
||||
|
||||
Samba suite, when running as a domain member, starts two daemons:
|
||||
|
||||
- `smbd`, the main process which handles network connections, file system
|
||||
operations, and remote procedure calls like LSA and NETLOGON. Each connection
|
||||
is handled by a separate `smbd` child;
|
||||
|
||||
- `winbindd`, a process to perform identity resolution for all configured and
|
||||
known domains. Active connection to a domain is handled by a separate
|
||||
`winbindd` child. `winbindd` processes connect to domain controllers and
|
||||
perform required LSA and NETLOGON operations against them. Normally,
|
||||
authentication of a user from a trusted domain is delegated to the domain
|
||||
member's own domain controller which then forwards it further.
|
||||
|
||||
Both `smbd` and `winbindd` daemons rely on a number of pluggable components to
|
||||
abstract out various aspects of their operations. For `smbd`, there are
|
||||
pluggable modules to represent file system operations. It also uses so-called
|
||||
PASSDB interface to convert SIDs to POSIX identities and back --- this
|
||||
interface might be optional on a domain member. In some special cases `smbd`
|
||||
also directly resolves a name of a user associated with the authenticated
|
||||
connection using standard POSIX API for name resolution (getpwnam() and similar
|
||||
calls). All other identity resolution operations it delegates to `winbindd`.
|
||||
|
||||
`winbindd` uses a set of identity mapping modules collectively called 'idmap
|
||||
modules' in Samba terminology. Each `idmap` module represents a strategy to map
|
||||
SIDs to corresponding POSIX IDs. Since SID name space in Active Directory is
|
||||
common for all kind of objects and POSIX ID name space is separate for users and
|
||||
groups, with both POSIX ID name spaces being smaller than a common SID name
|
||||
space, there exist multiple approaches to perform the translation. A choice of a
|
||||
translation method is tightly connected with a specific deployment
|
||||
configuration. ID mapping module should be coordinated with a PASSDB module (if
|
||||
one is defined) and how an operating system represents the POSIX users and
|
||||
groups.
|
||||
|
||||
To communicate with its domain controller, Samba needs to know own machine
|
||||
account information. Machine account is an account in Active Directory that has
|
||||
its name derived from a NetBIOS machine name (due to Windows NT past) post-fixed
|
||||
with a `$` sign, e.g. `MY-MACHINE$`. Password for the machine account is the
|
||||
same as the one used to derive Kerberos keys for the `host/..` and `cifs/..`
|
||||
principals of the same host. In Active Directory all Kerberos principals
|
||||
associated with the host (service principal names, SPNs) share the same Kerberos
|
||||
keys. Thus, Samba needs to known a clear text password for the machine account
|
||||
and it can derive all Kerberos keys for itself based on that knowledge. The
|
||||
clear text password knowledge is also important for the case of machine account
|
||||
password rotation.
|
||||
|
||||
The knowledge of the machine account password is recorded in a special
|
||||
database, `secrets.tdb`, during the process of a machine join to the domain.
|
||||
For FreeIPA client the join process is different from the one Samba uses for
|
||||
Active Directory, thus we need to seed the machine account password separately
|
||||
to enrolling FreeIPA client. Note that FreeIPA machine enrollment does not
|
||||
allow to share clear text machine account password as it is not recorded
|
||||
anywhere.
|
||||
|
||||
## Domain controller side configuration overview
|
||||
|
||||
See [samba-domain-controller] for the details of how Samba domain controller is
|
||||
set up and configured in FreeIPA.
|
||||
|
||||
## Changes required on domain member
|
||||
|
||||
In order to configure the domain member part of Samba suite, following steps
|
||||
need to be preformed. These steps are implemented as an installer utility
|
||||
`ipa-client-samba` and are provided here for documentation purpose only.
|
||||
|
||||
Assumptions:
|
||||
|
||||
* At least one of IPA masters is configured as a trust controller using
|
||||
`ipa-adtrust-install`. This is required to enable a hybrid SMB domain where
|
||||
Samba domain controller would understand Samba domain members enrolled via
|
||||
IPA tools but will not be able to enroll them any other way.
|
||||
|
||||
* A client host is enrolled into IPA, with a fully-qualified hostname,
|
||||
`${hostname}`. Additional elements that will be referred to below:
|
||||
|
||||
`${realm}`
|
||||
: IPA domain's realm
|
||||
|
||||
`${netbios_name}`
|
||||
: NetBIOS name of a domain, whether it is IPA or a trusted Active Directory domain
|
||||
|
||||
`${machine_name}`
|
||||
: NetBIOS name of the client where Samba domain member is being deployed
|
||||
|
||||
Next steps should be performed on the client itself. With the support for Samba
|
||||
domain member enabled, IPA masters allow creation of the required records with
|
||||
the host credentials (`host/${hostname}`).
|
||||
|
||||
```
|
||||
# kinit -k
|
||||
```
|
||||
|
||||
1. Retrieve information about Security Identifier and NetBIOS name of the IPA
|
||||
domain:
|
||||
|
||||
```
|
||||
# kinit -k
|
||||
# ipa trustconfig-show --raw
|
||||
cn: ipa.realm
|
||||
ipantsecurityidentifier: S-1-5-21-570121326-3336757064-1157332047
|
||||
ipantflatname: ipa
|
||||
ipantdomainguid: be06e132-876a-4f9c-aed4-ef2dc1de8118
|
||||
ipantfallbackprimarygroup: cn=Default SMB Group,cn=groups,cn=accounts,dc=ipa,dc=realm
|
||||
```
|
||||
|
||||
In the output above,
|
||||
|
||||
`cn`
|
||||
: IPA domain's realm, `${realm}`, in lower case
|
||||
|
||||
`ipantsecurityidentifier`
|
||||
: IPA domain's SID (security identifier)
|
||||
|
||||
`ipaflatname`
|
||||
: IPA domain's NetBIOS name, `${netbios_name}, also known as the flat name in Active Directory
|
||||
|
||||
`ipantdomainguid`
|
||||
: IPA domain's globally unique identifier (GUID)
|
||||
|
||||
2. Retrieve ID range information for the IPA domain and other trusted domains:
|
||||
|
||||
```
|
||||
# ipa idrange-find --raw
|
||||
----------------
|
||||
2 ranges matched
|
||||
----------------
|
||||
cn: AD.DOMAIN_id_range
|
||||
ipabaseid: 967000000
|
||||
ipaidrangesize: 200000
|
||||
ipabaserid: 0
|
||||
ipanttrusteddomainsid: S-1-5-21-1356309095-650748730-1613512775
|
||||
iparangetype: ipa-ad-trust
|
||||
|
||||
cn: IPA.REALM_id_range
|
||||
ipabaseid: 1536000000
|
||||
ipaidrangesize: 200000
|
||||
ipabaserid: 1000
|
||||
ipasecondarybaserid: 100000000
|
||||
iparangetype: ipa-local
|
||||
----------------------------
|
||||
Number of entries returned 2
|
||||
----------------------------
|
||||
```
|
||||
|
||||
From the output above, `ipabaseid` and `ipaidrangesize` attributes are used
|
||||
to define ranges for Samba configuration. Samba requires to have IDMAP ranges
|
||||
set for specific domains. For each such range, a pair of (range start, range
|
||||
end) values will need to be calculated:
|
||||
|
||||
```
|
||||
${range_id_min} = ipabaseid
|
||||
${range_id_max} = ipabaseid + ipaidrangesize - 1
|
||||
```
|
||||
|
||||
3. Add Samba-specific Kerberos service principal using `ipa service-add-smb`
|
||||
command. This command runs a sequence of operations on IPA master that create
|
||||
an LDAP object for the Samba service Kerberos principal with required LDAP
|
||||
object classes and attributes. Some of the attributes have to be set at the
|
||||
creation time because they are auto-generated when the object is added, thus
|
||||
a sequence of `ipa service-add` and `ipa service-mod` commands cannot be used
|
||||
instead.
|
||||
|
||||
```
|
||||
# ipa service-add-smb <hostname> [<NetBIOS name>]
|
||||
```
|
||||
|
||||
4. Generate a random pre-defined password for the machine account that will be
|
||||
used for both Samba-specific Kerberos service princiapl and for Samba machine
|
||||
account. The generated password has to follow few rules to be usable by
|
||||
Samba. In particular, it has to be encoded in UTF-16. Samba Python bindings
|
||||
provide two methods to allow the password generation,
|
||||
`generate_random_machine_password()` and `generate_random_password()`. While
|
||||
the former call is what is needed, it returns munged UTF-16 which is not
|
||||
readable by `net changesecretpwd -f` utility. Thus, the latter call is used
|
||||
instead. Its output is limited to ASCII characters but still should be strong
|
||||
enough for a machine account password. The code used by the
|
||||
`ipa-client-samba` utility is equivalent for the following call:
|
||||
|
||||
```
|
||||
# python3 -c 'import samba; print(samba.generate_random_password(128, 255))'
|
||||
```
|
||||
|
||||
5. Retrieve the Kerberos key for `cifs/<hostname>` service using pre-defined
|
||||
password for the key. The domain controller must know RC4-HMAC hash of the
|
||||
domain member machine account in order to allow NetLogon ServerAuthenticate3
|
||||
operation. ServerAuthenticate3 call needs an AES session key which is
|
||||
calculated based on an RC4-HMAC of the machine account credential according
|
||||
to [MS-NRPC] section 3.1.4.3.1. The code used by the `ipa-client-samba`
|
||||
utility is equivalent for the following call:
|
||||
|
||||
```
|
||||
# ipa-getkeytab -p cifs/<hostname> -k /etc/samba/samba.keytab -P \
|
||||
-e aes128-cts-hmac-sha1-96,aes256-cts-hmac-sha1-96,arcfour-hmac
|
||||
```
|
||||
Note that in the call above three encryption types were passed explicitly.
|
||||
The reason for that is to allow to pass RC4-HMAC encryption type request
|
||||
through Kerberos library used by `ipa-getkeytab` in FIPS mode.
|
||||
`ipa-getkeytab` utility uses Kerberos encryption types internally. If
|
||||
RC4-HMAC is not allowed for use by the system-wide crypto policy, it will not
|
||||
be specified in the list of default encryption types. If `ipa-getkeytab`
|
||||
utility gets `-e` option, it overrides rather than amends the list of the
|
||||
default encryption types, thus forcing to specify the whole set of encryption
|
||||
types explicitly.
|
||||
|
||||
6. Create Samba config as `/etc/samba/smb.conf` on the client:
|
||||
|
||||
```
|
||||
[global]
|
||||
# Limit number of forked processes to avoid SMBLoris attack
|
||||
max smbd processes = 1000
|
||||
# Use dedicated Samba keytab. The key there must be synchronized
|
||||
# with Samba tdb databases or nothing will work
|
||||
dedicated keytab file = FILE:/etc/samba/samba.keytab
|
||||
kerberos method = dedicated keytab
|
||||
# Set up logging per machine and Samba process
|
||||
log file = /var/log/samba/log.%m
|
||||
log level = 1
|
||||
# We force 'member server' role to allow winbind automatically
|
||||
# discover what is supported by the domain controller side
|
||||
server role = member server
|
||||
realm = IPA.REALM
|
||||
netbios name = ${machine_name}
|
||||
workgroup = ${netbios_name}
|
||||
# Local writable range for IDs not coming from IPA or trusted domains
|
||||
idmap config * : range = 0 - 0
|
||||
idmap config * : backend = tdb
|
||||
idmap config ${netbios_name} : range = ${range_id_min} - ${range_id_max}
|
||||
idmap config ${netbios_name} : backend = sss
|
||||
```
|
||||
|
||||
In the config above two IDMAP configurations were defined:
|
||||
* for the IPA domain the range from `ipabaseid` to
|
||||
`ipabaseid + ipaidrangesize - 1` is used. IDMAP backend configuration says
|
||||
that the range is served by SSSD, using `idmap_sss` module. `idmap_sss`
|
||||
module is provided by `sssd-winbind-idmap` package.
|
||||
|
||||
* for all unknown domains a local 'tdb' IDMAP backend and a range that
|
||||
doesn't conflict with IPA domain is used. In fact, this has to be choosen
|
||||
carefully, especially if IPA setup already integrates with Active
|
||||
Directory and other ranges defined for AD domains. In such case one needs
|
||||
to define separate `idmap config FOO : range` and
|
||||
`idmap config FOO : backend` options per each AD domain that is served
|
||||
through IPA trust to Active Directory the same way as for
|
||||
`idmap config IPA`. The values there should come from the corresponding ID
|
||||
ranges for AD domains.
|
||||
|
||||
7. Defining access to specific shares can be done with a normal Samba
|
||||
`write list` option. An example below grants access to share `shared` to
|
||||
everyone in IPA `admins` group. The group membership resolution will be done
|
||||
by SSSD. It is recommended to use POSIX ACLs tools to set up access controls
|
||||
on the local file system instead of directly setting them in the Samba
|
||||
configuration as this gives more flexibility. Also, one needs to make sure
|
||||
that the POSIX path specified in the share actually allows write access to
|
||||
the users or groups from the `write list`:
|
||||
|
||||
```
|
||||
[shared]
|
||||
path = /srv/shared
|
||||
read only = No
|
||||
write list = @admins
|
||||
|
||||
[homes]
|
||||
browsable = no
|
||||
writable = yes
|
||||
|
||||
```
|
||||
|
||||
8. Samba configuration has to use the same Security Identifier for the domain as
|
||||
is used by the IPA domain controller. The original value is retrieved in step
|
||||
1 as `ipantsecurityidentifier`. This information is not stored in the
|
||||
`smb.conf`. Instead, it is stored in the binary databases managed by Samba.
|
||||
It can be set through `net setdomainsid` command:
|
||||
|
||||
```
|
||||
# net setdomainsid ${ipantsecurityidentifier}
|
||||
```
|
||||
|
||||
9. For SMB protocol, `BUILTIN\Guests` group has always to be mapped to a local
|
||||
POSIX groups. It is typically mapped to a local nobody group. This is
|
||||
required in all recent Samba releases:
|
||||
|
||||
```
|
||||
# net groupmap add sid=S-1-5-32-546 unixgroup=nobody type=builtin
|
||||
```
|
||||
|
||||
10. Before using Samba, it needs to know the machine account credentials.
|
||||
Unfortunately, it is only possible to change the machine account credentials
|
||||
when Samba is already enrolled into domain or set it when it is being
|
||||
enrolled with `net [ads|rpc] join` command. Since IPA client host is
|
||||
enrolled using an alternative method, the join command cannot be used and
|
||||
internal binary databases do not contain correct values that allow Samba to
|
||||
see itself as an enrolled one.
|
||||
|
||||
Instead, until a support for 'offline' enrollment is added, the following
|
||||
procedure has to be used. The procedure employs low-level tools to
|
||||
manipulate Samba TDB databases:
|
||||
|
||||
```
|
||||
# tdbtool /var/lib/samba/private/secrets.tdb store SECRETS/MACHINE_LAST_CHANGE_TIME/${netbios_name} '2\00'
|
||||
# tdbtool /var/lib/samba/private/secrets.tdb store SECRETS/MACHINE_PASSWORD/${netbios_name} '2\00'
|
||||
# net changesecretpw -f
|
||||
```
|
||||
`${netbios_name}` value in the calls above corresponds to the IPA domain's
|
||||
NetBIOS name. `net changesecretpw -f` call will require entering the
|
||||
password generated at the step 4.
|
||||
|
||||
11. Start Samba systemd services. At least `smb.service` and `winbind.service`
|
||||
services has to be started because Samba cannot function without both of
|
||||
them in newer releases. `winbindd` daemon is an integral part of Samba and
|
||||
all fallback code for the cases when `winbindd` was not running in some
|
||||
configurations was removed from `smbd` daemon in newer Samba releases.
|
||||
|
||||
```
|
||||
# systemctl start smb winbind
|
||||
```
|
||||
|
||||
## Example of using Samba file server on IPA client
|
||||
|
||||
Once `ipa-client-samba` utility was used to configure Samba services, the shares
|
||||
were added and systemd services `smb.service` and `winbind.service` were
|
||||
started, one can access a Samba share as a user from IPA domain. Below is an
|
||||
example from the test run of `ipatests/test_integration/test_smb.py` done by PR
|
||||
CI.
|
||||
|
||||
```
|
||||
# kinit athena
|
||||
Password for athena@IPA.TEST:
|
||||
# mkdir -p /mnt/athena
|
||||
# mount -t cifs //replica0.ipa.test/homes /mnt/athena -o user=athena,sec=krb5i
|
||||
# dd count=1024 bs=1K if=/dev/zero of=/mnt/athena/athena.dat
|
||||
1024+0 records in
|
||||
1024+0 records out
|
||||
1048576 bytes (1.0 MB, 1.0 MiB) copied, 0.0339479 s, 30.9 MB/s
|
||||
# findmnt -t cifs
|
||||
TARGET SOURCE FSTYPE OPTIONS
|
||||
/mnt/athena //replica0.ipa.test/homes cifs rw,relatime,vers=3.1.1,sec=krb5,cruid=0i,cache=strict,username=athena,uid=0,noforceuid,gid=0,noforcegid,addr=192.168.121.171,file_mode=0755,dir_mode=0755,soft,nounix,serverino,mapposix,rsize=4194304,wsize=4194304,bsize=1048576,echo_interval=60,actimeo=1
|
||||
# ls -laZ /mnt/athena/athena.dat
|
||||
-rwxr-xr-x 1 root root ? 1048576 Jun 19 11:45 /mnt/athena/athena.dat
|
||||
# smbstatus
|
||||
|
||||
Samba version 4.10.4
|
||||
PID Username Group Machine Protocol Version Encryption Signing
|
||||
----------------------------------------------------------------------------------------------------------------------------------------
|
||||
17249 athena athena 192.168.121.43 (ipv4:192.168.121.43:46286) SMB3_11 - AES-128-CMAC
|
||||
|
||||
Service pid Machine Connected at Encryption Signing
|
||||
---------------------------------------------------------------------------------------------
|
||||
IPC$ 17249 192.168.121.43 Wed Jun 19 11:45:46 AM 2019 UTC - AES-128-CMAC
|
||||
athena 17249 192.168.121.43 Wed Jun 19 11:45:46 AM 2019 UTC - AES-128-CMAC
|
||||
|
||||
No locked files
|
||||
|
||||
# umount -a -t cifs
|
||||
# smbclient -k //replica0.ipa.test/homes -c 'allinfo athena.dat'
|
||||
altname: athena.dat
|
||||
create_time: Wed Jun 19 11:45:46 AM 2019 UTC
|
||||
access_time: Wed Jun 19 11:45:46 AM 2019 UTC
|
||||
write_time: Wed Jun 19 11:45:46 AM 2019 UTC
|
||||
change_time: Wed Jun 19 11:45:46 AM 2019 UTC
|
||||
attributes: A (20)
|
||||
stream: [::$DATA], 1048576 bytes
|
||||
# kdestroy -A
|
||||
```
|
||||
|
||||
|
||||
## Notes about unfinished Samba work
|
||||
|
||||
Since changes on Samba side apply for both domain controller and domain member,
|
||||
unfinished work is reflected in a single place only. Please see [samba-domain-controller]
|
||||
for details.
|
||||
|
||||
[Samba]: https://www.samba.org/
|
||||
[MS-NRPC]: https://msdn.microsoft.com/en-us/library/cc237008.aspx
|
||||
[MS-LSAD]: https://msdn.microsoft.com/en-us/library/cc234225.aspx
|
||||
[MS-LSAT]: https://msdn.microsoft.com/en-us/library/cc234420.aspx
|
||||
[samba-domain-controller]: samba-domain-controller.md
|
||||
|
||||
303
doc/designs/disable-stale-users.md
Normal file
303
doc/designs/disable-stale-users.md
Normal file
@@ -0,0 +1,303 @@
|
||||
# Disable Stale Users
|
||||
|
||||
**DESIGN STAGE**
|
||||
|
||||
## Overview
|
||||
|
||||
Some regulations call for accounts that have not been used for a specific
|
||||
amount of time be automatically disabled in the identity management system.
|
||||
|
||||
FreeIPA does not keep track of successful authentication events.
|
||||
The krbLastSuccessfulAuth attribute is not updated by default since
|
||||
https://pagure.io/freeipa/issue/5313 for reliability reasons.
|
||||
Therefore distinguishing between stale and active accounts cannot be done with
|
||||
existing logon data.
|
||||
|
||||
|
||||
## Possible approaches
|
||||
|
||||
### Environments with mandatory, periodic password changes
|
||||
|
||||
The problem is easy to solve in environments where user passwords must be
|
||||
changed regularly. A user account whose associated password is past its due
|
||||
change date can be considered stale and therefore be disabled by the system.
|
||||
In this case, a grace period must be provided between password expiration and
|
||||
the actual account locking event.
|
||||
Total writes to LDAP using this approach due to the disable stale users tooling
|
||||
are minimal (only nsAccountLock). However, password-change related writes are
|
||||
needed every 90 days (by default).
|
||||
Each password change updates the krbLastPwdChange, krbPasswordExpiration,
|
||||
userPassword, krbPrincipalKey, and krbExtraData attributes.
|
||||
|
||||
The Disable Stale Users (DSU) tooling proposes to make sure no non-locked
|
||||
account has a password expired since N days, N being 7 by default.
|
||||
|
||||
### Environments with no mandatory password changes
|
||||
|
||||
For environments where user passwords never expire, a new mechanism must be
|
||||
added to FreeIPA plugins ipa-kdb and ipa-lockout to account for each user
|
||||
account authentication events. Since updating a LDAP user account attribute on
|
||||
each authentication event must be avoided as the update frequency could easily
|
||||
be high, (see https://pagure.io/freeipa/issue/5313 for background
|
||||
information), a coarse update mechanism is proposed.
|
||||
|
||||
An attribute containing a timestamp is added to each user:
|
||||
coarseSuccessfulAuthTime. It will be added at account creation time (set to
|
||||
current date).
|
||||
The timestamp contained therein is not precise. It is updated by IPA plugins
|
||||
whenever a successful authentication event happens, but only if the current
|
||||
timestamp is sufficiently in the past. The update interval is configurable, but
|
||||
to avoid replication storms, it is randomized. To achieve this, a randomized
|
||||
value is added to a fixed time interval.
|
||||
|
||||
Some attributes must be added to the cn=ipaConfig schema:
|
||||
* the first one to activate the mechanism (default: not present):
|
||||
```
|
||||
ipaConfigString: DSU:RecordSuccessfulAuth
|
||||
```
|
||||
* the second attribute contains the fixed time period (default: 28 days):
|
||||
```
|
||||
ipaDSURecordSucessfulAuthTimeInterval: 2419200
|
||||
```
|
||||
* the third one contains a time period to be added. The actual value used is
|
||||
randomized between 0 and the attribute's value (default: 7 days) whenever
|
||||
a user successfully authenticates.
|
||||
```
|
||||
ipaDSURecordSucessfulAuthRandomizedTimeInterval: 604800
|
||||
```
|
||||
|
||||
Updating this (replicated) timestamp attribute every ~30 days requires less
|
||||
LDAP writes than mandating password changes every 90 days as the latter would
|
||||
imply updating five (replicated) attributes at least once in that 90-day
|
||||
period.
|
||||
|
||||
The Disable Stale Users (DSU) tooling, when the above mechanism is active,
|
||||
proposes to make sure no non-locked account has a timestamp attribute 90 days
|
||||
(by default) in the past.
|
||||
|
||||
On a successful authentication event:
|
||||
|
||||
```
|
||||
current_date = datetime.now(timezone.utc)
|
||||
last_update = coarseSuccessfulAuthTime
|
||||
update_internal = ipaDSURecordSucessfulAuthTimeInterval
|
||||
+ randint(0, ipaDSURecordSucessfulAuthRandomizedTimeInterval)
|
||||
if current_date - last_update > update_internal:
|
||||
coarseSuccessfulAuthTime = current_date
|
||||
```
|
||||
|
||||
As a rule of thumb, if the requirement is to disable users not seen for 90 days
|
||||
maximum, updating the attribute roughly every 35 days is good enough.
|
||||
At worst, the user would have authenticated the first day and the last day of
|
||||
the 35-day maximum update interval and the randomized time interval would have
|
||||
been 7 days.
|
||||
The attribute would therefore contain the date from the first day, as day #35
|
||||
would have been considered too close to the existing timestamp to warrant
|
||||
updating it. DSU would then proceed to disable the user account 90 days after
|
||||
the existing coarseSuccessfulAuthTime timestamp - this is only after 55 day
|
||||
(90-35) of real inactivity, which fits the requirement (albeit loosely).
|
||||
|
||||
Having a 90-day inactive user disabling requirement would by default disable
|
||||
accounts really inactive for 55 (90-35) to 90 days.
|
||||
|
||||
In short:
|
||||
|
||||
```
|
||||
if (current_date - 90d) > coarseSuccessfulAuthTime:
|
||||
disable_account()
|
||||
```
|
||||
|
||||
The 90-day default value is configurable (see appropriate section below).
|
||||
|
||||
|
||||
### Notes
|
||||
|
||||
Installing the DSU tooling will not change the behavior of existing clusters.
|
||||
DSU has to be explicitly configured and enabled to start disabling stale
|
||||
accounts.
|
||||
|
||||
Accounts are locked out by setting the nsAccountLock attribute
|
||||
(OID: 2.16.840.1.113730.3.1.610) to True.
|
||||
|
||||
FreeeIPA is not directly involved when a user logs in using an ssh key so it
|
||||
cannot make decisions on whether an account is "active" or not. However,
|
||||
setting nsaccountlock = TRUE will block all logins including those using ssh
|
||||
key authentication.
|
||||
For passwordless environments, S4U2Self is proposed to be added to SSSD to
|
||||
account for successful user logon events through ipa-kdb:
|
||||
https://pagure.io/SSSD/sssd/issue/4077
|
||||
The mechanism laid out in "Environments with no mandatory password changes"
|
||||
would then be applied as-is.
|
||||
|
||||
There is always the possibility that a long-inactive user account will be
|
||||
disabled (nsAccountLock'd) by DSU even if that user managed to logon the
|
||||
previous few seconds before or during the DSU window due to:
|
||||
* the time it takes for the timestamp attribute to be replicated to the DSU
|
||||
runner
|
||||
* the time it takes for nsAccountLock to be replicated from the DSU runner
|
||||
to the replica this user uses.
|
||||
|
||||
There is no way to prevent that from happening with the present design, but
|
||||
the probability of that happening is low.
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
### Environments with mandatory, periodic password changes
|
||||
|
||||
Given the following requirements and facts:
|
||||
* stale accounts must be disabled after 90 days' inactivity
|
||||
* grace period is decided to be 7 days
|
||||
* the tool runs every day
|
||||
* replication is expected to complete in 2h maximum
|
||||
|
||||
setting the maximum password lifetime to 80 days or less would meet the
|
||||
guidelines as 80+7+1 (give or take 2h) is less than 90.
|
||||
|
||||
### Environments with no mandatory password changes
|
||||
|
||||
If the requirement is to disable users not seen for 90 days maximum, updating
|
||||
the attribute every 35 days is good enough.
|
||||
At worst, the user would have authenticated the first day and at least once
|
||||
during this 35 day period, say day #29. The attribute would therefore contain
|
||||
the date from the first day, as day #29 would have been considered too close to
|
||||
the existing timestamp to warrant updating it. The user account would then be
|
||||
disabled after 61 days of inactivity which fits (loosely) the requirement.
|
||||
In short, having a 90-day inactive user disabling requirement would by default
|
||||
disable accounts inactive for 55 (90-35) to 90 days.
|
||||
|
||||
|
||||
## Limitations
|
||||
|
||||
### Environments with mandatory, periodic password changes
|
||||
|
||||
If regulations call for stale/inactive accounts to be disabled within X
|
||||
number of days, then the lifetime of the passwords for these accounts must be
|
||||
set to a value lower than:
|
||||
* X,
|
||||
* minus the expected grace period mentioned above,
|
||||
* minus the maximum amount of time between two invocations of the DSU tool,
|
||||
* minus the expected maximum replication delay from the replica the DSU tool is
|
||||
installed on to the farthest point of the cluster.
|
||||
|
||||
### Environments with no mandatory password changes
|
||||
|
||||
The longer the time period, the less update activity for the timestamp
|
||||
attribute. But using a longer period runs the risk of disabling users who have
|
||||
been gone for too short a time. For instance, setting the update period to 65
|
||||
days would disable accounts inactive for the last 25 to 90 days. Whether this
|
||||
fits the site's requirements is up to the administrators to determine.
|
||||
|
||||
Sites requiring a better accuracy must take care not to set the update period
|
||||
too low for performance reasons. It is strongly recommended to make sure the
|
||||
update period is longer than the expected maximum PTO or simply "away from IPA"
|
||||
period for most user accounts to avoid replication storms when users come back.
|
||||
This is especially true when these away periods are in sync, like in schools.
|
||||
|
||||
|
||||
## Multiple runners
|
||||
|
||||
DSU can be installed on more than a single replica. This provides redundancy.
|
||||
Having multiple DSU instances active at the same time provides no advantage,
|
||||
so the systemd timer helper script includes a randomized time wait period.
|
||||
|
||||
On very busy clusters, using dedicated replicas (hidden replicas) for DSU is
|
||||
recommended.
|
||||
|
||||
|
||||
## How to Use DSU
|
||||
|
||||
### Installation
|
||||
|
||||
The Disable Stale Users tooling will be shipped with a new version of the
|
||||
FreeIPA server package so it will be included in default installs.
|
||||
|
||||
### Configuration
|
||||
|
||||
#### Environments with mandatory, periodic password changes
|
||||
|
||||
|
||||
The following attributes are added to the schema.
|
||||
```
|
||||
ipaConfigString: DSU:EnablePasswordBasedDSU
|
||||
PasswordBasedDSUGracePeriod: 604800
|
||||
DSUIgnoreGroups: admins
|
||||
DSUVerbosity: 1
|
||||
```
|
||||
Adding DSU:EnablePasswordBasedDSU to the cn=ipaconfig schema will let
|
||||
DSU disable accounts after a grace period defined in
|
||||
PasswordBasedDSUGracePeriod (by default 604800 seconds).
|
||||
This is the time delta after password expiry date on which to disable accounts.
|
||||
|
||||
The DSU:IgnoreGroups is multi-valued. Users belonging directly or
|
||||
indirectly to these groups will not be affected.
|
||||
|
||||
DSUVerbosity's default value is "1".
|
||||
A value of "1" makes the DSU tool log actions to systemd.
|
||||
A value of "0" disables logging.
|
||||
Other values are ignored and treated like "1".
|
||||
|
||||
|
||||
#### Environments with no mandatory password changes
|
||||
|
||||
The following attributes are added to the schema:
|
||||
```
|
||||
ipaConfigString: DSU:EnableTimeStampBasedDSU
|
||||
TimeStampBasedDSUInactivePeriod: 7776000
|
||||
DSUIgnoreGroups: admins
|
||||
DSUVerbosity: 1
|
||||
```
|
||||
|
||||
Adding DSU:EnableTimeStampBasedDSU to the cn=ipaconfig schema will let
|
||||
DSU disable accounts when the account's coarseSuccessfulAuthTime is more
|
||||
than TimeStampBasedDSUInactivePeriod in the past.
|
||||
|
||||
The other variables behave the same way as the password-based-dsu case.
|
||||
|
||||
|
||||
### Usage
|
||||
|
||||
The DSU tool is not a UNIX daemon. It is a CLI tool that can be triggered
|
||||
by a systemd timer.
|
||||
|
||||
Running ``ipa-dsu`` is enough to start the tool. If DSU is enabled (see above),
|
||||
it will disable stale accounts appopriately.
|
||||
|
||||
The dry-run mode ``ipa-dsu --dry-run`` does not disable/lock accounts in any
|
||||
way. Rather, it shows what would be done, essentially acting as a verbose mode
|
||||
with "disable_accounts" set to False. The output is JSON.
|
||||
|
||||
There is no verbose mode combined with disable_accounts set to True. The tool
|
||||
logs what it does and the reason for each account disabling action into
|
||||
journald if DSUVerbosity is set to 1.
|
||||
|
||||
|
||||
### Activation
|
||||
|
||||
Activate the DSU tool to run every night using the provided systemd timer:
|
||||
``systemctl enable ipa-dsu.timer``
|
||||
|
||||
|
||||
### Logs
|
||||
|
||||
The DSU tool logs each action in journald. Sample output:
|
||||
```
|
||||
ipa-dsu: disabled account uid=alice,cn=users,cn=accounts,dc=example,dc=com - password expired on 20191001.
|
||||
```
|
||||
```
|
||||
ipa-dsu: disabled account uid=bob,cn=users,cn=accounts,dc=example,dc=com - user not seen since 20190701.
|
||||
```
|
||||
|
||||
## Proposed Enhancements to DSU
|
||||
|
||||
DSU could reset passwords of locked-out accounts to a random, long string
|
||||
after a second grace period.
|
||||
|
||||
DSU could offer a way for admins to display which account(s) would be
|
||||
disabled past a certain date using a CLI knob that would modify --dry-run.
|
||||
|
||||
The DSU-mandated modifications to ipa-kdb and ipa-lockout described in
|
||||
"Environments with no mandatory password changes" could also update the
|
||||
timestamp attribute on password changes. That way, the DSU logic could be
|
||||
switched to being logon timestamp-based only.
|
||||
|
||||
242
doc/designs/extdom-plugin-protocol.md
Normal file
242
doc/designs/extdom-plugin-protocol.md
Normal file
@@ -0,0 +1,242 @@
|
||||
# Extdom plugin protocol
|
||||
|
||||
SSSD on ipa client uses extdom plugin to translate SID to names and POSIX IDs. It can
|
||||
also return secondary groups for any user.
|
||||
|
||||
## EXTDOM V0 (2.16.840.1.113730.3.8.10.4)
|
||||
|
||||
### V0 request
|
||||
|
||||
/*
|
||||
* ExtdomRequestValue ::= SEQUENCE {
|
||||
* inputType ENUMERATED {
|
||||
* sid (1),
|
||||
* name (2),
|
||||
* posix uid (3),
|
||||
* posix gid (4)
|
||||
* },
|
||||
* requestType ENUMERATED {
|
||||
* simple (1),
|
||||
* full (2)
|
||||
* },
|
||||
* data InputData
|
||||
* }
|
||||
*
|
||||
* InputData ::= CHOICE {
|
||||
* sid OCTET STRING,
|
||||
* name NameDomainData
|
||||
* uid PosixUid,
|
||||
* gid PosixGid
|
||||
* }
|
||||
*
|
||||
* NameDomainData ::= SEQUENCE {
|
||||
* domain_name OCTET STRING,
|
||||
* object_name OCTET STRING
|
||||
* }
|
||||
*
|
||||
* PosixUid ::= SEQUENCE {
|
||||
* domain_name OCTET STRING,
|
||||
* uid INTEGER
|
||||
* }
|
||||
*
|
||||
* PosixGid ::= SEQUENCE {
|
||||
* domain_name OCTET STRING,
|
||||
* gid INTEGER
|
||||
* }
|
||||
*/
|
||||
|
||||
### V0 reply
|
||||
|
||||
/*
|
||||
* ExtdomResponseValue ::= SEQUENCE {
|
||||
* responseType ENUMERATED {
|
||||
* sid (1),
|
||||
* name (2),
|
||||
* posix_user (3),
|
||||
* posix_group (4)
|
||||
* },
|
||||
* data OutputData
|
||||
* }
|
||||
*
|
||||
* OutputData ::= CHOICE {
|
||||
* sid OCTET STRING,
|
||||
* name NameDomainData,
|
||||
* user PosixUser,
|
||||
* group PosixGroup
|
||||
* }
|
||||
*
|
||||
* NameDomainData ::= SEQUENCE {
|
||||
* domain_name OCTET STRING,
|
||||
* object_name OCTET STRING
|
||||
* }
|
||||
*
|
||||
* PosixUser ::= SEQUENCE {
|
||||
* domain_name OCTET STRING,
|
||||
* user_name OCTET STRING,
|
||||
* uid INTEGER
|
||||
* gid INTEGER
|
||||
* }
|
||||
*
|
||||
* PosixGroup ::= SEQUENCE {
|
||||
* domain_name OCTET STRING,
|
||||
* group_name OCTET STRING,
|
||||
* gid INTEGER
|
||||
* }
|
||||
*/
|
||||
|
||||
## EXTDOM V1 (2.16.840.1.113730.3.8.10.4.1)
|
||||
|
||||
In V1 version the requestType is extended of `full_with_groups`.
|
||||
The response introduces new type `posix_user_grouplist` containing
|
||||
the list of groups
|
||||
|
||||
### V1 request
|
||||
|
||||
/*
|
||||
* ExtdomRequestValue ::= SEQUENCE {
|
||||
* inputType ENUMERATED {
|
||||
* sid (1),
|
||||
* name (2),
|
||||
* posix uid (3),
|
||||
* posix gid (4),
|
||||
* },
|
||||
* requestType ENUMERATED {
|
||||
* simple (1),
|
||||
* full (2),
|
||||
* full_with_groups (3)
|
||||
* },
|
||||
* data InputData
|
||||
* }
|
||||
*
|
||||
* InputData ::= CHOICE {
|
||||
* sid OCTET STRING,
|
||||
* name NameDomainData
|
||||
* uid PosixUid,
|
||||
* gid PosixGid
|
||||
* }
|
||||
*
|
||||
* NameDomainData ::= SEQUENCE {
|
||||
* domain_name OCTET STRING,
|
||||
* object_name OCTET STRING
|
||||
* }
|
||||
*
|
||||
* PosixUid ::= SEQUENCE {
|
||||
* domain_name OCTET STRING,
|
||||
* uid INTEGER
|
||||
* }
|
||||
*
|
||||
* PosixGid ::= SEQUENCE {
|
||||
* domain_name OCTET STRING,
|
||||
* gid INTEGER
|
||||
* }
|
||||
*/
|
||||
|
||||
### V1 reply
|
||||
|
||||
/*
|
||||
* ExtdomResponseValue ::= SEQUENCE {
|
||||
* responseType ENUMERATED {
|
||||
* sid (1),
|
||||
* name (2),
|
||||
* posix_user (3),
|
||||
* posix_group (4),
|
||||
* posix_user_grouplist (5)
|
||||
* },
|
||||
* data OutputData
|
||||
* }
|
||||
*
|
||||
* OutputData ::= CHOICE {
|
||||
* sid OCTET STRING,
|
||||
* name NameDomainData,
|
||||
* user PosixUser,
|
||||
* group PosixGroup,
|
||||
* user_grouplist PosixUserGrouplist
|
||||
* }
|
||||
*
|
||||
* NameDomainData ::= SEQUENCE {
|
||||
* domain_name OCTET STRING,
|
||||
* object_name OCTET STRING
|
||||
* }
|
||||
*
|
||||
* PosixUser ::= SEQUENCE {
|
||||
* domain_name OCTET STRING,
|
||||
* user_name OCTET STRING,
|
||||
* uid INTEGER
|
||||
* gid INTEGER
|
||||
* }
|
||||
*
|
||||
* GroupNameList ::= SEQUENCE OF groupname OCTET STRING
|
||||
*
|
||||
* PosixGroup ::= SEQUENCE {
|
||||
* domain_name OCTET STRING,
|
||||
* group_name OCTET STRING,
|
||||
* gid INTEGER
|
||||
* }
|
||||
*
|
||||
* PosixUserGrouplist ::= SEQUENCE {
|
||||
* domain_name OCTET STRING,
|
||||
* user_name OCTET STRING,
|
||||
* uid INTEGER
|
||||
* gid INTEGER
|
||||
* gecos OCTET STRING,
|
||||
* home_directory OCTET STRING,
|
||||
* shell OCTET STRING,
|
||||
* grouplist GroupNameList
|
||||
* }
|
||||
*
|
||||
* GroupNameList ::= SEQUENCE OF groupname OCTET STRING
|
||||
*
|
||||
*/
|
||||
|
||||
## EXTDOM V2 (2.16.840.1.113730.3.8.10.4.2)
|
||||
|
||||
The `name` request tries to translate name to ID. It first tries translate it
|
||||
as if it is a user and when it fails, it tries to resolve is as group.
|
||||
|
||||
To make it more efficient when SSSD knows the type of requested object, two new
|
||||
inputTypes are defined - username and groupname.
|
||||
|
||||
The response is the same as in V1
|
||||
|
||||
### V2 request
|
||||
|
||||
/*
|
||||
* ExtdomRequestValue ::= SEQUENCE {
|
||||
* inputType ENUMERATED {
|
||||
* sid (1),
|
||||
* name (2),
|
||||
* posix uid (3),
|
||||
* posix gid (4),
|
||||
* username (5),
|
||||
* groupname (6)
|
||||
* },
|
||||
* requestType ENUMERATED {
|
||||
* simple (1),
|
||||
* full (2),
|
||||
* full_with_groups (3)
|
||||
* },
|
||||
* data InputData
|
||||
* }
|
||||
*
|
||||
* InputData ::= CHOICE {
|
||||
* sid OCTET STRING,
|
||||
* name NameDomainData
|
||||
* uid PosixUid,
|
||||
* gid PosixGid
|
||||
* }
|
||||
*
|
||||
* NameDomainData ::= SEQUENCE {
|
||||
* domain_name OCTET STRING,
|
||||
* object_name OCTET STRING
|
||||
* }
|
||||
*
|
||||
* PosixUid ::= SEQUENCE {
|
||||
* domain_name OCTET STRING,
|
||||
* uid INTEGER
|
||||
* }
|
||||
*
|
||||
* PosixGid ::= SEQUENCE {
|
||||
* domain_name OCTET STRING,
|
||||
* gid INTEGER
|
||||
* }
|
||||
*/
|
||||
153
doc/designs/hidden-replicas.md
Normal file
153
doc/designs/hidden-replicas.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# Hidden replicas
|
||||
|
||||
**TECH PREVIEW**
|
||||
|
||||
## Overview
|
||||
|
||||
A hidden replica is an IPA master server that is not advertised to
|
||||
clients or other masters. Hidden replicas have all services running
|
||||
and available, but none of the services has any DNS SRV records or
|
||||
enabled LDAP server roles. This makes hidden replicas invisible for
|
||||
service discovery.
|
||||
|
||||
* IPA clients and SSSD ignore hidden replicas and don't consider them
|
||||
during installation or daily operations.
|
||||
* Kerberos clients with ``dns_lookup_kdc = True`` do not auto-discover
|
||||
hidden replicas.
|
||||
* Certmonger does not use a hidden replica to renew certificates.
|
||||
* Masters without a CA or KRA instance never use CA or KRA services
|
||||
of a hidden replica.
|
||||
|
||||
By default, only services on a hidden replica use other services on
|
||||
the same machine, e.g. local LDAP and Kerberos services.
|
||||
|
||||
## Limitations
|
||||
|
||||
It's critical to understand that hidden replicas have limitations. Most
|
||||
importantly, hidden replicas are just concealed, but not isolated and
|
||||
secluded. Other machines merely don't see hidden replicas, when they
|
||||
use standard mechanisms to discover IPA servers. Other machines are
|
||||
able to find hidden replicas if they know what to look for. Any machine
|
||||
is able to use services on a hidden replica, when they are explicitly
|
||||
configured to do so.
|
||||
|
||||
* Hidden replicas are neither firewalled nor do they have any ACLs in
|
||||
place to prevent connections from other machines. All IPA TCP and
|
||||
UDP ports must be open for at least all other IPA servers.
|
||||
* There must be at least one regular, non-hidden server available and
|
||||
online for each service (IPA master, DNS, CA, KRA). If DNS locations
|
||||
are used, there should be at least one regular replica in each
|
||||
location.
|
||||
* As of now, a hidden replica cannot be a *CA renewal master* or
|
||||
a *DNSSEC key master*. The restriction may be lifted in the future.
|
||||
* Hard-coded server names and explicit configurations like
|
||||
``ipa-client-install --server=$HOST``, SSSD config, or ``ca_host``
|
||||
setting in ``/etc/ipa/default.conf`` override auto-discovery.
|
||||
* The process of demoting a regular replica to hidden replica or
|
||||
promotion from hidden to regular replica is not instantaneous. It
|
||||
takes a while until the changes have been replicated and cached
|
||||
settings are refreshed.
|
||||
|
||||
## Use Cases
|
||||
|
||||
Hidden replicas are primarily designed for dedicated services that may
|
||||
otherwise disrupt clients. For example a full backup requires a
|
||||
complete shutdown of all IPA services. Since a hidden replica is not
|
||||
used by any clients by default, a temporary shutdown does not affect
|
||||
clients.
|
||||
|
||||
Other use cases include operations that put a high load on the IPA
|
||||
API or LDAP server, like mass imports or extensive queries.
|
||||
|
||||
## How to Use
|
||||
|
||||
### installation of a hidden replica
|
||||
|
||||
A new hidden replica can be installed with
|
||||
``ipa-replica-install --hidden-replica``.
|
||||
|
||||
### demotion / promotion of hidden replicas
|
||||
|
||||
A new command ``ipa server-state`` can be used to modify the state of a
|
||||
replica. An existing replica can be demoted to a hidden replica by
|
||||
executing ``ipa server-state $HOST --state=hidden``. The command
|
||||
``ipa server-state $HOST --state=enabled`` turns a hidden replica
|
||||
into an enabled, visible replica.
|
||||
|
||||
A *CA renewal master* or *DNSSEC key master* can't be demoted to hidden
|
||||
replica. First the services must be moved to another replica with
|
||||
``ipa-dns-install --dnssec-master`` and
|
||||
``ipa config-mod --ca-renewal-master-server=$HOST``.
|
||||
|
||||
### query status
|
||||
|
||||
The ``ipa config-show`` command now shows additional information about
|
||||
DNS and KRA as well as hidden servers:
|
||||
|
||||
```
|
||||
$ ipa config-show
|
||||
...
|
||||
IPA masters: server1.ipa.example
|
||||
Hidden IPA masters: hidden1.ipa.example
|
||||
IPA master capable of PKINIT: hidden1.ipa.example, server1.ipa.example
|
||||
IPA CA servers: server1.ipa.example
|
||||
Hidden IPA CA servers: hidden1.ipa.example
|
||||
IPA CA renewal master: server1.ipa.example
|
||||
IPA KRA servers: server1.ipa.example
|
||||
Hidden IPA KRA servers: hidden1.ipa.example
|
||||
IPA DNS servers: server1.ipa.example
|
||||
Hidden IPA DNS servers: hidden1.ipa.example
|
||||
IPA DNSSec key master: server1.ipa.example
|
||||
$ ipa server-role-find --server=hidden1.ipa.example --include-master
|
||||
----------------------
|
||||
6 server roles matched
|
||||
----------------------
|
||||
Server name: hidden1.ipa.example
|
||||
Role name: AD trust agent
|
||||
Role status: absent
|
||||
|
||||
Server name: hidden1.ipa.example
|
||||
Role name: AD trust controller
|
||||
Role status: absent
|
||||
|
||||
Server name: hidden1.ipa.example
|
||||
Role name: CA server
|
||||
Role status: hidden
|
||||
|
||||
Server name: hidden1.ipa.example
|
||||
Role name: DNS server
|
||||
Role status: hidden
|
||||
|
||||
Server name: hidden1.ipa.example
|
||||
Role name: IPA master
|
||||
Role status: hidden
|
||||
|
||||
Server name: hidden1.ipa.example
|
||||
Role name: KRA server
|
||||
Role status: hidden
|
||||
----------------------------
|
||||
Number of entries returned 6
|
||||
----------------------------
|
||||
```
|
||||
|
||||
## Implementation
|
||||
|
||||
The status of a service is stored in LDAP inside the
|
||||
``cn=masters,cn=ipa,cn=etc,$SUFFIX`` subtree. The subtree contains
|
||||
entries for each IPA master. Each entry holds a bunch of sub entries
|
||||
for services. For example
|
||||
``cn=CA,cn=hidden1.ipa.example,cn=masters,cn=ipa,cn=etc,$SUFFIX`` is
|
||||
the container for the *CA* service on the IPA master
|
||||
*hidden1.ipa.example*. During the installation process the service
|
||||
entries are created with multi-valued attribute ``ipaConfigString``
|
||||
set to ``configuredService``. At the end of the installation,
|
||||
``configuredService`` is either replaced with ``enabledService`` for a
|
||||
standard, enabled, and visible replica. Or it is set to
|
||||
``hiddenService`` for hidden, unadvertised replicas.
|
||||
|
||||
Auto-discovery ignores any and all hidden services. The
|
||||
``dns-update-system-records`` does not create SRV records for hidden
|
||||
services. The ``find_providing_servers`` API ignores hidden services
|
||||
except for preferred hosts. CA and KRA service discovery use the
|
||||
current host or explicit ``ca_host`` option from
|
||||
``/etc/ipa/default.conf`` as preferred host.
|
||||
121
doc/designs/krb-ticket-policy.md
Normal file
121
doc/designs/krb-ticket-policy.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# Policies by authentication indicators
|
||||
|
||||
## Overview
|
||||
|
||||
Based on the pre-authentication mechanism a user used to acquire the credential,
|
||||
the KDC can enforce policies such as service access control,
|
||||
user authentication and ticket lifetime/reissue time policies to achieve a finer control over ticket issuance.
|
||||
|
||||
## Authentication indicators
|
||||
|
||||
Authentication indicators are attached by KDC to tickets issued to user and depend on
|
||||
which pre-authentication mechanism used to acquire the credential.
|
||||
Indicators and corresponding mechanisms are listed below:
|
||||
|
||||
| Authentication indicator | Mechanism |
|
||||
|:------------------------ | :------------------- |
|
||||
| radius | RADIUS |
|
||||
| otp | Two factor authentication (password + OTP) |
|
||||
| pkinit | PKINIT |
|
||||
| hardened | Hardened Password (by SPAKE or FAST) |
|
||||
|
||||
Hardened password means a password authentication with either SPAKE or FAST armoring enabled.
|
||||
Although it is possible to assign separate indicators to SPAKE and FAST, when both SPAKE and FAST are used,
|
||||
only the indicator for SPAKE will be applied.
|
||||
Since there is no practical reason to forbid the use of SPAKE while using FAST armoring,
|
||||
these two are assigned the same indicator to represent a brute-force hardened form of password authentication.
|
||||
|
||||
By requiring certain authentication indicators to a user, we can force a user to be authenticated with one of
|
||||
the mechanisms associated with those auth indicators to obtain a ticket.
|
||||
By defining a white list of authentication indicators to a service, we can allow a user to use the service
|
||||
only if the user obtained a ticket with at least one of those indicators included.
|
||||
|
||||
#### Note
|
||||
|
||||
For unattended services (services that is a part of the IPA core system), the authentication indicator should not be set,
|
||||
or it may break the whole system. Examples for such services are `HTTP/*` (for webUI and IPA API end-points),
|
||||
`ldap/*` (for user data management etc.), `cifs/*` (for SMB and DCE-RPC services),
|
||||
also for `host/*` on IPA masters which are used by DCE-RPC services to validate client-server communication.
|
||||
|
||||
## Available policies and user interface
|
||||
|
||||
### Connection policy
|
||||
|
||||
Different service may need different security strength and consequently requires different pre-auth mechanism.
|
||||
|
||||
e.g. must have used 2FA or OTP in order to connect to `host/securemachine@REALM`
|
||||
|
||||
Services with no authentication indicator assigned will accept tickets authenticated by any mechanism.
|
||||
|
||||
#### CLI Workflow:
|
||||
|
||||
Administrators can specify required auth indicators for a service via `ipa service-mod` command.
|
||||
|
||||
e.g. `ipa service-mod service/@REALM --auth-ind otp --auth-ind pkinit`
|
||||
|
||||
#### WebUI Workflow:
|
||||
|
||||
Administrators can specify required auth indicator on service settings page.
|
||||
As default no auth indicator is specified which means all pre-auth mechanism is accepted.
|
||||
|
||||
### Ticket lifecycle policy
|
||||
|
||||
Administrators may want to define different ticket expiration and renewal values
|
||||
as well as ticket flags based on the type of the authentication conducted.
|
||||
|
||||
e.g. the lifetime of the OTP based ticket can be longer than for a single-factor
|
||||
|
||||
Tickets without an authentication indicator will have the default lifetime / renewtime.
|
||||
|
||||
#### CLI Workflow:
|
||||
|
||||
Administrators can specify max life and renew for each auth indicator and global default via `ipa krbtpolicy-mod` command.
|
||||
|
||||
e.g. `ipa krbtpolicy-mod --otp-maxlife=604800 --pkinit-maxlife=604800`
|
||||
|
||||
Current `--maxlife` and `--maxrenew` options for `ipa krbtpolicy-mod` will set the default max life / renew respectively.
|
||||
|
||||
After this, the output for `ipa krbtpolicy-show` will look like:
|
||||
|
||||
```
|
||||
Max life: 86400
|
||||
OTP max life: 604800
|
||||
PKINIT max life: 604800
|
||||
Max renew: 604800
|
||||
```
|
||||
|
||||
#### WebUI Workflow:
|
||||
|
||||
In Policy/Kerberos Ticket Policy tab, there is a table
|
||||
where administrators can specify max renew and life for each supported auth indicator.
|
||||
|
||||
### Ticket lifetime jitter
|
||||
|
||||
Ticket lifetimes can be jittered so that renewals / re-issues do not overwhelm the KDC at a certain moment.
|
||||
The feature is enabled automatically so that we can avoid triggering an LDAP query on every `AS_REQ` and `TGS_REQ`.
|
||||
|
||||
## Implementation
|
||||
|
||||
Kerberos policy, as krb5 presents it, consists of two interfaces:
|
||||
the authentication indicator attributes and the kdcpolicy plugin.
|
||||
Authentication indicator attributes allow us to make boolean access choices
|
||||
(i.e. allow or deny service principal requests) on the KDC based on configuration in the Kerberos Database (KDB).
|
||||
The kdcpolicy plugin is a much more powerful hook, allowing refinement of the request itself rather than
|
||||
a solely boolean decision.
|
||||
|
||||
Connection Policy can be implemented with authentication indicator attribute in krb5 alone,
|
||||
but ticket lifecycle policy will require LDAP to store relations between authentication indicators
|
||||
and lifetime information. We have global ticket lifetime and renew time setting stored as attribute
|
||||
`krbmaxticketlife` and `krbmaxrenewableage` inside the `cn=$REALM,cn=kerberos,$SUFFIX` subtree,
|
||||
which represents the default lifetime policy.
|
||||
|
||||
Two new multi-valued attributes are added to store an authentication
|
||||
indicator-specific maximum ticket life and ticket's maximum renewable age. The
|
||||
type of authentication indicator is specified as LDAP attribute option:
|
||||
|
||||
```
|
||||
krbAuthIndMaxTicketLife;otp: 604800
|
||||
krbAuthIndMaxRenewableAge;pkinit: 604800
|
||||
```
|
||||
|
||||
They are stored in the same policy object in LDAP.
|
||||
130
doc/designs/membermanager.md
Normal file
130
doc/designs/membermanager.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# Member Manager for group membership
|
||||
|
||||
## Overview
|
||||
|
||||
A member manager is a principal that is able to manage members of a
|
||||
group. Member managers are able to add new members to a group or remove
|
||||
existing members from a group. They cannot modify additional attributes
|
||||
of a group as a part of the member manager role.
|
||||
|
||||
Member management is implemented for *user groups* and *host groups*.
|
||||
Membership can be managed by users or user groups. Member managers are
|
||||
independent from members. A principal can be a member manager of a
|
||||
group without being a member of a group.
|
||||
|
||||
|
||||
## Use Cases
|
||||
|
||||
An administrator can use member management feature to delegate some
|
||||
control over user groups and host groups to users. For example a
|
||||
project manager is now able to add new team members to a project group.
|
||||
|
||||
A NFS admin with member management capability for a host group is able
|
||||
to indirectly influence an HBAC rules and control which hosts can
|
||||
connect to an NFS file share.
|
||||
|
||||
## Implementation
|
||||
|
||||
The user group commands and host group commands are extended to handle
|
||||
member managers. The plugin classes grow two additional sub commands,
|
||||
one for adding and one for removing member managers. The show command
|
||||
prints member manager users and member manager groups. The find command
|
||||
can search by member manager.
|
||||
|
||||
Member managers are stored in a new LDAP attribute ``memberManager``
|
||||
with OID 2.16.840.1.113730.3.8.23.1. It is multi-valued and contains
|
||||
DNs of users and groups which can manage members of the group. The
|
||||
attribute can be added to entries with object class ``ipaUserGroup``
|
||||
or ``ipaHostGroup``. The attribute is indexed and its membership
|
||||
controlled by referential integrity postoperation plugin.
|
||||
New userattr ACIs grant principals with user DN or group DN in
|
||||
``memberManager`` write permission to the ``member`` attribute of the
|
||||
group.
|
||||
|
||||
The ``memberManager`` attribute is protected by the generic read and
|
||||
modify permissions for each type of group. It is readable by everybody
|
||||
with ``System: Read Groups`` / ``System: Read Hostgroups`` permission
|
||||
and writable by everybody with ``System: Modify Groups`` /
|
||||
``System: Modify Hostgroups`` permission.
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
Add example user and groups:
|
||||
|
||||
```
|
||||
$ kinit admin
|
||||
$ ipa user-add john --first John --last Doe --random
|
||||
$ ipa user-add tom --first Tom --last Doe --random
|
||||
$ ipa group-add project
|
||||
$ ipa group-add project_admins
|
||||
```
|
||||
|
||||
Make user and group member managers:
|
||||
|
||||
```
|
||||
$ ipa group-add-member-manager project --users=john
|
||||
$ ipa group-add-member-manager project --groups=project_admins
|
||||
```
|
||||
|
||||
Show group:
|
||||
|
||||
```
|
||||
$ ipa group-show project
|
||||
Group name: project
|
||||
GID: 787600003
|
||||
Membership managed by groups: project_admins
|
||||
Membership managed by users: john
|
||||
```
|
||||
|
||||
Find groups by member managers:
|
||||
|
||||
```
|
||||
$ ipa group-find --membermanager-users=john
|
||||
---------------
|
||||
1 group matched
|
||||
---------------
|
||||
Group name: project
|
||||
GID: 787600003
|
||||
----------------------------
|
||||
Number of entries returned 1
|
||||
----------------------------
|
||||
$ ipa group-find --membermanager-groups=project_admins
|
||||
---------------
|
||||
1 group matched
|
||||
---------------
|
||||
Group name: project
|
||||
GID: 787600003
|
||||
----------------------------
|
||||
Number of entries returned 1
|
||||
----------------------------
|
||||
```
|
||||
|
||||
Use member management capability:
|
||||
|
||||
```
|
||||
$ kinit john
|
||||
$ ipa group-add-member project --users=tom
|
||||
Group name: project
|
||||
GID: 787600003
|
||||
Member users: tom
|
||||
Membership managed by groups: project_admins
|
||||
Membership managed by users: john
|
||||
-------------------------
|
||||
Number of members added 1
|
||||
-------------------------
|
||||
```
|
||||
|
||||
Remove member management capability:
|
||||
|
||||
```
|
||||
$ kinit admin
|
||||
$ ipa group-remove-member-manager project --groups=project_admins
|
||||
Group name: project
|
||||
GID: 787600003
|
||||
Member users: tom
|
||||
Membership managed by users: john
|
||||
---------------------------
|
||||
Number of members removed 1
|
||||
---------------------------
|
||||
```
|
||||
Reference in New Issue
Block a user