pam_usb

The Pam_usb Project

Install notes

% tar -zxvf pam_usb-0.2-beta1.tar.gz
% cd pam_usb-0.2-beta1
% make
# make install
This will unpack, compile and install the pam_usb module and its administration tool usbadm.

Setup

Now pam_usb can be enabled for your login applications.
A list of applications using PAM is avaible at /etc/pam.d/ (you may want to edit /etc/pam.d/login, and /etc/pam.d/xdm).
pam_usb can work in 3 different modes:

Unique: You can login using your USB pen, if it's not present, it isn't possible to login.
This mode can be enabled by commenting the line auth required pam_unix.so (by adding a # at the beginning of the line), and add the following line:

auth       required        pam_usb.so

Alternative: Plugging in the USB device is enough to login. If it's not present, the system prompts for password.
To use such, add the following line before the auth required pam_unix.so line:

auth       sufficient      pam_usb.so

Additional: To login, you have to put the USB device and type your password.
If you want to use this mode, add the following line before the auth required pam_unix.so line:

auth       required        pam_usb.so

Please note that the /etc/pam.d/ directory name, and the pam_unix.so module name are mostly the same in every distro, but could be different (mandrake uses pam_stack.so instead of pam_unix.so).
For a first usage, you should use a alternative mode, and enable the debug mode.
More info are avaible at the PAM documentation website.

Workarounds

2.6 kernel
As the proc format has changed, a workaround is avaible to use it under a 2.6 kernel.
Add the check_device=-1 option in order to make it work.
Non USB-Storage devices
Since the 0.2_rc2 version, it is possible to use a floppy, a cdrom or another mountable device. To use a floppy add the following options:
check_device=-1 check_if_mounted=-1 force_device=/dev/fd0
Replace /dev/fd0 by the device you're using, as /dev/cdrom if you want to store your private key on such support.
CD-ROMs mounting will require to be read-only. To do so, add the option mount_opts=ro.

Key setup

Now that we told PAM to use pam_usb for authentication, we have to create a couple of private and public keys that will be used for authentication. We will use the fresh installed usbadm tool: First you have to mount the USB device on your favourite mountpoint. - If you didn't create a mountpoint for the usb pen then do so :
# mkdir /mnt/usb
Replace /mnt/usb with any other inexistent directory (or leave it alone). - Mount the usb pen:
# mount /dev/sda1 /mnt/usb
Replace /dev/sda1 and /mnt/usb with the correct device name and mountpoint. If you don't have any clue of what your device entry is, just plug the pen and type dmesg. Usually, if you don't have any SCSI device it should be /dev/sda1. Use an empty directory for mountpoint (the one you just created, for example). Ok, now the device is mounted and we can access it's content via /mnt/usb - Now we can create a couple of private/public keys by using the usbadm tool: The syntax is the following: usbadm keygen <mntpoint> <user> <bits> For example this will generate a private and public key for the user root using a pair of 2048 bits DSA keys.
# usbadm keygen /mnt/usb root 2048
[!] Directory /root/.auth/ not found, creating one...
[!] Directory /mnt/usb/.auth/ not found, creating one...
[!] Generating 2048 DSA key pair for root@host
[!] Extracting private key...
[+] Private key extracted.
[+] Private key successfully written.
[!] Writing public key...
[+] Public key successfully written.
That's it. This will check the directories needed by pam_usb, generate, extract and write private/public keys for the chosen user for the local host. You can try with any configured application, like login or GDM. For a first test, you may want to use su as you can test it without switching to a console. If it's not working, look at the FAQ section.

Tips

Key encryption
In some cases you may want to encrypt the private key. By doing this, every time you authenticate your authentication program will prompt for password to unlock the key. This is useful when for example you go to a unsafe place and someone might copy your key. Without decrypting the private key it's not possible to log on.
# usbadm cipher /mnt/usb root   
[!] Importing the private key...
[+] Private key imported
[!] Encrypting the private key may prevent someone to authenticate with
    your key. The drawback is that pam_usb will prompt you for password
    every time you authenticate.
[?] Which algorithm want you to use ? (none/blowfish/des3): blowfish
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
[+] Private key successfully written using cipher blowfish
Now every time you authenticate pam_usb will prompt you for password:
# su
Your private key is locked using symmetric encryption
Passphrase to unlock the key: 
To switch back to unencrypted private key, use the cipher "none" :
# usbadm cipher /mnt/usb root none
[!] Importing the private key...
Enter PEM pass phrase:
[+] Private key imported
[+] Private key successfully written using cipher none
Note that the asked password is the one you setup earlier with blowfish.
Serial numbers ACL
You may want to deny all USB devices but yours. This might prevent people copying your key's content to log on:
# usbadm addserial
[+] procfile: /proc/scsi/usb-storage-0/0
[+] serial number: 69S258Q3BP2E2201
[+] attached: yes
Allowing serial number 69S258Q3BP2E2201...done.
You have to repeat this operation for every USB devices you want to grant. For more informations on usbadm type usbadm help.
Mounting read-only
To mount your device as readonly, you may use the mount_opts option as following:
mount_opts=ro
mount_opts may be used for other options such as ro,bind,sync,remount,nosuid,noexec,nodev.
Mount the device to a customized mount point
To do that, you have to insert mntpoint=/mnt/usb, or whatever you want. You may also want to keep it mounted by using keep_mounted=1, and check_if_mounted=1 to avoid mounting over and over.
File logging
To log debug messages to a file, first enable debug=1 then enter a filename with log_file=/var/log/pam_usb.
Allowing a remote host to use pam_usb
If for any reason you want to login with pam_usb from 192.168.0.1 and 192.168.0.2, you can to it by using local_hosts=:,192.168.0.1,192.168.0.2.
Don't forget the ':' which allows login from local.
Restricting the use of pam_usb to one or more local consoles
This can be done by first forbidding every remote host wich local_hosts="" and then using a comma-separated list of allowed virtual consoles: local_consoles=/dev/vc/1, /dev/vc/2.

Configuration options

As third argument of a pam.d file, it's possible to specify some arguments.
The following is a list of recognized options:

name description default value
mntpoint Tells pam_usb the form of the temporary directory. XXXXXX (6 times) will be replaced by a temporary value. /tmp/pam_usbXXXXXX
proc_basename the device's procfile. You usually don't have to change this, it's where pam_usb searches for devices. /proc/scsi/usb-storage-%d/%d
pwfile The path pam_usb will search for public and private keys (~user/ and mntpoint/) /.auth/
pubkey The name of the public key located in the user's home id_pub
snfile the serial number file contains the allowed SN. If it doesn't exists, the default behaviour is to grant everything. /etc/security/usb_serials
fs comma-separated list of filesystems used to mount the device ext2,vfat
utmp location of the utmp file /var/run/utmp
mount_opts comma-separated list of mount options (including: ro,bind,sync,remount,nosuid,noexec,nodev)
log_file print debug messages to that file instead of stdout
local_consoles comma-separated list of consoles which be able to login when allow_remote=-1 /dev/vc/,/dev/tty,:
local_hosts comma-separated list of hosts that will be able to login when allow_remote=-1 :
force_device Using this option, you can force pam_usb to use a specified device. If it fails mounting, it'll switch back to auto guess mode
allow_remote When set to -1, will allow only local_hosts and local_consoles to login. -1
check_device If unset, pam_usb will not check neither if the device is attached, nor its serial number. 1
check_if_mounted if the usb device is already mounted pam_usb will use its mountpoint (avoid using it) -1
keep_mounted When set to 1, it'll keep mntpoint mounted. -1
sign_times Number of times pam_usb will do the sign/check challenge. 3
debug enable debug mode -1

Boolean variables can have 3 values: -1 (No), 0 (Use Default) and 1 (Yes).

The syntax is of the name=value form, for exemple the following will tell pam_usb to use ext3 as filesystem, to enable debug mode, and that the serial number file is located at /etc/serials:
auth    requisite       pam_usb.so      fs=ext3 debug=1 snfile=/etc/serials