轶哥

📚 Having fun with AI Agent. Always learning.

为Linux启用人脸识别登录/授权
  •   更新:2024-08-05 13:09:21
  •   首发:2022-04-06 22:11:48
  •   教程
  •   6332

现在新购买默认搭载Windows系统的电脑一般都会提供一个Windows Hello身份认证方案,例如指纹或者人脸识别。Howdy是一个在Linux上模仿Windows Hello的程序,可以实现在系统用户登录锁屏登录sudo su等身份认证时候使用人脸识别。

安装及调试

Howdy开源地址:https://github.com/boltgolt/howdy

Howdy程序本身的使用方法官方已经已经非常详细了,在此仅做补充,更新:直接安装二进制现已经不可行,需要按照官方说明的编译方法进行编译安装。

除了说明提到的Ubuntu or Linux MintDebianArch LinuxFedoraopenSUSE这些Linux发行版之外,基于这些系统的一系列发行版系统都是可以用的。例如Raspberry Pi OSKali

支持Windows Hello的笔记本电脑配有红外摄像头和红外光线发射器。红外网络摄像头通常可以在Linux上自动检测到,但默认情况下,红外光线发射器不起作用。为了使它们工作,请安装和配置linux-enable-ir-emitter

配置中官方有启用说明:

How to enable your infrared emitter ?

  1. linux-enable-ir-emitter -h (each sub-command also has a help -h)
  2. sudo linux-enable-ir-emitter configure look at the ir emitter and answer to the asked questions. You can specify your infrared camera with the option -d /dev/videoX, by default is /dev/video2.
  3. reboot

补充一些调试细节:

你的红外摄像头可能是/dev/video0,但是红外发射器+摄像头可能是/dev/video1。换句话说,这两个地址都可以调用摄像头,但是可能只有后者可以在调用摄像头的同时启动红外发射器。

配置完成后可以通过linux-enable-ir-emitter test查看红外发射器是否可以正常工作,可以正常工作后可以通过linux-enable-ir-emitter boot设置开机启动。

配置完红外功能后,再执行howdy test可以实时查看摄像头,拉上窗帘关闭灯看是否还能看清自己的脸。

通过/lib/security/howdy/config.ini配置文件里面的dark_threshold参数可以调节黑暗阈值,由于红外发射器是闪烁的,某些频率摄像头可能完全看不到物体,可以通过测试不同的值获得更好的黑暗环境下识别的效果。

常见问题

Q: 我可以跳过"登录"按钮吗?

A: 不可以。由于危险的行为和对调用sudo的担忧#170,在5.2.1+版本中删除了dismiss_lockscreen配置项。

Q: 每次登录桌面都要输入用户名,是否可以设置默认登录用户?

A: 严格来说这与howdy无关,而是与对应Linux发行版的Desktop程序有关系。常见的LightDM支持通过设置解决该问题。详见后文。

Q: 提示登录密钥环没有被解锁。(The login keyring did no get unlocked)

A: “我想说这不是一个问题,而是预期的。默认情况下,密钥环会使用您的密码 解密。 这是保证他们的存储安全的唯一方法。但是,一旦您登录,密钥环就会一直解密,因此我认为面部识别是一种快速再次登录的方式,而不是让您登录的主要方式。无论如何,这非常不安全。”——#39

B: 实际上也可以通过命令登陆自动解锁。但是需要明文密码,并不安全。例如,在~/.profile中添加:

echo -n "你的密码" | gnome-keyring-daemon --replace --unlock

LightDM设置默认登录用户名

执行lightdm --show-config可以看到当前LigntDM配置信息。

$ lightdm --show-config  
   [Seat:*]
B  greeter-session=lightdm-greeter
B  greeter-hide-users=true
B  session-wrapper=/etc/X11/Xsession

Sources:
B  /usr/share/lightdm/lightdm.conf.d/01_debian.conf
B  /usr/share/lightdm/lightdm.conf.d/01_debian.conf
C  /etc/lightdm/lightdm.conf

可以看到配置文件B中配置了greeter-hide-users=true,我们只需要修改/usr/share/lightdm/lightdm.conf.d/01_debian.conf文件设置greeter-hide-users=false即可展示可选的登录用户信息,默认选中上一次登录的用户。如果配置文件B没有此配置项,那么可以直接在/etc/lightdm/lightdm.conf中添加该配置。

