From a6dc5b912fc2f6f7451a54abe6169515b394e669 Mon Sep 17 00:00:00 2001 From: Margo Crawford Date: Wed, 28 Jul 2021 14:35:29 -0700 Subject: [PATCH 1/3] Document how to configure the ActiveDirectoryIdentityProvider --- ...nfigure-supervisor-with-activedirectory.md | 153 ++++++++++++++++++ .../active-directory-configuration.md | 66 ++++++++ 2 files changed, 219 insertions(+) create mode 100644 site/content/docs/howto/configure-supervisor-with-activedirectory.md create mode 100644 site/content/docs/reference/active-directory-configuration.md diff --git a/site/content/docs/howto/configure-supervisor-with-activedirectory.md b/site/content/docs/howto/configure-supervisor-with-activedirectory.md new file mode 100644 index 000000000..d86383e76 --- /dev/null +++ b/site/content/docs/howto/configure-supervisor-with-activedirectory.md @@ -0,0 +1,153 @@ +--- +title: Configure the Pinniped Supervisor to use Microsoft Active Directory as an ActiveDirectoryIdentityProvider +description: Set up the Pinniped Supervisor to use Microsoft Active Directory +cascade: + layout: docs +menu: + docs: + name: Configure Supervisor With Active Directory + weight: 110 + parent: howtos +--- +The Supervisor is an [OpenID Connect (OIDC)](https://openid.net/connect/) issuer that supports connecting a single +"upstream" identity provider to many "downstream" cluster clients. + +This guide shows you how to configure the Supervisor so that users can authenticate to their Kubernetes +cluster using their identity from Active Directory. + +## Prerequisites + +This how-to guide assumes that you have already [installed the Pinniped Supervisor]({{< ref "install-supervisor" >}}) with working ingress, +and that you have [configured a FederationDomain to issue tokens for your downstream clusters]({{< ref "configure-supervisor" >}}). + +## Configure the Supervisor cluster + +Create an [ActiveDirectoryIdentityProvider](https://github.com/vmware-tanzu/pinniped/blob/main/generated/1.20/README.adoc#activedirectoryidentityprovider) in the same namespace as the Supervisor. + +### ActiveDirectoryIdentityProvider with default options + +This ActiveDirectoryIdentityProvider uses all the default configuration options. + +Learn more about the default configuration [here]({{< ref "../reference/active-directory-configuration">}}) + +```yaml +apiVersion: idp.supervisor.pinniped.dev/v1alpha1 +kind: ActiveDirectoryIdentityProvider +metadata: + name: my-active-directory-idp + namespace: pinniped-supervisor +spec: + + # Specify the host of the Active Directory server. + host: "activedirectory.example.com:636" + + # Specify the name of the Kubernetes Secret that contains your Active Directory + # bind account credentials. This service account will be used by the + # Supervisor to perform LDAP user and group searches. + bind: + secretName: "active-directory-bind-account" + +--- + +apiVersion: v1 +kind: Secret +metadata: + name: active-directory-bind-account + namespace: pinniped-supervisor +type: kubernetes.io/basic-auth +stringData: + + # The dn (distinguished name) of your Active Directory bind account. + username: "CN=Bind User,OU=Users,DC=activedirectory,DC=example,dc=com" + + # The password of your Active Directory bind account. + password: "YOUR_PASSWORD" +``` + +If you've saved this into a file `activedirectory.yaml`, then install it into your cluster using: + +```sh +kubectl apply -f activedirectory.yaml +``` + +Once your ActiveDirectoryIdentityProvider has been created, you can validate your configuration by running: + +```sh +kubectl describe ActiveDirectoryIdentityProvider -n pinniped-supervisor my-active-directory-idp +``` + +Look at the `status` field. If it was configured correctly, you should see `phase: Ready`. + +### (Optional) Configure the ActiveDirectoryIdentityProvider with custom options + +You can also override the default `userSearch` and `groupSearch` options with other values. + +```yaml +apiVersion: idp.supervisor.pinniped.dev/v1alpha1 +kind: ActiveDirectoryIdentityProvider +metadata: + name: my-active-directory-idp + namespace: pinniped-supervisor +spec: + + # Specify the host of the Active Directory server. + host: "activedirectory.example.com:636" + + # Specify how to search for the username when an end-user tries to log in + # using their username and password. + userSearch: + + # Specify the root of the user search. + base: "OU=my-department,OU=Users,DC=activedirectory,DC=example,DC=com" + + # Specify how to filter the search to find the specific user by username. + # "{}" will be replaced # by the username that the end-user had typed + # when they tried to log in. + filter: "&(objectClass=person)(userPrincipleName={})" + + # Specify which fields from the user entry should be used upon + # successful login. + attributes: + + # Specifies the name of the attribute in the LDAP entry whose + # value shall become the username of the user after a successful + # authentication. + username: "mail" + + # Specifies the name of the attribute in the LDAP entry whose + # value shall be used to uniquely identify the user within this + # LDAP provider after a successful authentication. + uid: "objectSid" + + # Specify how to search for the group membership of an end-user during login. + groupSearch: + + # Specify the root of the group search. This may be a different subtree of + # the LDAP database compared to the user search + base: "ou=Groups,DC=activedirectory,DC=example,DC=com" + + # Specify the search filter which should be applied when searching for + # groups for a user. "{}" will be replaced by the dn (distinguished + # name) of the user entry found as a result of the user search. + filter: "&(objectClass=group)(member={})" + + # Specify which fields from each group entry should be used upon + # successful login. + attributes: + + # Specify the name of the attribute in the LDAP entries whose value + # shall become a group name in the user’s list of groups after a + # successful authentication. + groupName: "dn" + + # Specify the name of the Kubernetes Secret that contains your Active Directory + # bind account credentials. This service account will be used by the + # Supervisor to perform LDAP user and group searches. + bind: + secretName: "active-directory-bind-account" +``` + +## Next steps + +Next, [configure the Concierge to validate JWTs issued by the Supervisor]({{< ref "configure-concierge-supervisor-jwt" >}})! +Then you'll be able to log into those clusters as your users from Active Directory. diff --git a/site/content/docs/reference/active-directory-configuration.md b/site/content/docs/reference/active-directory-configuration.md new file mode 100644 index 000000000..cd96f4f7c --- /dev/null +++ b/site/content/docs/reference/active-directory-configuration.md @@ -0,0 +1,66 @@ +--- +title: Active Directory Configuration +description: See the default configuration values for the ActiveDirectoryIdentityProvider. +cascade: + layout: docs +menu: + docs: + name: Active Directory Configuration + weight: 10 + parent: reference +--- + + +### `spec.userSearch.base` + +*Default Behavior*: Queries the Active Directory host for the [defaultNamingContext](https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse). + +*Implications*: Searches your entire domain for users. It may make sense to specify a subtree as a search base if you wish to exclude some users for security reasons or to make searches faster. + + +### `spec.userSearch.attributes.username` + +*Default Behavior*: The `samAccountName` attribute will become the user's Kubernetes username. + +### `spec.userSearch.attributes.uid` +*Default Behavior*: The `objectGUID` attribute will be used to uniquely identify users. + +### `spec.userSearch.filter` +*Default Behavior*: +``` +"(&(objectClass=person)(!(objectClass=computer))(!(showInAdvancedViewOnly=TRUE))(|(sAMAccountName={})(mail={}))(sAMAccountType=805306368))" +``` + +Requires the following of the Active Directory entry of the user specified: +* is a person. +* is not a computer. +* is not shown in advanced view only (which would likely mean its a system created service account with advanced permissions). +* either the `sAMAccountName` or the `mail` attribute matches the input username. +* the `sAMAccountType` is for a normal user account. + +### `spec.groupSearch.base` + +*Default Behavior*: Queries the Active Directory host for the [defaultNamingContext](https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse). + +*Implications*: Searches your entire domain for groups. It may make sense to specify a subtree as a search base if you wish to exclude some groups for security reasons or to make searches faster. + +### `spec.groupSearch.attributes.groupName` +*Default Behavior*: The `sAMAccountName` attributes of the groups will become their groups in Kubernetes. + +### `spec.groupSearch.filter` + +*Default Behavior*: +``` +(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})) +``` +Requires the following of the Active Directory entrys that will represent the groups: +* is a group. +* has a member that matches the DN of the user we successfully logged in as, including indirectly through nested groups. + +*Implications*: Nested group search may be slow. If you are having performance issues during login, you can change the filter to the following: +``` +(&(objectClass=group)(member={})) +``` + + + From cec3c2133af1bf69577874366a6699e59f27c2da Mon Sep 17 00:00:00 2001 From: Margo Crawford Date: Thu, 19 Aug 2021 16:27:43 -0700 Subject: [PATCH 2/3] Update with new default values --- .../howto/configure-supervisor-with-activedirectory.md | 2 +- .../docs/reference/active-directory-configuration.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/site/content/docs/howto/configure-supervisor-with-activedirectory.md b/site/content/docs/howto/configure-supervisor-with-activedirectory.md index d86383e76..af852902e 100644 --- a/site/content/docs/howto/configure-supervisor-with-activedirectory.md +++ b/site/content/docs/howto/configure-supervisor-with-activedirectory.md @@ -117,7 +117,7 @@ spec: # Specifies the name of the attribute in the LDAP entry whose # value shall be used to uniquely identify the user within this # LDAP provider after a successful authentication. - uid: "objectSid" + uid: "objectGUID" # Specify how to search for the group membership of an end-user during login. groupSearch: diff --git a/site/content/docs/reference/active-directory-configuration.md b/site/content/docs/reference/active-directory-configuration.md index cd96f4f7c..c77263641 100644 --- a/site/content/docs/reference/active-directory-configuration.md +++ b/site/content/docs/reference/active-directory-configuration.md @@ -20,7 +20,7 @@ menu: ### `spec.userSearch.attributes.username` -*Default Behavior*: The `samAccountName` attribute will become the user's Kubernetes username. +*Default Behavior*: The `userPrincipalName` attribute will become the user's Kubernetes username. ### `spec.userSearch.attributes.uid` *Default Behavior*: The `objectGUID` attribute will be used to uniquely identify users. @@ -28,14 +28,14 @@ menu: ### `spec.userSearch.filter` *Default Behavior*: ``` -"(&(objectClass=person)(!(objectClass=computer))(!(showInAdvancedViewOnly=TRUE))(|(sAMAccountName={})(mail={}))(sAMAccountType=805306368))" +"(&(objectClass=person)(!(objectClass=computer))(!(showInAdvancedViewOnly=TRUE))(|(sAMAccountName={})(mail={})(userPrincipalName={}))(sAMAccountType=805306368))" ``` Requires the following of the Active Directory entry of the user specified: * is a person. * is not a computer. * is not shown in advanced view only (which would likely mean its a system created service account with advanced permissions). -* either the `sAMAccountName` or the `mail` attribute matches the input username. +* either the `sAMAccountName`, the `userPrincipalName`, or the `mail` attribute matches the input username. * the `sAMAccountType` is for a normal user account. ### `spec.groupSearch.base` @@ -45,7 +45,7 @@ Requires the following of the Active Directory entry of the user specified: *Implications*: Searches your entire domain for groups. It may make sense to specify a subtree as a search base if you wish to exclude some groups for security reasons or to make searches faster. ### `spec.groupSearch.attributes.groupName` -*Default Behavior*: The `sAMAccountName` attributes of the groups will become their groups in Kubernetes. +*Default Behavior*: The attribute that will become the user's groups in Kubernetes will look like `sAMAccountName@domain` (where domain is constructed from the domain components of the group). ### `spec.groupSearch.filter` From 44e5e9d8c96e2ff894afa96a55c39a1ffb160e51 Mon Sep 17 00:00:00 2001 From: Margo Crawford Date: Thu, 26 Aug 2021 17:02:56 -0700 Subject: [PATCH 3/3] Add sentence about api docs --- site/content/docs/reference/active-directory-configuration.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/site/content/docs/reference/active-directory-configuration.md b/site/content/docs/reference/active-directory-configuration.md index c77263641..f7843954b 100644 --- a/site/content/docs/reference/active-directory-configuration.md +++ b/site/content/docs/reference/active-directory-configuration.md @@ -10,6 +10,8 @@ menu: parent: reference --- +This describes the default values for the `ActiveDirectoryIdentityProvider` user and group search. For more about `ActiveDirectoryIdentityProvider` +configuration, see [the API reference documentation](https://github.com/vmware-tanzu/pinniped/blob/main/generated/1.20/README.adoc#activedirectoryidentityprovider). ### `spec.userSearch.base`