How I remember my YubiKey

By | August 15, 2018

[The technique described here is obsolete. Please see this update.]

I’ve recently started using a YubiKey NEO for two-factor authentication for sites that support it.1

Because I am using my YubiKey for more and more sites, I tend to leave it plugged in whenever I am in front of a computer for an extended period of time. The first day I was using the key it became clear that this was going to be a problem, when I left it plugged into my computer at work and didn’t realize it until I’d gotten home. Yes, new technology leads to new problems, but problems that are created by technology can be solved by technology too. Here’s how I solved the “Don’t forget your YubiKey at work” problem.2

The Android Tasker app allows you to create automated workflows for a huge array of triggers, actions, and tasks. For example, you can turn on WiFi automatically when you get home (location-based trigger), generate a special alert when you receive a text message from a specific sender, and on and on; the possibilities are quite overwhelming. To solve this particular problem, I took advantage of Tasker’s “BT Near” trigger, which can be used to detect when a BlueTooth device matching specified criteria is within range of my phone.

High-level summary

At the most basic level, I tell Tasker to pay attention to whether I am near one of the computers that I plug my YubiKey into by watching for their BlueTooth interfaces, and to alert me when I walk away from one of them.

But that’s not quite enough. If I left it at that, then my phone would alert me whenever I walked away from my computer, regardless of whether my YubiKey was actually plugged into it, and that would be really annoying. So I also have my computers paying attention to whether my YubiKey is plugged in and setting a flag when it is that Tasker can check, so that Tasker only bothers me when I actually forget to take it with me.

To make this effective, I have Tasker checking for nearby BlueTooth devices more often than the default, so it notices when I’ve left my YubiKey behind quickly enough that I haven’t already left my house or office building. I’ve also increased the amount of time Tasker waits for BlueTooth devices to announce themselves each time it checks for them, because the default is too short and causes frequent false positives.

What follows are more detailed descriptions of the various components of this solution.

BlueTooth check timing

I’ve adjusted the default Tasker Preferences as follows to make BlueTooth device detection faster and more reliable:

  • On the “UI” tab of the Preferences, uncheck “Beginner Mode” (otherwise, I can’t see all of the preferences I need to adjust)
  • On the “Monitor” tab of the Preferences:
    • Under “Display On Monitoring”, change “BT Scan Seconds” to 35
    • Under “Display Off Monitoring”:
      • Change “All Checks Seconds” to 40
      • Change “Timeout Seconds” to 35
      • Check “Use Motion Detection” (otherwise Tasker’s BlueTooth checks when your screen is off will consume a lot more battery)
    • Under “General Monitoring”, change “BT Minimum Timeout Seconds” to 20

Even with these changes to the Preferences, I find that the Tasker Profile for this alert regularly “bounces,” i.e., decides that I am no longer near my computer and then changes its mind a few seconds later and decides that I am, when I’ve never moved. This appears to be due to a bug / deficiency in Tasker which many of its users encounter. I’ve employed a commonly recommended “de-bouncing” workaround for this, described below.

Proximity detection and alerting

Here’s what my profile for this problem looks like. How to create a profile like this within Tasker is left as an exercise to the reader; play around with Tasker or consult its user guide for assistance. I will, however, offer two tips:

  1. You need to name the profile after you create it because one of the actions within the exit task refers to the profile name; to do that, long-tap on the profile after creating it and then tap the little “A” icon that comes up to give it a name.
  2. When you make changes to your profiles, Tasker doesn’t actually apply the changes unless you exit from the app using the back arrow or tap the checkmark that shows up at the top of the main screen when there are unapplied changes. Don’t fall into the trap of scratching your head, wondering why the changes you made aren’t doing anything, when it’s because you haven’t actually applied them.

Note that I’ve actually edited out some pieces of the profile (that’s why there are gaps in the numbering) that I’m going to explain below, so you can just see the basic structure of the profile in this initial presentation of it.