LightDM 中的default-user配置选项早已在多年前被废弃。如果您的计算机被多人使用,那么默认选中的用户将会是最后一次登录的用户,因此,如果您希望固定默认选中的用户名,可以使用脚本动态修改/var/lib/lightdm/.cache/lightdm-gtk-greeter/state文件来实现固定默认用户的功能。

  1. 创建/usr/local/bin/lightdm-default-user脚本(脚本来自此处):

    #!/bin/sh
    
    # LightDM removed the default-user option.
    # The only recourse now is an ugly kludge. 
    
    # Note that if you want to default to the "Guest Session",
    # you need to specify the last user as "*guest".
    
    /bin/echo -e '[greeter]\nlast-user=*guest' > /var/lib/lightdm/.cache/lightdm-gtk-greeter/state
    
  2. 修改上诉脚本文件中的*guest为您的默认用户的用户名。

  3. 执行chmod 755 /usr/local/bin/lightdm-default-user赋予该脚本可执行权限。

  4. 编辑/etc/lightdm/lightdm.conf文件,添加下述内容,让lightdm在启动时自动运行该脚本:

    [SeatDefaults]
    greeter-setup-script=/usr/local/bin/lightdm-default-user
    

正如原作者所说,这个方法比较丑陋,但却是目前最完美的解决方案。

添加对Python3的支持

轶哥在2022年10月29日使用的howdy仍然是2020年9月发布的2.6.1版本。在这期间howdy一直正常运行,然而随着各个Linux发行版逐步移除对python2的支持,导致howdy在升级了Linux系统后可能出现异常。

注意: 使用3.0.0 beta版本无需修改下面代码。

查看无法人脸识别的报错信息:

cat /var/log/auth.log

提示如下报错:

Oct 27 23:24:26 [localhost] sudo:     yige : TTY=pts/0 ; PWD=/home/yige/Downloads ; USER=root ; COMMAND=/usr/bin/apt remove nodejs
Oct 27 23:24:26 [localhost] /lib/security/howdy/pam.py[11808]: Traceback (most recent call last):
Oct 27 23:24:26 [localhost] /lib/security/howdy/pam.py[11808]:   File "/lib/security/howdy/pam.py", line 10, in <module>
Oct 27 23:24:26 [localhost] /lib/security/howdy/pam.py[11808]:     import ConfigParser
Oct 27 23:24:26 [localhost] /lib/security/howdy/pam.py[11808]: ModuleNotFoundError: No module named 'ConfigParser'

可见No module named 'ConfigParser'是由于ConfigParser模块出现异常。

Python3中,ConfigParser已经更名为configparser

目前howdy作者还没有发布新版本添加对python3的支持,因此可以通过手工修改/lib/security/howdy/pam.py文件实现兼容(不要遗漏import sys):

# PAM interface in python, launches compare.py

# Import required modules
import subprocess
import os
import glob
import sys
import syslog

# pam-python is running python 2, so we use the old module here
if sys.version_info.major < 3:
    import ConfigParser
    config = ConfigParser.ConfigParser()
else:
    import configparser
    config = configparser.ConfigParser()

# Read config from disk
config.read(os.path.dirname(os.path.abspath(__file__)) + "/config.ini")

...

将此文件前面几行修改如上即可。重启后howdy即可正常运行。

出现howdy not found

先执行sudo ln /lib/security/howdy/cli.py /usr/local/bin/howdy,然后编辑:

sudo vim /lib/security/howdy/cli.py

import sys后面新增一行:

sys.path.append('/lib/security/howdy')

出现zsh: segmentation fault sudo pam-auth-update

由于zsh: segmentation fault sudo pam-auth-update报错导致sudo命令无法使用,因此常规方法是无法恢复的。需要使用U盘引导到恢复模式进入root用户环境卸载howdy然后重新安装。

出现Camera path is not configured correctly, please edit the 'device_path' config value.

需要修改/lib/security/howdy/config.ini中的device_path为你的摄像头路径(/dev/videoX)。

出现OpenCV警告信息

