mfa
Check out the source code here - git.chudnick.com/mfa
mfa is a system for out-of-band multi-factor authentication with PAM. My original reason for working on this was to get MFA functionality for a Postfix/Dovecot mail server that uses PAM for authentication. Solutions such as pam_oath are not feasible for this purpose because a mail client has no way of exposing an interface for the oath challenge-response. Therefore a way to circumvent the original application to get the request to the user is needed, which is what mfa does.
The design of mfa is not novel, it works the same way as Cisco's Duo. Duo does have open source modules for achieving this objective, but all the authentication requests are sent back to their proprietary "cloud" service. I'm sure that most free software enthusiasts see this as a major red flag, especially for small personal use cases.
Design
mfa is primarily composed of three parts - the server, the client, and the PAM module. The server listens for connections from both clients and PAM modules. The server receives a request from a PAM module that includes the username of the user attempting to authenticate, the hostname of the computer, and the service being accessed. The server then correlates the combination of user, host, and service to a particular client, and attempts to push a request. The server will then evaluate the client's response, and either return to the PAM module that the user is authenticated or denied.
The server itself consists of two parts that I've called mfad and mfac. mfad is the program responsible for doing what I've described above. mfac is a command line utility that the administrator uses to configure the server. mfac is used to enroll clients in the system and to provision applications. A client is enrolled by using the --add-client option and providing an alias for that user. The server then assigns that user an identifying key that is used to connect and a TOTP secret key. With the client enrolled, the administrator can then assign applications to that client. With the --add-app command, the administrator ties a username, hostname, and service combination to a client alias, so that when that combination is seen the server knows who to ask for authentication. The administrator also identifies which MFA methods are valid for this combination (currently either or both of push and/or totp). The example below shows the process of enrolling a new client called 'tux' and then provisioning MFA for SSH attempts to tux@linux.example.org.
# Enroll a client named tux
mfac --add-client tux
alias: tux
client key: VA32LB3SF2HG2FDWJS5XIOFVWTMBQYRSQ3PK3OOPA3FBIQMSMJZCXYJQCYKYUWUU
totp secret: TGGG3QCXA4MR2S2X6B33GSYN
uri: otpauth://totp/tux%40mfad?secret=TGGG3QCXA4MR2S2X6B33GSYN
# Provision MFA for SSH tux@linux.example.org allowing for both push
authentication or TOTP
mfac --add-app --user tux --host linux.example.org --service sshd --alias tux
--methods push totp
The PAM module of mfa also consists of two parts: the actual PAM module pam_mfa.so that gets called in the PAM stack and a helper program that interacts with mfad. The job of pam_mfa.so is to retrieve the necessary information (user and service) from PAM and then invoke the helper program with that data. It then waits for the MFA process to complete, retrieves the result, and returns either success or failure to the PAM stack. The helper program initiates a connetion to mfad when run and then passes username, hostname, and service information to the server. It too receives a success or failure response and then relays that information to the PAM module. Here is an example of using pam_mfa.so in the PAM stack for sshd.
/etc/pam.d/sshd
auth requisite pam_mfa.so
The client program is what the end user interacts with to provide authentication responses. Currently it is only a very simple terminal program but expanding on this is high on the TODO list. The client opens a connection to the server and identifies itself with the client key that was generated during enrollment. The client waits for a prompt from the server, and when it receives one, informs the user. The client receives the users input and sends it back to the server. The client performs this loop continuously until it is closed.
clibrary
Check out the source code here - git.chudnick.com/clibrary
mail-tools
deploy-scripts
git.chudnick.com/deploy-scripts