Profile: YubiKey Reminder (31)
State: BT Near [ Name:* Address:first computer BlueTooth address/second computer BlueTooth address/… Major Device Class:Any Standard Devices:On Low-Energy (LE) Devices:Off Unpaired Devices:On Toggle BlueTooth:On ]
Enter: Remove YubiKey Reminder (33)
A1: Notify Cancel [ Title:Don’t Forget Your YubiKey Warn Not Exist:Off ]

Exit: Remind Me About YubiKey (30)
Run Both Together
A4: Notify [ Title:Don’t Forget Your YubiKey Text:Don’t Forget Your YubiKey Icon:null Number:0 Permanent:Off Priority:5 ]
A5: Vibrate [ Time:1000 ]
A6: Beep [ Frequency:8000 Duration:500 Amplitude:50 Stream:4 ]

In other words, “Create a profile called ‘YubiKey Reminder’. This profile is active when my phone is near one of my computers. Whenever the profile becomes Inactive, i.e., I walk away from my computer, alert me with a notification, a vibration, and a beep. Whenever the profile becomes active, i.e., I return to my computer, remove the notification if it’s currently being displayed.” You obviously don’t have to use the same notifications I do; use whatever works for you.

Note that search fields in Tasker use “/” as the separator for OR’ing values, so since I list multiple BlueTooth addresses in the “BT Near” state separate by slashes, the state will match if any of the listed addresses is seen nearby. (On Linux, you can use the command hcitool dev to find out your computer’s BlueTooth address. I don’t know how to do this on other operating systems.)

Now, concerning the de-bouncing logic I mentioned, here’s the profile again, with the de-bouncing logic added to it, shown in bold:

Profile: YubiKey Reminder (31)
State: BT Near [ Name:* Address:first computer BlueTooth address/second computer BlueTooth address/… Major Device Class:Any Standard Devices:On Low-Energy (LE) Devices:Off Unpaired Devices:On Toggle BlueTooth:On ]
Enter: Remove YubiKey Reminder (33)
A1: Notify Cancel [ Title:Don’t Forget Your YubiKey Warn Not Exist:Off ]

Exit: Remind Me About YubiKey (30)
Run Both Together
A1: Wait [ MS:0 Seconds:10 Minutes:0 Hours:0 Days:0 ]
A2: Stop [ With Error:Off Task: ] If [ %PACTIVE ~ *,YubiKey Reminder,* ]
A4: Notify [ Title:Don’t Forget Your YubiKey Text:Don’t Forget Your YubiKey Icon:null Number:0 Permanent:Off Priority:5 ]
A5: Vibrate [ Time:1000 ]
A6: Beep [ Frequency:8000 Duration:500 Amplitude:50 Stream:4 ]

In other words, “Whenever Tasker thinks I’ve walked away from my computer, wait five seconds and check again, and don’t generate any alerts if Tasker now thinks I’m back at my computer.”

This de-bouncing logic, coupled with the preference values given above, seems to be enough, at least for me, to prevent false alerts. If you find that it isn’t, then either you need to increase the time in the “Wait” action shown above, or you need to increase the value of the “BT Scan Seconds” preference. You can tell which one is necessary by enabling the Run Log and (More | Run Log from the main menu) and checking whether there’s a long (like more than 30 seconds) gap between when the YubiKey Reminder profile goes inactive and when it goes active again. If it’s a long gap, you need to increase the preference; if it’s a gap of less than that, you need to increase the wait time. Note that when you change the preference, you also have to increase the other preferences mentioned above by the same amount, because they are all linked to each other and Tasker won’t let you increase the one without increasing the others.

Is my YubiKey actually plugged in?

You could leave things here, with Tasker reminding you every time you walk away from your computer to take your YubiKey with you. But there’s more fun to be had: what about making it only remind you if your YubiKey is actually plugged in?

My solution to this has three components:

  1. Teach my computers to notice when my YubiKey is plugged in our unplugged and push that information into the cloud in (near) real-time.
  2. Set up a little service in the cloud to accept the information pushes from my computers and make that information available to Tasker.
  3. Teach Tasker to query the service to find out whether my YubiKey is plugged in, and only bother me with alerts if it is.

