boltgolt/howdy

Revised Installation Instructions for Howdy 3.0.0 beta from Source (Debian-based):

Opened this issue · 21 comments

Hello all. As a recent Linux convert I was seeking out a way to use my Windows Hello for authentication because I had gotten very used to it on my laptop. I discovered this project but like many of you there were pains in getting it to properly install. There was a lot of scattered troubleshooting information out there and I found the existing documentation a bit lacking. I really want to keep this project alive and I know @boltgolt can't work on it as often as they used to so one day I sat down and wrote this very wordy but descriptive guide in an effort to consolidate a lot of these sources. This was written partially for my own documentation, but I'm also sharing it for others to use if they are also struggling. The main thing I intended to properly fix was installing dlib without breaking system packages and instead using a venv which I believe I succeeded in doing. I used it for my install on Mint 22.1 but it should work on Ubuntu/Debian just as well, lthough I have done no additional testing for either case. Keep in mind I have very, very little actual programing or Linux knowledge so a lot of this may be very janky. If there is any glaring issues with any of it please let me know. I am hoping if this is good enough it could potentially be merged into the official README but we will see I guess.

Installing boltgolt/Howdy 3.0.0 beta with Python 3.12 on Mint 22.1:

Specifically using:
Howdy Beta 3.0.0 (commit c4521c1 - Feb 2, 2025)
ZenBook UX425UG Q408UG
Kernel: 6.8.0-55-generic

Link to original inspiration for instructions (heavily modified)

Preparation:

  1. Clone the project with version 3.0.0 beta (beta branch). Clone this to an easily accessible folder somewhere where it won't be accidentally messed with. I don't think there is anything wrong with putting this somewhere in /home/ but it caused some slight issues for me so maybe don't do that. For me, I choose to put the parent howdy/ folder in /opt/. This location (/opt/howdy/) will be referred to as /path/to/project/.

  2. Edit meson.options in the downloaded folder and find option('install_pam_config') Change value: false to value: true

    • This will make sure the howdy Pam config is compiled properly and will be picked up by your system as an authentication method for all auth types in /etc/pam.d/. If you only want to use Howdy for specific auth types that can be found in the Howdy wiki.
  3. (Optional) Install python-is-python3: sudo apt install python-is-python3 Because we will be changing the path of the python binary during this build, Howdy will not require this package to function correctly. Thus, this is not essential however on distros that have separate Python and Python 3 binaries it is a nice feature to have. Very easy to uninstall if it causes problems which it shouldn't unless you also use python 2 dependent programs.

  4. dlib Installation:

    • Ever since Debian 12/Ubuntu 23ish (and now any distro using Python 3.12 or higher I think), the OS, by default prevents you from installing pip packages into the global environment (PEP 668). The proper way to go about using pip packages then is with a python virtual environment (venv). The build portion of this guide will go through the process of setting this up so hold off on installing dlib until then.
    • If this does not end up working later on during the Howdy Install, you can override this prevention with pip3 install dlib --break-system-packages but it is not recommended as it may cause issues with essential system packages for your distro. (don't use sudo)

Setup and Building:

Build and install as partially mentioned in README. (modified)

If you want to build Howdy from source, a few dependencies are required.

Dependencies

  • Python 3.6 or higher
    • pip
    • setuptools
    • wheel
    • opencv
    • dev
    • venv
  • cmake
  • make
  • build-essential
  • meson version 0.64 or higher
  • ninja-build
  • INIReader (can be pulled from git automatically if not found)
  • libpam0g-dev
  • libinih-dev
  • llibevdev-dev
  • libopencv-dev
  • libevdev

To install them on Debian/Ubuntu for example:

sudo apt-get update && sudo apt-get install -y \
python3 python3-pip python3-setuptools python3-wheel \
python3-opencv python3-dev python3-venv cmake make \
build-essential meson ninja-build libpam0g-dev \
libinih-dev libevdev-dev libopencv-dev

(The backslashes are only there for formatting, can be removed if they cause issues, this is all a single command)

Now we need to configure our Python virtual environment like mentioned in step 4:

# cd to project foler

cd /path/to/project/

# Create venv under folder named .venv/ inside project
# directory that can access system-managed python packages

python3 -m venv .venv/ --system-site-packages

Note: --system-site-packages is used to prevent the user from having to install every minute pip dependency again in the venv although you could do that to isolate howdy's python install even more if you wanted by removing the flag and installing everything like mentioned.

The .venv/ folder can be named whatever you like so long as you change your python path in the next step accordingly, .venv/ is simply a convention.

Now go back to meson.options and change '/usr/bin/python' in option('python_path') to '/path/to/project/.venv/bin/python3'. This is a crucial step for ensuring that Howdy is pointing to the correct Python binary inside of the venv and by extension the correct pip packages.

Meson Setup:

Next you need to activate the venv you just created and setup your meson build for compilation with the proper configuration.

source .venv/bin/activate

# (.venv) should now appear before your username in bash

meson setup build --python.install-env venv 

# If everything appears to finish without error then you are
# good to move on

While still in the venv, it is a good time to install the pip package dependencies (mainly dlib) as well as meson (Meson was already installed earlier but for this to work properly you should use the pip version installed separately in the venv. You may even get away with not installing it through apt although I have not tested that).
You can run pip like normal for installation (don't use sudo):

pip3 install dlib meson elevate keyboard

# elevate and keyboard are other dependencies for howdy-gtk
# (GUI) and rubberstamps respectively, they are not needed if
# you don't plan on using either feature

Build:

meson compile -C build

(All of this will create and compile your Howdy build into a folder build inside of /path/to/project)

You can then install Howdy to your system with:

meson install -C build

Howdy should now be installed with the main directory of note at /usr/local/lib/x86_64-linux-gnu/howdy/ and configs at /usr/local/etc/howdy.

You can leave the venv by simply running:

deactivate

Post-Install Setup:

  1. First we need to designate our IR camera: This can be done easily with v4l-utils. If you do not already have it it can be installed with sudo apt install v4l-utils and run with the command v4l2-ctl. You will then want to run v4l2-ctl --list-devices, this will list the video devices that appear in /dev (ex. /dev/video0, /dev/video1, etc...). In determining which video device is the correct one, qv4l2 is another helpful tool you can use, installed it with: sudo apt install qv4l2, run the command qv4l2 and a GUI should pop up showing information about the selected camera. Under File > Open Device you should have the option to pick from the aforementioned video devices under /dev, here you can select them one at a time until you find the one designated for IR. if qv4l2 does not show you readable names for each device under "General Information", testing of each device can be done by hitting the green, "Start Capturing" button in the top left until you find the device which both captures IR and activates the IR emitter (blinking red light). If the devices captures IR but does not activate the emitter, see the note about linux-enable-ir-emitter

    • It is also good practice to use the device name under /dev/v4l/by-path instead of just /dev as these device IDs will never change whereas the /dev names (video0, video1, etc.) may occasionally change at startup. These can be looked through with v4l2-ctl -d /dev/v4l/by-path/[fileName] -Dfor each file in the directory until the correct one is found. Mine was /dev/v4l/by-path/pci-0000:05:00.3-usb-0:3:1.2-video-index0.
  2. Now that we have found the IR camera, it's time to designate it in the Howdy config file. Typing sudo Howdy config should allow you to edit it but the file is also located at /usr/local/etc/howdy/config.ini if you wanted to edit it manually.

    • Find: device_path = none and replace none with your IR camera directory, in my case, this was /dev/video2
    • You will likely also have to change dark_threshold to something larger, I set mine to 90 because my IR emitter isn't all that great.
  3. One more fix we need to do before Howdy face model setup is symlink the pam-config for howdy to the proper pam-configs folder which is not in the right place by default for some reason having to do with the default meson install location for Howdy (the meson prefix is by default/usr/local/ of which share/pam-configs/howdy is added onto it for the final install path):
    `sudo ln -s /usr/local/share/pam-configs/howdy /usr/share/pam-configs/howdy

    • This fix can be verified by running sudo pam-auth-update and ensuring Howdy is present and enabled in the available options.
    • Note: If you want to configure Howdy to only work with specific auth types as seen in step 2, you should disable Howdy in pam-auth-update and follow the wiki for editing specific config files.

Real Setup

To begin with creating a stored face run: sudo howdy add. If you are given any errors involving missing packages, ensure dlib and the other dependencies were all installed properly and try again. It will likely ask you to run a script to download models on first attempt, this is normal procedure for dlib and it means things are working properly. Follow the rest of the instructions and let Howdy scan your face. If it says the scan was too dark, try increasing the dark_threshold value in the config mentioned earlier.
- Other troubleshooting tips can be found here here

Now, you can add and test the face (sudo Howdy test). Authentication for sudo and login should work now.

Uninstallation

Navigate to /path/to/project/build, open a terminal and run:

sudo ninja uninstall 

I think this technically just runs:

/path/to/project/.venv/bin/meson --internal uninstall

due to this excerpt from path/to/project/build/build.ninja

# Suffix

build uninstall: phony meson-internal__uninstall

build meson-internal__uninstall: CUSTOM_COMMAND PHONY
 COMMAND = /opt/howdy/.venv/bin/meson --internal uninstall
 pool = console

but I'm not really sure.

Notes

  • If face recognition login is still having problems. You may need to manually modify /usr/local/lib/x86_64-linux-gnu/howdy/compare.py. Add sys.path.append('/usr/local/lib/python3.12/dist-packages') after the import sys line. You should only have to do this if you installed the pip dependencies using pip3 install dlib --break-system-packages instead of making a venv.

  • The new version of Howdy has a GUI utility howdy-gtk. Python module elevate is needed which I talked about installing earlier. You can activate this feature with sudo howdy-gtk.

  • linux-enable-ir-emitter provides support for infrared cameras that are not directly supported (at the very least, the kernel must recognize your infrared camera). It can almost automatically, configure any infrared camera. Use this if your IR emitter does not function when using Howdy normally.

  • Rubberstamps - (Not really ready yet) By default Howdy will authenticate you the moment you have been successfully recognized. However, a lot of users want to have more control over the authentication flow. This is where rubber stamps can help. Rubber stamps are available in Howdy 3.0.0 and up.
    Stamps are activated just after your face has been successfully recognized and can approve or deny the authentication. They have to be manually enabled or disabled in the config.

  • There is an issue with the GNOME keyring being locked on login as mentioned in Ubuntu 24.04 howdy 3.0.0 beta installation #976 (comment)

    • The instructions may not work, but this comment could.

Sources and Helpful Links:

Thank you for this! After upgrading to kubuntu 25.04 I was ready to give up on howdy as the previous hacky installs didn't work anymore and I was tired of doing unsafe stuff to my system anyway. This guide worked flawlessly. I made my own notes so I can do this quickly on my other computer that will also need updating to 25.04. Don't know if it helps anyone but I'll put it in here regardless. It's a condensed version of your guide with the following pre-reqs:

User is markus with home directory of /home/markus.
Camera is found at /dev/v4l/by-path/pci-0000:2d:00.3-usbv3-0:4:1.0-video-index2
There is already an existing /home/markus/opt/github directory.

# As Markus
cd opt/github
rm -Rf howdy # If exists
git clone -b beta https://github.com/boltgolt/howdy.git

cd howdy
kate meson.options 
# Change 'install_pam_config' to "true"
# Change 'python_path' to '/home/markus/opt/github/howdy/.venv/bin/python3'
# SAVE CHANGES... I wasted time before forgetting this. sigh

sudo apt install v4l-utils qv4l2 python-is-python3 python3-pip python3-opencv python3-venv meson libpam0g-dev libinih-dev libevdev-dev libopencv-dev

python3 -m venv .venv/ --system-site-packages # We are still in ~/opt/github/howdy as Markus
source .venv/bin/activate
pip3 install dlib meson elevate keyboard

meson setup build --python.install-env venv
# If meson fails with "not in venv" error: "pip3 install --force-reinstall meson" and try meson command above again

meson compile -C build
meson install -C build
deactivate

sudo howdy config
# Find device_path and set it to device_path = /dev/v4l/by-path/pci-0000:2d:00.3-usbv3-0:4:1.0-video-index2

sudo ln -s /usr/local/share/pam-configs/howdy /usr/share/pam-configs/howdy

cd /usr/local/share/dlib-data
sudo ./install.sh

sudo howdy add

I'm glad to see I could help you out! Thank you for the compressed guide as well as mine could definitely stand to be a bit more brief. Really I just wanted to write out everything in as clear and explanatory of a way possible for other noobs like me to learn along the way but I know not everyone wants to read an essay just to find what commands to do...

Thank you so much! I'm trying to install on KDE Neon, and I was trying to follow the workaround from here: #954 (comment)
But it just didn't work for me. This finally did the trick!

I've been getting this issue with venv where it seems to not recognize that i"m already in a venv every time I try this fix, if I'm just stupid and missing something let me know.

(.venv) german-elias@german-elias-ThinkPad-T14-Gen-1:~/howdy$ meson setup build --python.install-env venv
The Meson build system
Version: 1.3.2
Source dir: /home/german-elias/howdy
Build dir: /home/german-elias/howdy/build
Build type: native build
Project name: howdy
Project version: beta
C++ compiler for the host machine: c++ (gcc 13.3.0 "c++ (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0")
C++ linker for the host machine: c++ ld.bfd 2.42
Host machine cpu family: x86_64
Host machine cpu: x86_64
Configuring paths.py using configuration

howdy-gtk/meson.build:27:22: ERROR: python.install_env cannot be set to "venv" unless you are in a venv!

A full log can be found at /home/german-elias/howdy/build/meson-logs/meson-log.txt

Ubuntu 24.04.2 LTS on a T14 gen 1 (Intel)

Be sure you have edited meson.options and set python_path correctly. I had that error when I edited meson.options but forgot to press save.

Edit: Just ran into this gain on my other computer. After an hour of googling, grok figured it out: It was picking the wrong meson. It was using /usr/bin/meson even though I told it to install it in the venv with "pip3 install meson" while in the venv.

Solution was to do "pip3 install --force-reinstall meson" while in the venv and then it worked.

Be sure you have edited meson.options and set python_path correctly. I had that error when I edited meson.options but forgot to press save.

Got fed up and changed to fedora, Howdy is working flawlessly!! (of course had to solve a couple issues but nothing out of this world)

Be sure you have edited meson.options and set python_path correctly. I had that error when I edited meson.options but forgot to press save.

Edit: Just ran into this gain on my other computer. After an hour of googling, grok figured it out: It was picking the wrong meson. It was using /usr/bin/meson even though I told it to install it in the venv with "pip3 install meson" while in the venv.

Solution was to do "pip3 install --force-reinstall meson" while in the venv and then it worked.

For me installing it again didn't help. After reinstalling I also had to explicitly run meson from inside the venv with:
/path/to/project/.venv/bin/meson

Even though "which meson", already returned the correct path. After running it once explicitly it seemed to be fixed.

Only partially works on kubuntu 25.04. sudo uses face auth, login screen does not. There seems to be a relevant howdy line in /etc/pam.d/common-account but maybe that is not enough?

I have done the howdy install using this procedure on two kubuntu 25.04 machines and howdy works for login and sudo on both. Looking in /etc/pam.d I do notice a difference in that I have a howdy line in common-auth, not common-account. My entry is:

auth [success=2 default=ignore] /usr/local/lib/x86_64-linux-gnu/security/pam_howdy.so

All other files in /etc/pam.d look untouched (no mention of howdy).

I have done the howdy install using this procedure on two kubuntu 25.04 machines and howdy works for login and sudo on both. Looking in /etc/pam.d I do notice a difference in that I have a howdy line in common-auth, not common-account. My entry is:

auth [success=2 default=ignore] /usr/local/lib/x86_64-linux-gnu/security/pam_howdy.so

All other files in /etc/pam.d look untouched (no mention of howdy).

oops yes, its common auth, apologies. still, login screen does not even try to use face auth.

Very odd. Here are my common-auth and sddm files in case it helps.

markus@pc` /etc/pam.d $ cat common-auth 

#
# /etc/pam.d/common-auth - authentication settings common to all services
#
# This file is included from other service-specific PAM config files,
# and should contain a list of the authentication modules that define
# the central authentication scheme for use on the system
# (e.g., /etc/shadow, LDAP, Kerberos, etc.).  The default is to use the
# traditional Unix authentication mechanisms.
#
# As of pam 1.0.1-6, this file is managed by pam-auth-update by default.
# To take advantage of this, it is recommended that you configure any
# local modules either before or after the default block, and use
# pam-auth-update to manage selection of other modules.  See
# pam-auth-update(8) for details.

# here are the per-package modules (the "Primary" block)
auth    [success=2 default=ignore]        /usr/local/lib/x86_64-linux-gnu/security/pam_howdy.so 
auth    [success=1 default=ignore]      pam_unix.so nullok try_first_pass
# here's the fallback if no module succeeds
auth    requisite                       pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
auth    required                        pam_permit.so
# and here are more per-package modules (the "Additional" block)
auth    optional                        pam_cap.so 
# end of pam-auth-update config


markus@pc /etc/pam.d $ cat sddm
#%PAM-1.0

# Block login if they are globally disabled
auth    requisite       pam_nologin.so
auth    required        pam_succeed_if.so user != root quiet_success

# auth    sufficient      pam_succeed_if.so user ingroup nopasswdlogin
@include common-auth
# gnome_keyring breaks QProcess
-auth   optional        pam_gnome_keyring.so
-auth   optional        pam_kwallet5.so

@include common-account

# SELinux needs to be the first session rule.  This ensures that any
# lingering context has been cleared.  Without this it is possible that a
# module could execute code in the wrong domain.
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close
# Create a new session keyring.
session optional        pam_keyinit.so force revoke
session required        pam_limits.so
session required        pam_loginuid.so
@include common-session
# SELinux needs to intervene at login time to ensure that the process starts
# in the proper default security context.  Only sessions which are intended
# to run in the user's context should be run after this.
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
-session optional       pam_gnome_keyring.so auto_start
-session optional       pam_kwallet5.so auto_start

@include common-password

# From the pam_env man page
# Since setting of PAM environment variables can have side effects to other modules, this module should be the last one on the stack.

# Load environment from /etc/environment
session required        pam_env.so

# Load environment from /etc/default/locale and ~/.pam_environment
session required        pam_env.so envfile=/etc/default/locale user_readenv=1
markus@pc /etc/pam.d $ 

Thanks for this complete and clear explanation, and for the condensed summary as well. It worked perfectly.

Very odd. Here are my common-auth and sddm files in case it helps.

@mstrobl2 so it works on screen lock, not on actual login. is there any way around that? windows hello allows face unlock even on first login after boot. kde does not on any fresh login after boot.

It works for me, that's why I said it's so odd you're having this problem. I use howdy on two systems and both will do the initial login using face unlock. Maybe you can find something in the logs? To get a short, concise log:

When you're at the sddm login screen, switch to a different VT (ctrl+alt+F4).
In that VT: journalctrl -f > log.txt
Back to sddm and attempt a login by pressing enter with blank pwd.
Back to VT and ctrl-C.

Login and now you have a log without too much junk.

It works for me, that's why I said it's so odd you're having this problem. I use howdy on two systems and both will do the initial login using face unlock. Maybe you can find something in the logs? To get a short, concise log:

When you're at the sddm login screen, switch to a different VT (ctrl+alt+F4). In that VT: journalctrl -f > log.txt Back to sddm and attempt a login by pressing enter with blank pwd. Back to VT and ctrl-C.

Login and now you have a log without too much junk.

theres nothing even mentioning howdy or anything failing. exact same pam.d configs you posted, howdy isnt even being attempted. im using the beta version built from source, and kubuntu 25.04.

Sorry, I'm out of ideas then,

Thanks for the how-tos.

git clone -b beta https://github.com/boltgolt/howdy.git

The beta branch doesn't seem to exist anymore, I only see master and dev.

I changed to auth sufficient , not sure if that was necessary, but the problem for me with the mint/cinnamon lockscreen is the installation of dlib to either root or user. I guess the lock screen was executing as normal user? Either way i had to install an actual python3-dlib package. The one on one of the issue pages here didn't work but getting the one from the slimbookface ppa did

Sorry, I'm out of ideas then,

Gonna be honest I went back to windows. Death by a million cuts as it were :)

Forget it, was able to follow: https://ubuntuhandbook.org/index.php/2024/10/howdy-ubuntu-2404/

Found in #1021

Way easier than building from source

Thank you very much for the thorough and informative guide! I experienced multiple issues along the way on a ThinkPad E16 Gen 1 running Linux Mint 22.2 but managed to get it working in the end. For anyone attempting this in the future on a similar config, below are the problems I experienced and how I fixed them. I also included some helpful tips at the end which will make the process quicker.

Issue 1: "No module named dlib"

This one was tricky, as I wasn't able to find anyone else discussing it. If you get No module named 'dlib' (or any other module) when running sudo howdy add, but the module works in venv without sudo (/path/to/project/.venv/bin/python3 -c "import dlib" doesn't error, but sudo /path/to/project/.venv/bin/python3 -c "import dlib" does), the module was likely installed to your user site-packages (~/.local/lib/python3.*/site-packages) instead of the howdy venv.

