A Linux pam-module using https and ssl client certificates for authentication
Linux-pam (Pluggable Authentication Modules) is responsible for handling
authentication requests in a flexible way from linux applications, such as
login. This is a minimal pam-module implementation written in C which performs
authentication through HTTP.
The purpose for developing this pam-module is to dispatch the authentication
procedure to a remote party, and keep options open of how authentication
actually is performed. Compare with options like kerberos, ldap, pam_*sql,
which is both higly coupled to a specific implemetation and complicated to
install & configure.
By using a simple HTTP POST request the authentication api is standardized and
independent of the underlying implementation and scheme. A mutual trust between
server and pam-client is establish using ssl server & client certificates. The
remote party (authentication server) could use ldap, password-database or
enables usage of other authentication schemes such as OpenID and Webauthn
only intended for web services.
This pam-plugin is built for usage with a webauth server using OpenID (from
Google or others) for authentication instead of promting for passwords.
See more @ https://github.com/1nfiniteloop/webauth.
docker build --tag=pam-http-builder:1.0.0 .devcontainer/
.
docker run \
--rm \
--workdir=/home/build \
--volume=$(pwd):/home/build \
--name=pam-http-builder \
--user=$(id -u):$(id -g) \
pam-http-builder:1.0.0 \
/bin/bash -c 'mkdir build && cd build && cmake .. && make package'
Install pam_http from the debian package:sudo dpkg -i build/pam-http-1.0.0-Linux.deb
Each Linux utility which need authentication and uses pam have a configuration
file in /etc/pam.d
. Example su
has its own configuration file named
accordingly, same as for login
, sudo
, passwd
etc. A pam-module consists
of four different services; auth, session, account, password which always is
present in each configuration file.
See more @ http://www.linux-pam.org/Linux-PAM-html/sag-configuration-file.html
This module implements only the auth service, this is the only service you
need to reconfigure. Below is an example for /etc/pam.d/login
. You might place
the pam-http configuration just above the common-auth include or optionally
inside /etc/pam.d/common-auth
, at the top.
...
# Custom http authentication
auth [success=done perm_denied=die new_authtok_reqd=done default=ignore] pam_http.so url=https://auth-server.com:443/api/auth cert-path=/etc/pam-http.d/ssl key=client.key.pem cert=client.cert.pem cacert=ca-chain.cert.pem
# Standard Un*x authentication.
@include common-auth
...
The options within the brackets above means:
success=done
a successfull auth request will return success to thedefault=ignore
errors such as connectivity issues, outdated certificateperm_denied=die
stops evaluation of further modules in the pam-stack whenAvailable command-line options in format “key=value” are:
The authentication is performed by sending a http POST request to a server with
parameters for username and service-name (e.g. login, sudo, su). Password is not
part of the http post request since my intention with this project is to avoid
the need for local user password promting.
The server can choose to send a 200 status code for grant authentication or 401
for deny. Other status codes are treated as errors. The pam-http module make
sure that user exists locally before sending a request.
The project is built using a docker-container as development environment, see
further in .devcontainer/Dockerfile
. Tests is written in C++ for conveniece
and have further dependencies located as git submodules under folderthird_party/
.
If you want to build unittests you need to first build the libraries gtest and
httpmockserver under third_party/.
git submodule update --init
.cd build && cmake -DWITH_UNITTEST=ON ..
make test_all
.Some sources of inspiration used within this project: