TITLE: Linux-PAM + CrackLib + Shadow LFS VERSION: 3.2+ AUTHOR: Ted Riley SYNOPSIS: How to configure cracklib, Linux-PAM and the Shadow suite HINT: CONTENTS ======== 1. Introduction 2. Changelog 3. Resources 4. CrackLib 5. Linux-PAM 6. Shadow 7. PAM Configuration 8. Trouble 9. Other Programs 10. Closing INTRODUCTION ============ We're going to install cracklib, Linux-PAM and the shadow package, in that order. (Shadow requires the PAM libraries, which require the cracklib libraries.) This hint can be used if you already have an LFS installation in place or if you are installing LFS for the first time. Once the binaries are in place, we will create and/or modify the necessary configuration files to get everything up and running smoothly. Please note: Do not log out until all the configuration files have been created, since you will not be able to log back in. In fact, the safest thing to do is test your configurations in a separate virtual terminal before ending your session. CHANGELOG ========= Current Version 1.2 - 2002.06.10 Modified hint to work "in-line" with LFS installation Replaced shadow patch with make flags Replaced cracklib 'sed' command with make flags 1.1 - 2002.05.31 Corrected directories in shadow patch Added troubleshooting section Added other programs section Added /usr/share/dict/words symbolic link and explained 1.0 - 2002.05.07 Updated explanation of shadow/PAM incompatibility Cosmetic/grammatical changes 0.9 - 2002.04.28 Original draft RESOURCES ========= You will need the following packages: cracklib (2.7 as of this hint): http://www.users.dircon.co.uk/~crypto/download/cracklib,2.7.tgz NOTE: That is not a typo; that is a comma. a dictionary: http://www.cotse.com/wordlists/allwords NOTE: This website also has a dictionary called 'cracklib' but it is 15.6MB compared to 'allwords' which is 467KB. I have had cracklib seg fault with the larger dictionary, but not with the smaller. I know others (with better systems than mine) who have used the 'cracklib' dictionary successfully. Your mileage may vary. Linux-PAM (0.75 as of this hint): http://wwww.kernel.org/pub/linux/libs/pam/pre/library/Linux-PAM-0.75.tar.gz NOTE: There is a cracklib-files.tgz here. DO NOT USE IT. This version of cracklib appears to be 2.5.1, which has a known vulnerability (see http://www.cert.org/vendor_bulletins/VB-97.16.CrackLib) Shadow (4.0.3 as of this hint): ftp://ftp.pld.org.pl/software/shadow/shadow-4.0.3.tar.gz NOTE: There is no note for this one; insert humor attempt here. CRACKLIB ======== The following assumes that you downloaded the 'allwords' dictionary. If you chose a different one, you will have to change the commands below to match. From the directory where you downloaded the dictionary: cp allwords /usr/share/dict/ && cd /usr/share/dict && ln -s allwords words One note about the above commands: Traditionally, the /usr/share/dict directory had only one file: words. The FHS standard does not prohibit other files from being here as long as they are wordlists as well. I like to remember what dictionary I used, which is why I do not simply rename 'allwords' to 'words.' Creating the link to 'words' helps other programs which might look in the standard location for a dictionary (that is, the '/usr/share/dict/words' file). Next, in the cracklib directory, we need to create a couple files: cat >> crack.h << "EOF" #ifndef CRACKLIB_H #define CRACKLIB_H /* Pass this function a password (pw) and a path to the * dictionaries (/usr/lib/cracklib_dict should be specified) * and it will either return a NULL string, meaning that the * password is good, or a pointer to a string that explains the * problem with the password. * You must link with -lcrack */ extern char *FascistCheck(char *pw, char *dictpath); #endif EOF cat >> util/create_cracklib_dict << "EOF" #!/bin/sh if [ -z "$*" ]; then echo "Usage:" echo " $0 wordlist ..." echo echo "This script takes one or more word list files as arguments" echo "and converts them into cracklib dictionaries for use" echo "by password checking programs. The results are placed in" echo "/usr/lib/cracklib_dict.*" echo echo "Example:" echo "$0 /usr/share/dict/words" else /usr/sbin/mkdict $* | /usr/sbin/packer /usr/lib/cracklib_dict fi EOF And finally we compile cracklib from the source directory: make DICTPATH=/usr/lib/cracklib_dict SRCDICTS=/usr/share/dict/words install && cp cracklib/libcrack.a /usr/lib && cp crack.h /usr/include && cp util/{mkdict,packer,create_cracklib_dict} /usr/sbin Command Explanations: cat >> crack.h ... : These commands create a header file for programs to use when compiling with the crack library. cat >> util/create_cracklib_dict ... : These commands create a script which takes a wordlist as an argument and creates a new cracklib dictionary. make ... install : Makes the cracklib libraries with the correct dictionary locations cp cracklib.a /usr/lib : The make install command does not install the static cracklib library, so we do it here. cp crack.h /usr/include : This command copies the header file we created. cp util/mkdict util/packer util/create_cracklib_dict : This command copies the scripts and binaries needed to create new cracklib dictionaries. Please note: The crack.h and create_cracklib_dict scripts were based on those found in the cracklib.tgz archive. Credit goes to the authors of the originals, although they were unlisted (unless the author was Alec Muffett, who wrote the cracklib library, in which case credit goes to him). LINUX-PAM ========= Now we will compile PAM: ./configure --enable-static-libpam --with-mailspool=/var/mail \ --enable-suplementedir=/usr/lib && make && make install && cd /lib && for name in libpam libpamc libpam_misc; do ln -s ${name}.so.0.75 ${name}.so.0 done Command Explanations: ./configure --enable-static-libpam : This builds static PAM libraries as well as the dynamic libraries --with-mailspool=/var/mail : This flag makes the mailspool directory FHS-compliant --with-suplementedir=/usr/lib : This flag installs the unix_chkpwd binary in an FHS-compliant location for name in libpam libpamc libpam_misc; do : The installer creates broken symlinks. These commands correct the library links. If you don't have sgml tools on your computer, you will receive an error message after the install. To install the docs manually, run the following commands from the Linux-PAM source directory: cd doc tar zxf Linux-PAM-0.75-docs.tar.gz cp -a html /usr/share/doc/Linux-PAM/ cd /usr/share/doc chown -R root:root Linux-PAM touch Linux-PAM cd Linux-PAM touch * (The final three commands aren't necessary unless you use a time-stamp sensitive install manager like install-log.) SHADOW ====== There is an incompatibility between the current versions of Shadow and the latest versions of Linux-PAM. For the record, the maintainer of the shadow package believes the incompatibility lies in the PAM libraries, not in shadow. Therefore, he advises using a different version of PAM. (available from ftp://ftp.pld.org.pl/software/pam/). However, I prefer to use the latest versions of both packages; the compiler flags below will accomplish this. LDFLAGS="-lpam -lpam_misc" ./configure --prefix=/usr --enable-shared \ --with-libpam --without-libcrack && make && make install && cd /usr/sbin && ln -sf vipw vigr && rm /bin/vipw && mv /bin/sg /usr/bin && mv /lib/{libmisc.*a,libshadow.*a} /usr/lib && cd /usr/lib && ln -sf ../../lib/libshadow.so sed 's%/var/spool/mail%/var/mail%' etc/login.defs.linux > /etc/login.defs cp debian/securetty /etc/securetty Command Explanations: LDFLAGS="..." ./configure : The compiler flags allow the shadow package to link correctly against the PAM libraries; they must be entered on the same line as the configure command. --enable-shared : Shadow no longer creates shared libraries by default, so this flag is used. --with-libpam : This flag compiles with PAM support. --without-libcrack : Cracklib will be called through PAM, so we do not need it here. ln -sf vipw vigr ... ln -s ../../lib/libshadow.so : These commands fix broken links and un-installed libraries. They are also useful for refreshing the time-stamps on the files if you use a time-stamp sensitive installer (like install-log). sed ... login.defs : This will create the /etc/login.defs file (if you don't already have one) and will make the mail directory FHS-compliant. cp debian/securetty /etc/securetty : This will create the securetty file which prevents root logons from all but listed terminals. Please note: We no longer need the 'limits' and 'login.access' files in /etc since PAM will handle these functions. You may safely delete these files if you had previously created them. PAM CONFIGURATION ================= We are almost done. Now we will customize our setup. Please note that the PAM configuration files below are necessary for PAM to function. Without these files, you will not be able to log in. You can comment out the following entries in login.defs since PAM is now handling them. In the right column are the PAM modules which replace the entries: DIALUPS_CHECK_ENAB (not sure - anyone know?) LASTLOG_ENAB (pam_lastlog.so) MAIL_CHECK_ENAB (pam_mail.so) OBSCURE_CHECKS_ENAB (pam_cracklib.so) PORTTIME_CHECKS_ENAB (pam_time.so) CONSOLE (pam_securetty.so) MOTD_FILE (pam_motd.so) NOLOGINS_FILE (pam_nologin.so) PASS_MIN_LEN (pam_cracklib.so) SU_WHEEL_ONLY (pam_wheel.so) CRACKLIB_DICTPATH (pam_cracklib.so) PASS_CHANGE_TRIES (pam_cracklib.so) PASS_ALWAYS_WARN (pam_cracklib.so) MD5_CRYPT_ENAB (pam_unix.so with md5 flag) CONSOLE_GROUPS (pam_groups.so) ENVIRON_FILE (pam_env.so) Several people have noticed a small problem with pam_issue.so. Specifically, if you enter the correct password the first time, the login fails, even if pam_issue is set to optional. However, if the wrong password is entered at least once, the correct password will work for any further attempts. I think this is because the first issue file is displayed by agetty, not login. All the other issue messages are displayed by login. So, if you succeed the first time, pam_issue is not called. I'm not sure how to get around this problem (since even the optional setting doesn't work), so I have left the issue command in /etc/login.defs and taken it out of PAM. If anyone knows how to fix this, please let me know. If you want to use the access or limits modules (among others), you can edit the configuration files in /etc/security/. Currently, my files are still fully commented out (the default), so I'm not much help for suggestions on those. If anyone is using these files, I would love to hear from them, though. Below are my pam.d files. I prefer separate files under pam.d as opposed to one file (/etc/pam.conf), but use whichever you prefer. In fact, if you want to, you can use both by specifying the --enable-both-confs flag when compiling Linux-PAM. /etc/pam.d/login: # Begin /etc/pam.d/login auth requisite pam_securetty.so auth requisite pam_nologin.so auth required pam_env.so auth required pam_unix.so account required pam_access.so account required pam_unix.so session required pam_motd.so session required pam_limits.so session optional pam_mail.so dir=/var/mail standard session optional pam_lastlog.so session required pam_unix.so # End /etc/pam.d/login /etc/pam.d/other: # Begin /etc/pam.d/other auth required pam_deny.so auth required pam_warn.so account required pam_deny.so session required pam_deny.so password required pam_deny.so password required pam_warn.so # End /etc/pam.d/other /etc/pam.d/passwd: # Begin /etc/pam.d/passwd password required pam_cracklib.so \ retry=3 difok=8 minlen=15 dcredit=3 ocredit=3 ucredit=2 lcredit=2 password required pam_unix.so md5 shadow use_authtok # End /etc/pam.d/passwd /etc/pam.d/shadow: # Begin /etc/pam.d/shadow auth sufficient pam_rootok.so auth required pam_unix.so account required pam_unix.so session required pam_unix.so password required pam_permit.so # End /etc/pam.d/shadow /etc/pam.d/su: # Begin /etc/pam.d/su auth sufficient pam_rootok.so auth required pam_unix.so account required pam_unix.so session required pam_unix.so # End /etc/pam.d/su /etc/pam.d/useradd: # Begin /etc/pam.d/useradd auth sufficient pam_rootok.so auth required pam_unix.so account required pam_unix.so session required pam_unix.so password required pam_permit.so # End /etc/pam.d/useradd One final note: The shadow file (and useradd, for that matter) require a password field, or else they will return a 'PAM chauthtok failed' error. Also, the shadow file affects many of the other programs in the shadow suite (chfn, chage, groupdel, userdel, etc.). These programs interface with PAM as 'shadow' instead of their own program name. TROUBLE ======= Here are a couple problems that crept up while I was installing the above programs myself. Just in case you run in these problems yourself, here are some tips to help you resolve them. Of course, you will not need these because everything will work great the first time. ;-) Cracklib Seg Fault: With a large dictionary file, cracklib gave a segmentation fault the second time I tried to change a password. (The first time worked.) To fix this, I ran the script create_cracklib_dict, as listed below (I was using the 'cracklib' dictionary at the time): create_cracklib_dict /usr/share/dict/cracklib This command rebuilt the cracklib dictionary files and cracklib worked fine the next time I changed a password. Then it crashed again the following time. However, when I ran the above command with the 'allwords' dictionary listed above, cracklib worked and has worked since. As noted above, this error may be a result of my computer's limited RAM and swap space. Other people have stated that the cracklib dictionary has worked fine for them. Incorrect Root Password: Later, due to a misconfiguration, I found myself unable to log in as root. To fix this, I used a boot disk (the Slackware boot disk, to be exact) which allowed me to log in as root without a password. Once I was logged in, I mounted my LFS system. Then, I renamed the pam.d directory and created a new pam.d directory with only the 'other' file. This temporary file is listed below: # Begin temporary /etc/pam.d/other auth required pam_unix.so nullok account required pam_unix.so session required pam_unix.so password required pam.unix.so nullok # End temporary /etc/pam.d/other I also edited my /etc/passwd file (after making a backup, of course) and removed the password field for root. After rebooting, I was able to log in as root without a password. Then, I copied my original pam.d directory back in place and changed the root password, testing the configuration in another virtual terminal. OTHER PROGRAMS ============== The main reason to install PAM (at least for me) was so that different programs could use it. Below are a few programs that utilize PAM, as well as instructions how to compile PAM support into them. SSH: OpenSSH (from http://www.openssh.com/) has a compile option for PAM. Simply specify the --with-pam flag when you run the configure script. The PAM configuration file I use for ssh is almost identical to the one used for login, with one exception: the securetty line is removed (so we can log in through ssh from anywhere). For simplicity's sake, the file is listed below: /etc/pam.d/sshd: # Begin /etc/pam.d/sshd auth requisite pam_nologin.so auth required pam_env.so auth required pam_unix.so account required pam_access.so account required pam_unix.so session required pam_motd.so session required pam_limits.so session optional pam_mail.so dir=/var/mail standard session optional pam_lastlog.so session required pam_unix.so # End /etc/pam.d/sshd PPPD: Another program that is useful if you use a modem (including DSL) is the pppd program (available from http://www.samba.org/ppp/). To enable PAM in pppd, simple add the USE_PAM=y flag after the make command. My configuration file for ppp is sparce compared to sshd and login, simply because I do not use ppp except to dial out. The configuration file for pppd is listed below: /etc/pam.d/ppp: # Begin /etc/pam.d/ppp auth requisite pam_nologon.so auth required pam_unix.so account required pam_unix.so session required pam_unix.so # End /etc/pam.d/ppp Please note that the file is called ppp, not pppd. This is because the ppp daemon uses "ppp" to interface with PAM instead of "pppd." CLOSING ======= Many thanks to Yannick Tousignant for writing the previous pam hint and helping me get my foot in the door. And of course, thanks to Gerard Beekmans and the rest of the LFS crew. Also, thanks to the following individuals for their contributions: Thien Vu Adrian Woffenden If you need additional help, be sure to check out the Linux-PAM manuals at http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/ Also, help may be available on the Shadow mailing list at http://lists.pld.org.pl/archive/index.htm?10 Enjoy.