Fix:

  1. Remove the module from user site-packages:

    rm -rf ~/.local/lib/python3.*/site-packages/<module_name>*
  2. Make the venv writable and reinstall the module. This will stop the "Defaulting to user installation because normal site-packages is not writeable." message.

    sudo chown -R $USER:$USER /path/to/project/.venv
    /path/to/project/.venv/bin/pip3 install <module_name>
  3. Verify it's in the venv:

    /path/to/project/.venv/bin/python3 -c "import <module_name>; print(<module_name>.__file__)"

    Should show /path/to/project/.venv/lib/python3.*/site-packages/<module_name>

Cause: When the venv isn't writable, pip defaults to --user installation, which isn't in sudo's Python path.

Issue 2: Howdy scripts using system Python instead of venv Python

Some howdy scripts (like howdy-gtk) may use the system Python (/usr/bin/python3) instead of the venv Python, causing module import errors.

Fix:

  1. Find which script is failing:

    which howdy-gtk  # or whichever command is failing
  2. Edit the script to use the venv Python:

    sudo nano /usr/bin/howdy-gtk  # or whatever path was returned
  3. In the file, change the following Python path:

    /usr/bin/python3

    to:

    /path/to/project/.venv/bin/python3

    (Adjust the path to match your howdy installation)

Cause: The script's points to system Python, which doesn't have access to venv packages.