I run my own virtual server (which I will call “jik-virtual-server” in the examples below, though that’s not its real host name, obviously) with Apache httpd on it, so it was easy for me to create a little service there to track whether my YubiKey is plugged in (I imagine one might also be able to do this with IFTTT, though I haven’t ever actually used it so I’m not certain). I created the CGI script https://jik-virtual-server/~jik/ykp.cgi (“ykp” stands for “YubiKey Plugged”, though obviously you can name it whatever you want) which looks like this:

#!/bin/bash
case "$QUERY_STRING" in
    *add*) touch ~/public_html/ykp ;;
    *remove*) rm -f ~/public_html/ykp ;;
esac

echo "Content-Type: text/plain"
echo

With this script in place, every time someone fetches the URL https://jik-virtual-server/~jik/ykp.cgi?add, the script creates https://jik-virtual-server/~jik/ykp, and every time someone fetches https://jik-virtual-server/~jik/ykp.cgi?remove, it is removed.

Next, how to make my computers notice when my YubiKey is plugged in or unplugged and notify my little service? For this, I use two different approaches in parallel, for redundancy: a systemd timer and associated service which run a script periodically to check whether the YubiKey is plugged in and notify the service as needed; and a udev rule to trigger the systemd service whenever there’s an add or remove event for the YubiKey.

The udev rule triggers the systemd service rather than calling a script directly which hits the web service because, at least on Ubuntu Linux, udev scripts are blocked from using the network.

Setting up the systemd service and timer

Create the executable script /usr/local/bin/yubikey-monitor.sh, tweaked to replace my URLs with yours (note that the lockfile command used in this script comes from the procmail package):

#!/bin/bash -e

FLAG=/var/run/yubikey-watcher
ADD_URL='https://jik-virtual-server/~jik/ykp.cgi?add'
REMOVE_URL='https://jik-virtual-server/~jik/ykp.cgi?remove'

trap "rm -f \"$FLAG.lock\"" EXIT
lockfile -1 -l 5 "$FLAG.lock"

if usb-devices 2>/dev/null | grep -q -s -i -w yubikey; then
    ACTION="add"
else
    ACTION="remove"
fi

if [ "$ACTION" = "add" ]; then
    if [ ! -f "$FLAG" ]; then
        curl --silent "$ADD_URL"
        touch "$FLAG"
    fi
elif [ -f "$FLAG" ]; then
    curl --silent "$REMOVE_URL"
    rm -f "$FLAG"
fi

Next, create /etc/systemd/system/yubikey-monitor.service:

[Unit]
Description=Check for inserted Yubikey

[Service]
Type=oneshot
ExecStart=/usr/local/bin/yubikey-monitor.sh

And /etc/systemd/system/yubikey-monitor.timer:

[Unit]
Description=Check for inserted Yubikey every 5 seconds

[Timer]
OnStartupSec=60
OnUnitActiveSec=60

[Install]
WantedBy=timers.target

Then do systemctl daemon-reload, systemctl enable yubikey-monitor.timer, and systemctl start yubikey-monitor.timer.

Note that if the udev approach described below is working properly, then the timer should never be needed because the script should get called automatically whenever a YubiKey is plugged or unplugged, but we run the timer once per minute just in case something goes wrong with udev.

Setting up the udev rule

Create /etc/udev/rules.d/50-yubikey.rules with these contents:

ATTRS{idVendor}=="1050", ACTION=="add|remove", RUN+="/bin/systemctl start yubikey-monitor.service"

Then run udevadm control --reload-rules.

Checking in Tasker if the YubiKey is plugged in

So, now I’ve got my computers notifying my virtual server when my YubiKey is plugged in and my virtual server making that information available for Tasker to use, I need to make Tasker use it. Here’s how the profile looks with that functionality integrated into it (additions in bold):

Profile: YubiKey Reminder (31)
State: BT Near [ Name:* Address:first computer BlueTooth address/second computer BlueTooth address/… Major Device Class:Any Standard Devices:On Low-Energy (LE) Devices:Off Unpaired Devices:On Toggle BlueTooth:On ]
Enter: Remove YubiKey Reminder (33)
A1: Notify Cancel [ Title:Don’t Forget Your YubiKey Warn Not Exist:Off ]

