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!
- 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.
/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
The authentication process is done in four steps:
- first, vsftpd calls
pam_authenticateto 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
NO), vsftpd calls
pam_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_sessionto 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 files are located in
/etc/pam.d. Each line (called rule) is composed as follow:
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
typepreviously. It can be
sessiondepending on which step you want to configure.
controlindicates 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-pathis the PAM module used to perform the action. A lot of PAM modules exist. For example,
pam_listfile.sois used to allow or deny the access if the username is (or is not) in a text file ; and
pam_unix.sois used to ask password and compare it against
/etc/shadow. Note that certain modules cannot be used for every
type. For instance, the module
pam_shells.sowhich allows access to the system if the users shell is listed in
/etc/shellscan only be used for the types
module-argumentsare the arguments given to the module. For example, it could be
item=user sense=deny file=/etc/ftpusers onerr=succeedfor
pam_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
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:
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:
ignoreto prevent returning an error to the application if the PAM module fails. In our case, the application is vsftpd, and we
ignorewhen the authentication using the .htpasswd file fails to let later rules decide if we should grant access.
doneto return the current status to the application, and stop processing further rules.
N (an unsigned integer)to skip the next
action can also be
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]),
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