[ WARN:0@2.157] global ./modules/videoio/src/cap_gstreamer.cpp (2401) handleMessage OpenCV | GStreamer warning: Embedded video playback halted; module source reported: Could not read from resource.
[ WARN:0@2.158] global ./modules/videoio/src/cap_gstreamer.cpp (1356) open OpenCV | GStreamer warning: unable to start pipeline
[ WARN:0@2.158] global ./modules/videoio/src/cap_gstreamer.cpp (862) isPipelinePlaying OpenCV | GStreamer warning: GStreamer: pipeline have not been created

可以无视,如果介意的话添加到你的shell初始化脚本:

export OPENCV_LOG_LEVEL=0
export OPENCV_VIDEOIO_PRIORITY_INTEL_MFX=0

GNOME 锁屏界面异常

如果是2.6.x版本,可尝试将 /lib/security/howdy/compare.py 文件内容使用https://github.com/boltgolt/howdy/blob/caf244ce297d27d40168c40571b0fad6f7ee2596/src/compare.py代替即可。

如果是3.0.0beta,参考下面这个没有找到pam.so文件的说明,然后编辑sudo vim /etc/pam.d/gdm-password,添加:auth sufficient /usr/local/lib/x86_64-linux-gnu/security/pam_howdy.so,路径替换为find / -name pam_howdy.so。同时参考避免conda环境影响使用中的内容指明模块路径。查看日志:sudo journalctl -u gdm,测试:sudo systemctl restart gdm

没有找到pam.so文件

编辑meson.options,修改option('install_pam_config', type: 'boolean', value: true, description: 'Install pam config file (for Debian/Ubuntu)')

然后执行meson setup build --reconfigure重新配置和编译。

避免conda环境影响使用

编辑sudo vim /usr/local/lib/x86_64-linux-gnu/howdy/compare.py的头部,参考如下:

#!/usr/bin/env python3
# Compare incoming video with known faces
# Running in a local python instance to get around PATH issues

# Import time so we can start timing asap
import time

# Start timing
timings = {
    "st": time.time()
}

# Import required modules
import sys
import os
import json
import configparser
import getpass
import subprocess

# 检查当前Python解释器是否是Conda环境
if 'conda' in sys.version or 'Continuum' in sys.version:
    print("Detected Conda environment. Switching to system Python 3...")

    # 获取当前脚本的路径
    script_path = os.path.abspath(__file__)

    # 构造命令使用系统的Python 3重新运行脚本
    command = f'/usr/bin/python3 {script_path}'

    # 调用系统的Python 3重新运行脚本
    subprocess.run(command, shell=True)
    sys.exit(0)

print("Using system Python 3")

# 强制添加dlib路径
dlib_paths = [
    '/usr/local/lib/python3.11/dist-packages',
    '/home/yige/.local/lib/python3.11/site-packages'
]

for path in dlib_paths:
    if path not in sys.path:
        sys.path.append(path)
# 打印 Python 版本
print(f"Python version: {sys.version}")

# 打印运行的用户
print(f"Running user: {getpass.getuser()}")

# 尝试获取并打印 pip 版本
try:
    pip_version = subprocess.check_output([sys.executable, '-m', 'pip', '--version'], text=True)
    print(f"pip version: {pip_version.strip()}")
except Exception as e:
    print(f"Failed to get pip version: {e}")

# 打印 sys.path
print("sys.path:")
for path in sys.path:
    print(f"  {path}")

# 打印环境变量
print("Environment variables:")
for key, value in os.environ.items():
    print(f"  {key}: {value}")
import dlib
import cv2
import datetime
import atexit
import subprocess
import snapshot
import numpy as np
import _thread as thread
import paths_factory
from recorders.video_capture import VideoCapture
from i18n import _

更新说明

2022年10月29日

  • 添加查看报错信息的方法
  • 添加对python3的支持
  • 修改文章名称

2024年08月04日

  • 添加更多异常情况的解决办法。
  • 总而言之,遇到问题自己参考文章内容进行研究,风险自担。
打赏
交流区

暂无内容

尚未登陆
发布
  上一篇 (Mac通用控制bug临时解决方案)
下一篇 (Win11 多用户同时登录远程桌面配置方法)  

评论回复提醒