是否有可能在 Ubuntu 16.04 上安装 Pamusb 通过 USB 或 SD 卡进行外部身份验证?这个 LTS 版本似乎不再有 pamusb!
请提供意见或推荐其他替代方案。非常感谢!
答案1
免责声明
这不是 PAM 模块。它实际上所做的只是自动输入密码并按下回车键。因此,插入 USB 时应非常小心。您的密码将被输入到具有焦点的任何应用程序中,然后发送回车键。如果活动窗口是聊天客户端,这可能会非常糟糕。这些脚本按原样提供,在实施之前,您可能应该添加额外的安全措施。例如,我实际使用的一项未在此处实施的安全措施是将加密密码写入 USB 上第一个分区之前的未使用空间(使用 dd)。也许检查我们是否在登录屏幕上是应该实施的另一项安全措施。使用风险自负!通过使用或调整下面提供的任何信息/代码,您将承担保护您自己的实施的所有责任。
黑客攻击
我遇到了同样的问题,并创建了自己的解决方法。我在 Ubuntu 16.04 上使用了 lightdm(默认设置)。每次插入 USB“密钥”时,它都会输入凭据,因此在屏幕未锁定时插入 USB 记忆棒时请务必小心!
我如何让它发挥作用......
当 USB 被授权用于身份验证时,USB 上的各种信息将用作密码,然后用于加密您的密码。然后,此加密密码将存储在计算机上的某个位置。
接下来,编写一个 udev 规则,用于监视要添加到系统中的 USB 存储设备。添加 USB 存储设备时,设备路径将写入由辅助脚本监视的命名管道。
最后,从命名管道读取的辅助脚本会检查插入的 USB 是否有关联的加密密码条目。如果有,则加密密码将被解密,并在焦点后跟回车键的位置自动输入。辅助脚本必须与 udev 脚本分开,因为 udev 脚本运行的范围使我们无法根据需要使用 xdotool。
脚本
插入您要用于登录的 USB。将以下脚本复制到一个空文件并运行*一次: *请注意,该脚本将创建路径 /etc/usbauth 并在您的系统上安装 xdotool。
#!/bin/bash
# This is the a script for authorizing USB devices as logon devices
# run as root
if [ "$(whoami)" != root ]; then
sudo $0 $@
exit
fi
# Install the xdotool if it's not already installed
(
[ "$(which xdotool)" == "" ] && apt install -y xdotool
) &
encryptedPasswordStorage="/etc/usbauth" # path where encrypted passwords are stored
# if path does not exist create it and make sure permissions are set correctly
[ ! -d "$encryptedPasswordStorage" ] && mkdir -p "$encryptedPasswordStorage"
chown root:root $encryptedPasswordStorage
chmod 700 $encryptedPasswordStorage
# Get a list of attached USB storage devices
usbDevices=$(ls -l /dev/disk/by-uuid/ | grep -oP "/sd[a-z][0-9]?" | sort | awk '{print "/dev" $1}' | while read part; do [ "$(udevadm info -q all -n $part | grep "E: ID_BUS" | cut -f2 -d=)" == "usb" ] && echo $part; done)
# Iterate over this list and display partitions
while read device
do
info="$(udevadm info -q all -n $device)"
vendor=$(echo "$info" | grep "E: ID_VENDOR_ID=" | cut -f2 -d=)
model=$(echo "$info" | grep "E: ID_MODEL_ID=" | cut -f2 -d=)
sn=$(echo "$info" | grep "E: ID_SERIAL_SHORT=" | cut -f2 -d=)
uuid=$(echo "$info" | grep "E: ID_FS_UUID=" | cut -f2 -d=)
label=$(echo "$info" | grep "E: ID_FS_LABEL=" | cut -f2 -d=)
key="$vendor$model$sn$uuid"
checksum=$(echo -n "$key" | sha256sum | cut -f1 -d' ')
keyList[$[++i]]="$key" # used as an encryption key for encrypting account password
labelList[$i]="$label"
checksumList[$i]="$checksum"
printf "%5s %-9s %-15s %s\n" "[$i]" $device "$label" $sn
done<<<"$usbDevices"
# Ask user which attached device should be used for authentication
echo ""
read -p "Enter the number of the device to authorize: " selection
read -sp "Enter your login password: " pwd
key=${keyList[$selection]}
encpwd=$(gpg2 --output - -a -c --passphrase "$key" --batch --cipher-algo AES256 --digest-algo SHA512<<< "$pwd")
# Save the encrypted password to the system
encPwdFile="$encryptedPasswordStorage/${labelList[$selection]}_${checksumList[$selection]}"
echo -e "$encpwd" > "$encPwdFile"
chmod 600 "$encPwdFile"
echo ""
* 从现在开始,以 root 身份或使用 sudo 创建/编辑所有文件 *
接下来创建文件 /etc/usbauth/udev.sh,内容如下
#!/bin/bash
# This script watches for USB storage devices. As they are plugged in, this script
# sends the path of these devices to a named pipe that is watched by our helper
# script.
# This script is intended to be called by udev. Add the following rule
# file path: /etc/udev/rules.d/80-USB.rules
# file contents: ACTION=="add",KERNEL=="sd[a-z]*",RUN+="[path to this script]"
encryptedPasswordStorage="/etc/usbauth" # path where encrypted passwords are stored
namedPipe="/tmp/usb-auth" # named pipe used for notification of added USB storage devices
[ -e "$namedPipe" ] && echo "$DEVNAME" > "$namedPipe"
我们还需要创建一个 udev 规则。创建 /etc/udev/rules.d/80-USB.rules,内容如下。
ACTION=="add",KERNEL=="sd[a-z]*",RUN+="/etc/usbauth/udev.sh"
现在,创建最后一个文件 /etc/usbauth/lightdm.sh,内容如下。
#!/bin/sh
# this is the helper script that reads devices that are added and automates typing
# the password if an authorized stick is plugged in.
(
encryptedPasswordStorage="/etc/usbauth" # path where encrypted passwords are stored
namedPipe="/tmp/usb-auth" # named pipe used for notification of added USB storage devices
rm "$namedPipe"; mkfifo "$namedPipe" # create the named pipe
while true;do # this infinite loop helps to ensure that we're always watching for the next device
while read device # when a device is read ...
do
# gather information about the device that was read
info="$(udevadm info -q all -n $device)"
vendor=$(echo "$info" | grep "E: ID_VENDOR_ID=" | cut -f2 -d=)
model=$(echo "$info" | grep "E: ID_MODEL_ID=" | cut -f2 -d=)
sn=$(echo "$info" | grep "E: ID_SERIAL_SHORT=" | cut -f2 -d=)
uuid=$(echo "$info" | grep "E: ID_FS_UUID=" | cut -f2 -d=)
key="$vendor$model$sn$uuid"
checksum=$(echo -n "$key" | sha256sum | cut -f1 -d' ')
# check to see if this device has an associted encrypted password file
encpwdFile="$(find $encryptedPasswordStorage -type f | grep "$checksum")"
echo "$key:checksum --> $encpwdFile" > /tmp/encfile
# if it does, decrypt the password, type it on the screen and press [Enter]
if [ -e "$encpwdFile" ]; then
pwd=$(gpg2 -a -d --passphrase "$key" --batch --output - < $encpwdFile)
echo "$pwd" > /tmp/pwd
xdotool type "$pwd"
sleep .5
xdotool key Return
fi
done < "$namedPipe"
done
) &
此脚本必须在 lightdm 启动时调用。为此,请编辑 /usr/share/lightdm/lightdm.conf.d/50-unity-greeter.conf。在下方[Seat:*]
添加
greeter-setup-script=/etc/usbauth/lightdm.sh
例如,我的 /usr/share/lightdm/lightdm.conf.d/50-unity-greeter.conf 文件如下所示
[Seat:*]
greeter-session=unity-greeter
greeter-setup-script=/etc/usbauth/lightdm.sh
我还没有创建用于管理已添加的 USB 设备的脚本,但您会在 /etc/usbauth 中找到所有已添加的 USB 设备。此文件夹中的每个加密密码文件都以分区标签名称开头,后跟下划线和用于加密密码的密钥的 sha256 哈希值。只需删除加密密码文件即可删除 USB 作为身份验证设备。
请注意,如果您重新格式化 USB 存储设备,UUID 将发生变化,您将无法再次使用该设备登录,除非您再次将其添加为密钥,只需重新运行本文提供的第一个脚本即可完成。我之所以加入 UUID,是因为如今中国生产的许多廉价存储设备都没有配置序列号。此外,当您使用 SD 卡时,值得注意的是,您看到的序列号实际上来自当今大多数系统上的 SD 卡读卡器。因此,如果您使用 SD 卡,即使 SD 卡本身的序列号实际上不同,您安装的每张 SD 卡的序列号也将相同。