Exit: Remind Me About YubiKey (30)
Run Both Together
A1: Wait [ MS:0 Seconds:5 Minutes:0 Hours:0 Days:0 ]
A2: Stop [ With Error:Off Task: ] If [ %PACTIVE ~ *,YubiKey Reminder,* ]
A3: HTTP Head [ Server:Port:https://jik-virtual-server Path:~jik/ykp Attributes: Cookies: User Agent: Timeout:10 Trust Any Certificate:Off Continue Task After Error:On ]
A4: Notify [ Title:Don’t Forget Your YubiKey Text:Don’t Forget Your YubiKey Icon:null Number:0 Permanent:Off Priority:5 ] If [ %HTTPR eq 200 ]
A5: Vibrate [ Time:1000 ] If [ %HTTPR eq 200 ]
A6: Beep [ Frequency:8000 Duration:500 Amplitude:50 Stream:4 ] If [ %HTTPR eq 200 ]

In other words, “When Tasker decides I’ve walked away from my computer, before alerting me it should check if the URL indicating that my YubiKey is plugged in exists, and only alert me if it does.”

And there you have it. My phone is now loudly alerting me whenever I walk away from my computer and leave my YubiKey behind, and yours can too, assuming that you’re as ridiculously obsessive about stuff like this as I am and willing to take the time to set it up.

Please email me or comment if you found this useful!

P.S. Don’t forget to back up your Tasker configuration (“Data” -> “Backup” from the home screen menu) and save the backup file somewhere off your phone, so you don’t have to rebuild everything if you lose or break it! Note, however, that preferences aren’t saved in the backups, so you’ll have to redo all the timeouts as described above.


1A quick primer, for those of you who are unfamiliar… The YubiKey sends two-factor authentication information to web sites when I either tap the button on the key, when it is plugged into my computer, or tap it on my phone’s NFC sensor, if I’m logging into somewhere on my phone. Furthermore, for sites that support Universal 2nd Factor (U2F) authentication, the YubiKey adds an additional layer of security, confirming the identity of the web site I’m logging into to ensure that I’m not being phished.

2If someone else has already solved this problem and I’m a fool to have wasted my time on it ;-), please feel free to let me know in a comment below. I’m always happy to throw away my own hacks and use somebody else’s instead, if it means one less hack for me to have to maintain.

Share

7 thoughts on “How I remember my YubiKey

  1. Jeff Brixhamite

    Alternatively … you place your Yubikey on the keyring with your car keys. I bet you never drive home and leave the key behind again that way.

    Reply
    1. jik Post author

      I don’t drive to/from work. If I kept my Yubikey on my keyring then I could easily plug it in at home, forget it was plugged in, walk out of the house without my keys in my bag where I usually keep them, and then realize only once I’m at work that I don’t have my Yubikey.

      Furthermore, I keep my Yubikey on a chain around my neck because I use it all the time, including when I’m at home. I don’t want to carry my keyring around with me in my own home, and I don’t want to have to go run to get my keys every time I need my Yubikey.

      I admire your ability not to envision that other people’s circumstances might be different from yours. Thanks for the mansplaining here, it’s really helpful.

      Reply
      1. jik Post author

        Also, did you miss the fact that someone else made basically the same comment as you a year ago, and I already replied and explained why it wasn’t a useful solution? Scroll down a bit and you can see that other comment. Reading other comments before chiming in is generally considered polite; you should try it some time.

        Reply
  2. Pingback: How I remember my YubiKey, take three – Something better to do

  3. Pingback: How I remember my YubiKey, take two – Something better to do

  4. Anonymous

    Dude this is all really interesting. I assume you had some fun setting it all up but wouldn’t it be easier to simply attach it to your car/house keys or something?

    Reply
    1. jik Post author

      Figuring out how to make it all work is indeed half the fun.

      But your suggested solution doesn’t really work. I don’t drive to work, I take the bus, bike, or walk, depending on the weather and my mood. I often leave the house before my family in the morning, which means I don’t need to lock up the house. So if my YubiKey is on my keychain and I use it at home, the odds are I’ll forget, leave it plugged in, and not realize I don’t have it until I get to work and need it.

      YMMV.

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *