Hey guys,
So at work we are given these awesome devices called "YubiKeys", which generate OTPs which can be verified against a FreeRADIUS server, their servers as well as many online services and even your computer logon. They're only $25 (+$5 shipping to most of the world) too, which is a steal!
One of the great things is that they have already coded a libPAM module for it, all you need to do is ensure you are running a newer version of Ubuntu or Debian to install and use it.
This script enables single-factor authentication with either your YubiKey or your password (pressing enter when logging in without your YubiKey skips to normal password authentication).
You will need your API ID and key, which can be obtained from here and your device's unique token ID, which can be obtained by running this in a terminal:
read -p "Press the gold circle on your YubiKey: " s && echo 'The key id is' ${s:0:12}
Just replace the ENTER_YOUR_* with the required information, and all should work :)
yubi_auth.sh
# Yubikey authentication script
echo "Installing Yubikey Authentication System."
# Install the Yubikey package
apt-get -y install libpam-yubico
# Add to the beginning of /etc/pam.d/sshd
sed -i "1s/^/auth sufficient pam_yubico.so id=ENTER_YOUR_ID_HERE key=''ENTER_YOUR_KEY_HERE" authfile=\/etc\/yubikey_mappings debug\n/" /etc/pam.d/sshd
sed -i '1s/^/# Yubikey Security\n/' /etc/pam.d/sshd
# Create and place this line into /etc/yubikey_mappings
echo "root:ENTER_YOUR_TOKEN_ID_HERE" > /etc/yubikey_mappings
# Changing the following in /etc/ssh/sshd_config
# ChallengeResponseAuthentication yes
# PasswordAuthentication yes
# UsePAM yes
file=/etc/ssh/sshd_config
cp -p $file $file.old &&
awk '
$1=="PasswordAuthentication" {$2="yes"}
$1=="ChallengeResponseAuthentication" {$2="yes"}
$1=="UsePAM" {$2="yes"}
{print}
' $file.old > $file
# Restart SSH
service ssh restart
echo "Yubikey Authentication System - Installed."
Yes, I know the script is crappy (made it in a minute), but it works for me. Also ensure that if your API key has "/" in it, use a \ in front to stop the script failing. If you have any questions, feel free to ask! :)