Issue 3: Howdy doesn't appear as authentication option

If howdy doesn't prompt for face recognition during sudo or login (only asks for password), the Howdy PAM script may be silently failing. This can be fixed by using /usr/local/lib/x86_64-linux-gnu/security/pam_howdy.so instead of the default /lib/security/howdy/pam.py. Credits to this reply for providing the fix.

Fix:

  1. Open /etc/pam.d/common-auth, or other relevant files.
    sudo nano /etc/pam.d/common-auth
  2. If you find a line like:
    auth [success=2 default=ignore] pam_python.so /lib/security/howdy/pam.py
    
  3. Replace it with:
    auth [success=2 default=ignore] /usr/local/lib/x86_64-linux-gnu/security/pam_howdy.so
    
  4. Test authentication:
    sudo -i

Cause: Howdy used an old Python script with pam_python.so, which has multiple issues. This needs to be replaced with pam_howdy.so.

Bonus tips

  • I needed to use linux-enable-ir-emitter to get my IR emitter to activate. They have a simple guide on how to integrate it with Howdy which you can read here.
  • When attempting to find the device name of your IR camera under /dev/v4l/by-path, you can look through them using v4l2-ctl -d /dev/v4l/by-path/[fileName] --stream-mmap. The --stream-mmap flag should enable the provided device; if it is an IR camera, the flashing IR emitter will make it immediately obvious if the device is the correct one. If it is a camera with a light that lights up when the camera is in use, it will also be activated. Make sure to not include the backslash escape characters when pasting the device path into your Howdy config.

These were the main issues I encountered during my installation. Hope this helps others avoid the troubleshooting time I had to spend figuring these out!