Skip to content
Snippets Groups Projects
Forked from an inaccessible project.

NSS/PAM modules for OpenID Connect/OAuth2

nss-pam-oidc is a multi-purpose shared library that links Linux system authentication (PAM) and name resolution for users and groups (NSS) to an OAuth2 API.

It is "multi-purpose" because it builds a single shared object file exposing both the APIs of PAM and NSS. It can be used:

  • in /lib/security/pam_oidc.so as PAM module
  • in /lib/libnss_oidc.so as NSS database module
  • in /sbin/nss_pam_oidc_cached as caching daemon to speed up requests

System authentication (PAM module)

The following OAuth flows are implemented for system authentication:

  • Resource Owner Password Grant Flow

The following OAuth flows are on the roadmap for system authentication:

  • Authorization Code Grant Flow
  • Device Code Grant Flow

Resource Owner Password Grant Flow

Using this flow, the user is queried for their password as usual. The password is then used to acquire an access token.

If acquiring the token succeeds, the authentication is considered successful.

Athorization Code Grant Flow

Using this flow, the user is displayed a web page and logs in to it.

After login, the website returns an authorization token that is used to a cquire an access token.

This flow is only supported on graphical logins with display managers that support it.

Device Code Grant Flow

Using this flow, the user is displayed a short alpha-numeric code. They are required to open the backing website on another device and enter the code there.

While they do, the server is periodically polled, and an access token is acquired once the user has granted access on the other device.

Name resolution (NSS database)

An API endpoint on the OAuth-autenticated server can be used to retrieve information on users and groups. There are two modes the NSS database can operate in:

System-wide mode

The system-wide mode uses client credentials to access the API and to retrieve the full lists of available users and groups. This resembles the standard UNIX mechanism where the full user and group lists are available to every user on the system.

It is insecure for several reasons:

  • The client secret used to retrieve lists is leaked to every user as well, as any program calling NSS library functions has to be able to read the configured secret
  • All user information is visible to every user, which nowadays must be considered a privacy issue

Querying the API can also be slow depending on the amount of data.

The first problem can be mitigated by using the caching daemon, and only allowing regular users to read data from the cache isntead of use the API live. This also mitigates the performance issue.

The second problem can be mitigated by using the user-only mode, comproising compatibility with applications that rely on NSS tables being complete.

User-only mode

In user-only mode, an access token bound to a single user is used to query the backend for NSS data. This can be the token acquired during PAM login.

As NSS lookups are always done i nthe context of the program that does the lookup, and thus in the context of the user owning the process, this means that every program doing NSS lookups has a partial view on the NSS databases, corresponding to the resources the owner is allowed to see on the server.

This mode is privacy-friendly, but breaks name resolution for all users and groups that are invisible to the calling user.

It can only be used if the OAuth server used supports refresh tokens (while technically, it can be used without refresh tokens, doing so will break name resolution once the access token expires until the user logs in anew).

Caching daemon (nss_pam_oidc_cached)

The caching daemon is a system service that periodically keeps data from the API up to date. It handles the following data:

  • User access tokens (using corresponding refresh tokens, if available)
  • NSS data

Installation

Building from source

To build from source, development headers for libjq and libonig are required. On Debian, install them with:

sudo apt install libjq-dev libonig-dev

Credits

Special thanks to mirabilos in his position as Senior Unix System Development Consultant.

Also, thanks to the very helpful occupants of the Rust chatroom.