Kanidm book review 6 (#800)

* change capitalization on section headings, and some terminology, small wording tweaks
* more small corrections, line breaks, capitalization, small wording changes
* minor corrections, punctuation, wording
* NAS = Network Access Server
This commit is contained in:
Carla Schroder 2022-06-01 18:09:02 -07:00 committed by GitHub
parent 0b3fc8caf0
commit e5b37dfe20
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 193 additions and 156 deletions

View file

@ -1,7 +1,8 @@
# Client tools
To interact with Kanidm as an administrator, you'll need to use our command line tools.
If you haven't installed them yet, [install them now](installing_client_tools.mdc).
To interact with Kanidm as an administrator, you'll need to use our command
line tools. If you haven't installed them yet,
[install them now](installing_client_tools.mdc).
## Kanidm configuration

View file

@ -1,33 +1,36 @@
# LDAP
While many applications can support systems like SAML or OAuth, many do not. LDAP
has been the "lingua franca" of authentication for many years, with almost
every application in the world being able to search and bind to LDAP. As there
are still many of these in the world, Kanidm can host a read-only
LDAP interface.
While many applications can support systems like Security Assertion Markup
Language (SAML), or Open Authorization (OAuth), many do not.
Lightweight Directory Access Protocol (LDAP) has been the "lingua franca" of
authentication for many years, with almost every application in the world being
able to search and bind to LDAP. As many organization still rely on LDAP, Kanidm
can host a read-only LDAP interface.
> **WARNING** The LDAP server in Kanidm is not RFC compliant. This
> is intentional, as Kanidm wants to cover the common use case (simple bind and search).
> is intentional, as Kanidm wants to cover the common use case,
> simple bind and search.
## What is LDAP
LDAP is a protocol to read data from a directory of information. It is not
a server, but a way to communicate to a server. There are many famous LDAP
implementations such as Active Directory, 389 Directory Server, DSEE,
FreeIPA and many others. Because it is a standard, applications can use
FreeIPA, and many others. Because it is a standard, applications can use
an LDAP client library to authenticate users to LDAP, given "one account" for
many applications - an IDM just like Kanidm!
## Data Mapping
Kanidm is not able to be mapped 100% to LDAP's objects. This is because LDAP
Kanidm cannot be mapped 100% to LDAP's objects. This is because LDAP
types are simple key-values on objects which are all UTF8 strings (or subsets
thereof) based on validation (matching) rules. Kanidm internally implements complex
data types such as tagging on SSH keys, or multi-value credentials. These can not
be represented in LDAP.
As well many of the structures in Kanidm don't correlate closely to LDAP. For example
Kanidm only has a gidnumber, where LDAP's schema's define uidnumber and gidnumber.
Many of the structures in Kanidm do not correlate closely to LDAP. For example
Kanidm only has a GID number, where LDAP's schemas define both a UID number and a
GID number.
Entries in the database also have a specific name in LDAP, related to their path
in the directory tree. Kanidm is a flat model, so we have to emulate some tree-like
@ -36,54 +39,55 @@ elements, and ignore others.
For this reason, when you search the LDAP interface, Kanidm will make some mapping decisions.
* The domain_info object becomes the suffix root.
* All other entries are direct subordinates of the domain_info for DN purposes
* DN's are generated from the attributes naming attributes
* Bind DN's can be remapped and rewritten, and may not even be a DN during bind.
* The Kanidm domain name is used to generate the basedn.
* All other entries are direct subordinates of the domain_info for DN purposes.
* Distinguished Names (DNs) are generated from the attributes naming attributes.
* Bind DNs can be remapped and rewritten, and may not even be a DN during bind.
* The Kanidm domain name is used to generate the base DN.
* The '\*' and '+' operators can not be used in conjuction with attribute lists in searches.
These decisions were made to make the path as simple and effective as possible,
relying more on the Kanidm query and filter system than attempting to generate a tree-like
representation of data. As almost all clients can use filters for entry selection
we don't believe this is a limitation for consuming applications.
we don't believe this is a limitation for the consuming applications.
## Security
### TLS
StartTLS is not supported due to security risks. LDAPS is the only secure method
of communicating to any LDAP server. Kanidm if configured with certificates will
of communicating to any LDAP server. Kanidm, if configured with certificates, will
use them for LDAPS (and will not listen on a plaintext LDAP port). If no certificates exist
Kanidm will listen on a plaintext LDAP port, and you MUST TLS terminate in front
of the Kanidm system to secure data and authentication.
### Access Controls
LDAP only supports password authentication. As LDAP is used heavily in posix environments
LDAP only supports password authentication. As LDAP is used heavily in POSIX environments
the LDAP bind for any DN will use its configured posix password.
As the posix password is not equivalent in strength to the primary credentials of Kanidm
(which may be MFA), the LDAP bind does not grant rights to elevated read permissions.
All binds have the permissions of "Anonymous" (even if the anonymous account is locked).
As the POSIX password is not equivalent in strength to the primary credentials of Kanidm
(which may be multi-factor authentication, MFA), the LDAP bind does not grant
rights to elevated read permissions. All binds have the permissions of "Anonymous"
even if the anonymous account is locked.
## Server Configuration
To configure Kanidm to provide LDAP you add the argument to the `server.toml` configuration:
To configure Kanidm to provide LDAP, add the argument to the `server.toml` configuration:
ldapbindaddress = "127.0.0.1:3636"
You should configure TLS certificates and keys as usual - LDAP will re-use the webserver TLS
material.
You should configure TLS certificates and keys as usual - LDAP will re-use the Web
server TLS material.
## Showing LDAP entries and attribute maps
## Showing LDAP Entries and Attribute Maps
By default Kanidm is limited in what attributes are generated or remaped into LDAP entries. However,
the server internally contains a map of extended attribute mappings for application specific requests
that must be satisfied.
By default Kanidm is limited in what attributes are generated or remapped into
LDAP entries. However, the server internally contains a map of extended attribute
mappings for application specific requests that must be satisfied.
An example is that some applications expect and require a 'CN' value, even though Kanidm does not
provide it. If the application is unable to be configured to accept "name" it may be necessary
to use Kanidm's mapping feature. Today these are compiled into the server so you may need to open
to use Kanidm's mapping feature. Currently these are compiled into the server, so you may need to open
an issue with your requirements.
To show what attribute maps exists for an entry you can use the attribute search term '+'.
@ -93,8 +97,8 @@ To show what attribute maps exists for an entry you can use the attribute search
# To show all attribute maps
ldapsearch ... -x '(name=admin)' '+'
Attributes that are in the map, can be requested explicitly, and this can be combined with requesting
kanidm native attributes.
Attributes that are in the map can be requested explicitly, and this can be combined with requesting
Kanidm native attributes.
ldapsearch ... -x '(name=admin)' cn objectClass displayname memberof
@ -119,12 +123,12 @@ This can be queried with:
entryuuid: 22a65b6c-80c8-4e1a-9b76-3f3afdff8400
It is recommended that client applications filter accounts that can login with '(class=account)'
and groups with '(class=group)'. If possible, group membership is defined in rfc2307bis or
and groups with '(class=group)'. If possible, group membership is defined in RFC2307bis or
Active Directory style. This means groups are determined from the "memberof" attribute which contains
a DN to a group.
LDAP binds can use any unique identifier of the account. The following are all valid bind DN's for
the object listed above (if it was a posix account that is).
LDAP binds can use any unique identifier of the account. The following are all valid bind DNs for
the object listed above (if it was a POSIX account, that is).
ldapwhoami ... -x -D 'name=test1'
ldapwhoami ... -x -D 'spn=test1@example.com'
@ -147,9 +151,8 @@ All give the same error:
This is despite the fact:
* The first command is a certificate validation error
* The second is a missing LDAPS on a TLS port
* The third is an incorrect port
* The first command is a certificate validation error.
* The second is a missing LDAPS on a TLS port.
* The third is an incorrect port.
To diagnose errors like this, you may need to add "-d 1" to your LDAP commands or client.

View file

@ -1,36 +1,44 @@
# PAM and nsswitch
[PAM](http://linux-pam.org) and [nsswitch](https://en.wikipedia.org/wiki/Name_Service_Switch) are the core mechanisms used by Linux and BSD clients to resolve identities from an IDM service like Kanidm into accounts that can be used on the machine for various interactive tasks.
[PAM](http://linux-pam.org) and [nsswitch](https://en.wikipedia.org/wiki/Name_Service_Switch)
are the core mechanisms used by Linux and BSD clients to resolve identities from an IDM service
like Kanidm into accounts that can be used on the machine for various interactive tasks.
## The UNIX daemon
## The UNIX Daemon
Kanidm provides a UNIX daemon that runs on any client that wants to use PAM and nsswitch integration. This is provided as the daemon can cache the accounts for users who have unreliable networks or leave the site where Kanidm is. The cache is also able to cache missing-entry responses to reduce network traffic and main server load.
Kanidm provides a UNIX daemon that runs on any client that wants to use PAM and nsswitch integration.
The daemon can cache the accounts for users who have unreliable networks, or who leave
the site where Kanidm is hosted. The daemon is also able to cache missing-entry responses to reduce network
traffic and main server load.
Additionally, the daemon means that the PAM and nsswitch integration libraries can be small, helping to reduce the attack surface of the machine. Similarly, a tasks daemon is available that can create home directories on first login and supports several features related to aliases and links to these home directories.
Additionally, running the daemon means that the PAM and nsswitch integration libraries can be small,
helping to reduce the attack surface of the machine. Similarly, a tasks daemon is available that can
create home directories on first login and supports several features related to aliases and links to
these home directories.
We recommend you install the client daemon from your system package manager.
We recommend you install the client daemon from your system package manager:
# OpenSUSE
zypper in kanidm-unixd-clients
# Fedora
dnf install kanidm-unixd-clients
You can check the daemon is running on your Linux system with
You can check the daemon is running on your Linux system with:
systemctl status kanidm-unixd
You can check the privileged tasks daemon is running with
You can check the privileged tasks daemon is running with:
systemctl status kanidm-unixd-tasks
> **NOTE** The `kanidm_unixd_tasks` daemon is not required for PAM and nsswitch functionality.
> If disabled, your system will function as usual. It is however recommended due to the features
> If disabled, your system will function as usual. It is, however, recommended due to the features
> it provides supporting Kanidm's capabilities.
Both unixd daemons use the connection configuration from /etc/kanidm/config. This is the covered in
[client_tools](./client_tools.md#kanidm-configuration).
You can also configure some unixd specific options with the file /etc/kanidm/unixd.
You can also configure some unixd-specific options with the file /etc/kanidm/unixd:
pam_allowed_login_groups = ["posix_group"]
default_shell = "/bin/sh"
@ -40,11 +48,11 @@ You can also configure some unixd specific options with the file /etc/kanidm/uni
uid_attr_map = "spn"
gid_attr_map = "spn"
The `pam_allowed_login_groups` defines a set of posix groups where membership of any of these
groups will be allowed to login via PAM. All posix users and groups can be resolved by nss
regardless of PAM login status. This may be a group name, spn or uuid.
`pam_allowed_login_groups` defines a set of POSIX groups where membership of any of these
groups will be allowed to login via PAM. All POSIX users and groups can be resolved by nss
regardless of PAM login status. This may be a group name, spn, or uuid.
`default_shell` is the default shell for users with none defined. Defaults to `/bin/sh`.
`default_shell` is the default shell for users. Defaults to `/bin/sh`.
`home_prefix` is the prepended path to where home directories are stored. Must end with
a trailing `/`. Defaults to `/home/`.
@ -52,7 +60,8 @@ a trailing `/`. Defaults to `/home/`.
`home_attr` is the default token attribute used for the home directory path. Valid
choices are `uuid`, `name`, `spn`. Defaults to `uuid`.
`home_alias` is the default token attribute used for generating symlinks pointing to the users
`home_alias` is the default token attribute used for generating symlinks
pointing to the user's
home directory. If set, this will become the value of the home path
to nss calls. It is recommended you choose a "human friendly" attribute here.
Valid choices are `none`, `uuid`, `name`, `spn`. Defaults to `spn`.
@ -60,8 +69,8 @@ Valid choices are `none`, `uuid`, `name`, `spn`. Defaults to `spn`.
> **NOTICE:**
> All users in Kanidm can change their name (and their spn) at any time. If you change
> `home_attr` from `uuid` you *must* have a plan on how to manage these directory renames
> in your system. We recommend that you have a stable id (like the uuid) and symlinks
> from the name to the uuid folder. Automatic support is provided for this via the unixd
> in your system. We recommend that you have a stable ID (like the UUID), and symlinks
> from the name to the UUID folder. Automatic support is provided for this via the unixd
> tasks daemon, as documented here.
`uid_attr_map` chooses which attribute is used for domain local users in presentation. Defaults
@ -70,9 +79,9 @@ to `spn`. Users from a trust will always use spn.
`gid_attr_map` chooses which attribute is used for domain local groups in presentation. Defaults
to `spn`. Groups from a trust will always use spn.
You can then check the communication status of the daemon as any user account.
You can then check the communication status of the daemon:
$ kanidm_unixd_status
kanidm_unixd_status
If the daemon is working, you should see:
@ -80,9 +89,11 @@ If the daemon is working, you should see:
If it is not working, you will see an error message:
[2020-02-14T05:58:10Z ERROR kanidm_unixd_status] Error -> Os { code: 111, kind: ConnectionRefused, message: "Connection refused" }
[2020-02-14T05:58:10Z ERROR kanidm_unixd_status] Error ->
Os { code: 111, kind: ConnectionRefused, message: "Connection refused" }
For more, see troubleshooting.
For more information, see the
[Troubleshooting](./pam_and_nsswitch.md#troubleshooting) section.
## nsswitch
@ -91,21 +102,22 @@ When the daemon is running you can add the nsswitch libraries to /etc/nsswitch.c
passwd: compat kanidm
group: compat kanidm
You can [create a user](./accounts_and_groups.md#creating-accounts) then [enable posix feature on the user](./posix_accounts.md#enabling-posix-attributes-on-accounts).
You can [create a user](./accounts_and_groups.md#creating-accounts) then
[enable POSIX feature on the user](./posix_accounts.md#enabling-posix-attributes-on-accounts).
You can then test that the posix extended user is able to be resolved with:
You can then test that the POSIX extended user is able to be resolved with:
$ getent passwd <account name>
$ getent passwd testunix
getent passwd <account name>
getent passwd testunix
testunix:x:3524161420:3524161420:testunix:/home/testunix:/bin/sh
You can also do the same for groups.
$ getent group <group name>
$ getent group testgroup
getent group <group name>
getent group testgroup
testgroup:x:2439676479:testunix
> **HINT** Remember to also create unix password with something like
> **HINT** Remember to also create a UNIX password with something like
> `kanidm account posix set_password --name idm_admin demo_user`.
> Otherwise there will be no credential for the account to authenticate.
@ -113,24 +125,27 @@ You can also do the same for groups.
> **WARNING:** Modifications to PAM configuration *may* leave your system in a state
> where you are unable to login or authenticate. You should always have a recovery
> shell open while making changes (ie root), or have access to single-user mode
> shell open while making changes (for example, root), or have access to single-user mode
> at the machine's console.
PAM (Pluggable Authentication Modules) is how a unix-like system allows users to authenticate
and be authorised to start interactive sessions. This is configured through a stack of modules
that are executed in order to evaluate the request. This is done through a series of steps
where each module may request or reuse authentication token information.
Pluggable Authentication Modules (PAM) is the mechanism a UNIX-like system
that authenticates users, and to control access to some resources. This is
configured through a stack of modules
that are executed in order to evaluate the request, and then each module may
request or reuse authentication token information.
### Before you start
### Before You Start
You *should* backup your /etc/pam.d directory from its original state as you *may* change the
PAM config in a way that will cause you to be unable to authenticate to your machine.
You *should* backup your /etc/pam.d directory from its original state as you
*may* change the PAM configuration in a way that will not allow you
to authenticate to your machine.
cp -a /etc/pam.d /root/pam.d.backup
### SUSE / OpenSUSE
To configure PAM on suse you must modify four files, which control the various stages of authentication.
To configure PAM on suse you must modify four files, which control the
various stages of authentication:
/etc/pam.d/common-account
/etc/pam.d/common-auth
@ -186,7 +201,8 @@ The content should look like:
session optional pam_env.so
> **WARNING:** Ensure that `pam_mkhomedir` or `pam_oddjobd` are *not* present in any stage of your
> pam configuration, as they interfere with the correct operation of the kanidm tasks daemon.
> PAM configuration, as they interfere with the correct operation of the
> Kanidm tasks daemon.
### Fedora / CentOS
@ -194,13 +210,15 @@ The content should look like:
> run the daemon with permissive mode for the unconfined_service_t daemon type. To do this run:
> `semanage permissive -a unconfined_service_t`. To undo this run `semanage permissive -d unconfined_service_t`.
>
> You may also need to run `audit2allow` for sshd and other types to be able to access the unix daemon sockets.
> You may also need to run `audit2allow` for sshd and other types to be able to access the UNIX daemon sockets.
These files are managed by authselect as symlinks. You can either work with authselect, or remove the symlinks first.
These files are managed by authselect as symlinks. You can either work with
authselect, or remove the symlinks first.
#### Without authselect
If you just remove the symlinks:
edit the content.
Edit the content.
# /etc/pam.d/password-auth
auth required pam_env.so
@ -263,11 +281,18 @@ edit the content.
#### With authselect
To work with authselect:
You will need to [create a new profile](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_authentication_and_authorization_in_rhel/configuring-user-authentication-using-authselect_configuring-authentication-and-authorization-in-rhel#creating-and-deploying-your-own-authselect-profile_configuring-user-authentication-using-authselect). First run
You will need to
[create a new profile](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_authentication_and_authorization_in_rhel/configuring-user-authentication-using-authselect_configuring-authentication-and-authorization-in-rhel#creating-and-deploying-your-own-authselect-profile_configuring-user-authentication-using-authselect).
<!--TODO this URL is too short -->
First run the following command:
authselect create-profile kanidm -b sssd
A new folder, /etc/authselect/custom/kanidm, should be created. Inside that folder, create or overwrite the following 3 files: nsswitch.conf, password-auth, system-auth. password-auth and system-auth should be the same as above. nsswitch should be modified for your usecase, but a working example looks like this:
A new folder, /etc/authselect/custom/kanidm, should be created. Inside that folder, create or
overwrite the following three files: nsswitch.conf, password-auth, system-auth.
password-auth and system-auth should be the same as above. nsswitch should be
modified for your use case. A working example looks like this:
passwd: compat kanidm sss files systemd
group: compat kanidm sss files systemd
@ -285,7 +310,7 @@ A new folder, /etc/authselect/custom/kanidm, should be created. Inside that fold
publickey: files
rpc: files
finally run
Then run:
authselect select custom/kanidm
@ -293,7 +318,7 @@ to update your profile.
## Troubleshooting
### Check POSIX-status of group and config
### Check POSIX-status of Group and Configuration
If authentication is failing via PAM, make sure that a list of groups is configured in `/etc/kanidm/unixd`:
@ -301,15 +326,18 @@ If authentication is failing via PAM, make sure that a list of groups is configu
pam_allowed_login_groups = ["example_group"]
```
Check the status of the group with `kanidm group posix show example_group`. If you get something similar to the below:
Check the status of the group with `kanidm group posix show example_group`.
If you get something similar to the following example:
```shell
> kanidm group posix show example_group
Using cached token for name idm_admin
Error -> Http(500, Some(InvalidAccountState("Missing class: account && posixaccount OR group && posixgroup")), "b71f137e-39f3-4368-9e58-21d26671ae24")
Error -> Http(500, Some(InvalidAccountState("Missing class: account && posixaccount OR group && posixgroup")),
"b71f137e-39f3-4368-9e58-21d26671ae24")
```
POSIX-enable the group with `kanidm group posix set example_group`. You should get a result similar to this when you search for your group name:
POSIX-enable the group with `kanidm group posix set example_group`. You should get a result similar
to this when you search for your group name:
```shell
> kanidm group posix show example_group
@ -322,7 +350,7 @@ Also, ensure the target user is in the group by running:
> kanidm group list_members example_group
```
### Increase logging
### Increase Logging
For the unixd daemon, you can increase the logging with:
@ -341,28 +369,29 @@ To debug the pam module interactions add `debug` to the module arguments such as
auth sufficient pam_kanidm.so debug
### Check the socket permissions
### Check the Socket Permissions
Check that the `/var/run/kanidm-unixd/sock` is 777, and that non-root readers can see it with
Check that the `/var/run/kanidm-unixd/sock` has permissions mode 777, and that non-root readers can see it with
ls or other tools.
Ensure that `/var/run/kanidm-unixd/task_sock` is 700, and that it is owned by the kanidm unixd
process user.
Ensure that `/var/run/kanidm-unixd/task_sock` has permissions mode 700, and
that it is owned by the kanidm unixd process user.
### Check you can access the kanidm server
### Verify that You Can Access the Kanidm Server
You can check this with the client tools:
kanidm self whoami --name anonymous
### Ensure the libraries are correct.
### Ensure the Libraries are Correct
You should have:
/usr/lib64/libnss_kanidm.so.2
/usr/lib64/security/pam_kanidm.so
The exact path *may* change depending on your distribution, `pam_unixd.so` should be co-located with pam_kanidm.so so looking for it findable with:
The exact path *may* change depending on your distribution, `pam_unixd.so` should be co-located
with pam_kanidm.so. Look for it with the find command:
```
find /usr/ -name 'pam_unix.so'
@ -370,16 +399,17 @@ find /usr/ -name 'pam_unix.so'
For example, on a Debian machine, it's located in `/usr/lib/x86_64-linux-gnu/security/`.
### Increase connection timeout
### Increase Connection Timeout
In some high latency environments, you may need to increase the connection timeout. We set
In some high-latency environments, you may need to increase the connection timeout. We set
this low to improve response on LANs, but over the internet this may need to be increased.
By increasing the conn timeout, you will be able to operate on higher latency links, but
some operations may take longer to complete causing a degree of latency.
By increasing the conn_timeout, you will be able to operate on higher latency
links, but some operations may take longer to complete causing a degree of
latency.
By increasing the cache_timeout, you will need to refresh "less" but it may mean on an
account lockout or group change, that you need to wait until cache_timeout to see the effect
(this has security implications)
By increasing the cache_timeout, you will need to refresh less often, but it may result in an
account lockout or group change until cache_timeout takes effect. Note that this has security
implications:
# /etc/kanidm/unixd
# Seconds
@ -387,21 +417,20 @@ account lockout or group change, that you need to wait until cache_timeout to se
# Cache timeout
cache_timeout = 60
### Invalidate the cache
### Invalidate or Clear the Cache
You can invalidate the kanidm_unixd cache with:
$ kanidm_cache_invalidate
kanidm_cache_invalidate
You can clear (wipe) the cache with:
$ kanidm_cache_clear
kanidm_cache_clear
There is an important distinction between these two - invalidated cache items may still
be yielded to a client request if the communication to the main Kanidm server is not
possible. For example, you may have your laptop in a park without wifi.
Clearing the cache, however, completely wipes all local data about all accounts and groups.
If you are relying on this cached (but invalid data) you may lose access to your accounts until
If you are relying on this cached (but invalid) data, you may lose access to your accounts until
other communication issues have been resolved.

View file

@ -1,74 +1,77 @@
# RADIUS
RADIUS is a network protocol that is commonly used to allow wifi devices or
VPN's to authenticate users to a network boundary. While it should not be a
sole point of trust/authentication to an identity, it's still an important
control for improving barriers to attackers access to network resources.
Remote Authentication Dial In User Service (RADIUS) is a network protocol
that is commonly used to authenticate Wi-Fi devices or Virtual Private
Networks (VPNs). While it should not be a sole point of trust/authentication
to an identity, it's still an important control for protecting network resources.
Kanidm has a philosophy that each account can have multiple credentials which
are related to their devices and limited to specific resources. RADIUS is
are related to their devices, and limited to specific resources. RADIUS is
no exception and has a separate credential for each account to use for
RADIUS access.
## Disclaimer
It's worth noting some disclaimers about Kanidm's RADIUS integration here
It's worth noting some disclaimers about Kanidm's RADIUS integration.
### One Credential - One Account
Kanidm normally attempts to have credentials for each *device* and *application*
rather than the legacy model of one to one.
Kanidm normally attempts to have credentials for each *device* and
*application* rather than the legacy model of one to one.
The RADIUS protocol is only able to attest a *single* credential in an authentication
attempt, which limits us to storing a single RADIUS credential per account. However
despite this limitation, it still greatly improves the situation by isolating the
RADIUS credential from the primary or application credentials of the account. This
solves many common security concerns around credential loss or disclosure
and prevents rogue devices from locking out accounts as they attempt to
authenticate to wifi with expired credentials.
The RADIUS protocol is only able to attest a *single* credential in an
authentication attempt, which limits us to storing a single RADIUS credential
per account. However, despite this limitation, it still greatly improves the
situation by isolating the RADIUS credential from the primary or application
credentials of the account. This solves many common security concerns around
credential loss or disclosure, and prevents rogue devices from locking out
accounts as they attempt to authenticate to Wi-Fi with expired credentials.
### Cleartext Credential Storage
RADIUS offers many different types of tunnels and authentication mechanisms.
However, most client devices "out of the box" only attempt a single type when you select
a WPA2-Enterprise network: MSCHAPv2 with PEAP. This is a challenge-response protocol
that requires cleartext or NTLM credentials.
However, most client devices "out of the box" only attempt a single type when
a WPA2-Enterprise network is selected: MSCHAPv2 with PEAP. This is a
challenge-response protocol that requires clear text or Windows NT LAN
Manager (NTLM) credentials.
As MSCHAPv2 with PEAP is the only practical, universal RADIUS type supported
on all devices with "minimal" configuration, we consider it imperative
As MSCHAPv2 with PEAP is the only practical, universal RADIUS-type supported
on all devices with minimal configuration, we consider it imperative
that it MUST be supported as the default. Esoteric RADIUS types can be used
as well, but this is up to administrators to test and configure.
Due to this requirement, we must store the RADIUS material as cleartext or
NTLM hashes. It would be silly to think that NTLM is "secure" as it's md4
which is only an illusion of security.
Due to this requirement, we must store the RADIUS material as clear text or
NTLM hashes. It would be silly to think that NTLM is secure as it relies on
the obsolete and deprecated MD4 cryptographic hash, providing only an
illusion of security.
This means Kanidm stores RADIUS credentials in the database as cleartext.
This means Kanidm stores RADIUS credentials in the database as clear text.
We believe this is a reasonable decision and is a low risk to security as:
We believe this is a reasonable decision and is a low risk to security because:
* The access controls around RADIUS secrets by default are "strong", limited
* The access controls around RADIUS secrets by default are strong, limited
to only self-account read and RADIUS-server read.
* As RADIUS credentials are separate from the primary account credentials and have
no other rights, their disclosure is not going to lead to a full account compromise.
* Having the credentials in cleartext allows a better user experience as clients
can view the credentials at any time to enrol further devices.
* As RADIUS credentials are separate from the primary account credentials and
have no other rights, their disclosure is not going to lead to a full
account compromise.
* Having the credentials in clear text allows a better user experience as
clients can view the credentials at any time to enroll further devices.
## Account Credential Configuration
For an account to use RADIUS they must first generate a RADIUS secret unique to
that account. By default, all accounts can self-create this secret.
For an account to use RADIUS they must first generate a RADIUS secret unique
to that account. By default, all accounts can self-create this secret.
kanidm account radius generate_secret --name william william
kanidm account radius show_secret --name william william
## Account group configuration
## Account Group Configuration
Kanidm enforces that accounts which can authenticate to RADIUS must be a member
In Kanidm, accounts which can authenticate to RADIUS must be a member
of an allowed group. This allows you to define which users or groups may use
wifi or VPN infrastructure and gives a path for "revoking" access to the resources
through group management. The key point of this is that service accounts should
not be part of this group.
a Wi-Fi or VPN infrastructure, and provides a path for revoking access to the
resources through group management. The key point of this is that service
accounts should not be part of this group:
kanidm group create --name idm_admin radius_access_allowed
kanidm group add_members --name idm_admin radius_access_allowed william
@ -77,7 +80,7 @@ not be part of this group.
To read these secrets, the RADIUS server requires an account with the
correct privileges. This can be created and assigned through the group
"idm_radius_servers" which is provided by default.
"idm_radius_servers", which is provided by default.
kanidm account create --name admin radius_service_account "Radius Service Account"
kanidm group add_members --name admin idm_radius_servers radius_service_account
@ -127,7 +130,7 @@ The config.ini has the following template:
; ipaddr = # ipv4 or ipv6 address of the NAS
; secret = # Shared secret
A fully configured example is:
A fully configured example:
[kanidm_client]
; be sure to check the listening port is correct, it's the docker internal port
@ -165,25 +168,26 @@ You can then run the container with:
docker run --name radiusd -v ...:/data kanidm/radius:latest
Authentication can be tested through the client.localhost NAS configuration with:
Authentication can be tested through the client.localhost Network Access Server (NAS) configuration with:
docker exec -i -t radiusd radtest <username> badpassword 127.0.0.1 10 testing123
docker exec -i -t radiusd radtest <username> <radius show_secret value here> 127.0.0.1 10 testing123
Finally, to expose this to a wifi infrastructure, add your NAS in `config.ini`:
Finally, to expose this to a Wi-Fi infrastructure, add your NAS in `config.ini`:
[client.access_point]
ipaddr = <some ipadd>
secret = <random value>
And re-create/run your docker instance with `-p 1812:1812 -p 1812:1812/udp` ...
Then re-create/run your docker instance with `-p 1812:1812 -p 1812:1812/udp` ...
If you have any issues, check the logs from the radius output they tend to indicate the cause
of the problem. To increase the logging you can re-run your environment with debug enabled:
If you have any issues, check the logs from the RADIUS output, as they tend
to indicate the cause of the problem. To increase the logging level you can
re-run your environment with debug enabled:
docker rm radiusd
docker run --name radiusd -e DEBUG=True -i -t -v ...:/data kanidm/radius:latest
Note the radius container *is* configured to provide Tunnel-Private-Group-ID so if you wish to use
wifi assigned VLANs on your infrastructure, you can assign these by groups in the config.ini as
shown in the above examples.
Note the RADIUS container *is* configured to provide Tunnel-Private-Group-ID,
so if you wish to use Wi-Fi-assigned VLANs on your infrastructure, you can
assign these by groups in the config.ini as shown in the above examples.