PAM is one of the Linux components you probably already heard of. You know that it is used someway to authenticate users. You don't exactly know how it works neither how to configure it, but at the very bottom of the todo list you made a few years ago, there's the line "understand how PAM works" written, so you will get it eventually!
I had to understand PAM to configure the torrents InstantApp of Scaleway. You can use this app to create a C1 server in one click. It contains:
- rTorrent to download torrent files.
- ruTorrent, a pretty cool web interface to visualize and manage your downloads.
- a fancy web page to list your downloaded files using h5ai.
I also wanted to install the FTP server vsftpd to allow the user to download his/her files from his favorite FTP client.
The web interface of the torrents InstantApp is protected by basic authentication (i.e. credentials are generated with htpasswd -c <filename> <username>
) and I want to setup vsftpd to use this htpasswd file for authentication too.
Note that even if this tutorial explains how vsftpd is using PAM, the concepts are the same if you need to configure other softwares.
PAM authentication lifecycle
When you read some documentation about PAM, it's often explained how to configure it and it's quite... complicated. Let's try another way, and explain first how vsftpd uses PAM to handle authentication. We'll discuss the configuration files a little bit later.
In /etc/vsftpd.conf
you will find pam_service_name=vsftpd
. It means vsftpd uses the PAM service named vsftpd
to perform authentication (in other words, it uses PAM configured by /etc/pam.d/vsftpd
).
The authentication process is done in four steps:
- first, vsftpd calls
pam_authenticate
to authenticate the user. PAM requires the user to provide an authentication token depending upon its configuration, usually this is a password, but could also be a finger print. - if it succeeds, vsftpd calls
pam_acct_mgmt
. PAM determines if the user's account is valid. It checks for the authentication token and account expiration and verifies access restrictions. - if it succeeds and
SESSION_SUPPORT=YES
invsftpd.conf
(default isNO
), vsftpd callspam_open_session
. PAM sessions are used to do things that need to be done for the user before/after they can be given a service, for instance mounting directories. - finally, vsftpd calls
pam_close_session
to close the PAM session.
Each step (authentication, account management and session management) corresponds to a PAM type, named auth, account and session. Another type exists, password, useful to update the authentication token associated with the user but won't be discussed here, though after this blog post you should be able to read and understand the manual of pam.conf easily if you need to use it.
PAM configuration
PAM configuration files are located in /etc/pam.d
. Each line (called rule) is composed as follow:
type
control
module-path
module-arguments
For example the following rule is successful only if the username is not in /etc/ftpusers:
auth required pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed
Let's see what is the meaning of each part:
- we saw
type
previously. It can beauth
,account
,password
orsession
depending on which step you want to configure. control
indicates if the module should fail or succeed in its authentication task. Since the syntax is a bit more complex, we will discuss what it can contain just after.module-path
is the PAM module used to perform the action. A lot of PAM modules exist. For example,pam_listfile.so
is used to allow or deny the access if the username is (or is not) in a text file ; andpam_unix.so
is used to ask password and compare it against/etc/shadow
. Note that certain modules cannot be used for everytype
. For instance, the modulepam_shells.so
which allows access to the system if the users shell is listed in/etc/shells
can only be used for the typesauth
,account
andpassword
.- Finally,
module-arguments
are the arguments given to the module. For example, it could beitem=user sense=deny file=/etc/ftpusers onerr=succeed
forpam_listfile.so
. You need to read the module documentation to understand the meaning of each parameter.
For the authentication process to succeed, the set of rules for each type must be successful. First, auth
rules are processed, then account
, then optionally session
rules.
There is a way to control the behavior of a rule, and tell PAM "if this rule fails, then ignore it and go to the next one" or "if this rule succeeds, skip the next one and execute the one after" or "if this rule fails, do not process the next rules and return an error immediately to the application". This is what control
is for.
control
format in a PAM rule
control
is a square-bracketed selection of value=action
pairs, for example [success=ok new_authtok_reqd=ok ignore=ignore default=bad]
.
value
can be one of these: success
, cred_unavail
, acct_expired
, or default
(and actually muuuuuuch more, everything is detailed in pam.conf
). It allows to configure the behavior of the rule if the module returns a success, or if it returns that credentials are unavailable, or... you get the idea. default
is used to configure the behavior of the values not explicitely mentionned.
action
defines what to do if the PAM module returns value
. It can be:
ignore
to prevent returning an error to the application if the PAM module fails. In our case, the application is vsftpd, and weignore
when the authentication using the .htpasswd file fails to let later rules decide if we should grant access.done
to return the current status to the application, and stop processing further rules.N (an unsigned integer)
to skip the nextN
rules..
action
can also be bad
, die
or ok
.
Last thing about control: the square-bracket syntax is hard to read and you can use required
(equivalent to [success=ok new_authtok_reqd=ok ignore=ignore default=bad]
), requisite
, sufficient
or optional
instead.
Everything is detailed in the man of pam.conf ;)
The final PAM configuration file
From now, you should be able to understand the configuration file.
# Ensure the FTP username is not in /etc/ftpusers
auth required pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed
# If credentials match what is in the htpasswd file, return
# success and do not process the other rules
auth sufficient pam_pwdfile.so pwdfile=/var/www/credentials debug
# Always return success. Note the type `account` will only
# be called if `auth` previously returned a success.
account sufficient pam_permit.so
# Standard PAM includes, to authenticate using /etc/passwd.
@include common-account
@include common-session
@include common-auth
# Ensure the user has a shell in /etc/passwd.
auth required pam_shells.so
Bonus time! Our /etc/pam.d/vsftpd
and /etc/vsftpd.conf
files are on github!