AWS, Linux, Yubikeys and MFA

Seán Murphy
4 min readNov 7, 2021

AWS supports U2F MFA which can be used with Yubikeys to support secure access to your AWS account with an important limitation — only a single U2F device can be associated within any account, be that a root account or an IAM account. If you are not administering an AWS account, this is probably reasonable in many cases — if something happens to the Yubikey, MFA can be temporarily disabled via the root account and a new device can be associated with the account.

When responsible for root accounts, however, this approach is not realistic as loss of the Yubikey can render a root account inaccessible requiring AWS intervention to provide access to the account.

An alternative approach for those working in Linux is to use GPG on the Yuibikey with pass, a Virtual MFA and the pass-otp extension — this can be used with multiple Yubikeys which contain the same GPG key and remains quite easy to use when configured properly. It can also be used in conjunction with mobile authentication apps as appropriate.

Assuming you have GPG keys set up on your Yubikey and you are using pass for password management, you can install the pass-otp extension for this scenario. This is packaged in recent versions of Ubuntu as pass-otp in Hirsute and pass-extensions-otp in Impish — an apt install will install it. (Similar packages exist for Arch and Fedora). Once installed, you should simply be able to run pass otp from the command line.

With that set up, you can add an OTP generator to pass. In AWS, modify your Security Credentials such that you are adding a Virtual MFA Device — if you have an existing Virtual Device registered, you may need to deregister it and register a new one. Take a screenshot of the QR Code — this will be provided as an input to pass otp Note that this QR Code contains sensitive information so be sure to delete it when finished.

Add the secret contained in the QR code — essentially the OTP generator — to pass using

$ zbarimg -q --raw /tmp/qr-code.png | pass otp insert <name-of-secret-in-pass>

(this uses the zbar-tools to extract the information from the QR code which you may need to install if not installed already).

This will add a secret to pass using the name you specify — you can view this secret as normal using pass show and you will see a single line of the form:

otpauth://totp/Amazon%20Web%20Services:<AWS-identifier>?secret=<SOME-SECRET>&issuer=Amazon%20Web%20Services

To generate a OTP from the command line, simply type pass otp <name-of-secret-in-pass> .

You now have a mechanism to log in to AWS which uses MFA and is secured using GPG and your Yubikeys but is not tied to any specific device.

At this point, it is worth noting that you can scan the same QR code in mobile authentication apps such as Authy or Google Authenticator to have an alternative way to create this OTP should you require it.

So with pass able to generate a valid OTP, we can make it slightly more convenient to use using rofi-pass. rofi-pass uses rofi to access information in pass — in some sense, an evolution of passmenu. rofi-pass has built in support for OTPs which get copied to the clipboard and automatically pasted to context. Although rofi-pass is not packaged with Ubuntu, it is a simple bash script which is very easy to install from the git repo using make install.

rofi-pass assumes passwords are stored in a specific format; it assumes passwords are of the form:

<password-string>
user: <user-string>
url: <url-string>
autotype: <autotype-string>

ie, the password string is the first line and the subsequent lines contain a set of keys and values separated by a : — it does not make any assumptions on what fields follow the password, simply the format that is used. autotype is a special field which can be used to specify ways to combine the other fields and is important in the OTP case.

To use rofi-pass with a OTP, add an extra line to your secret file — you can do this with pass edit <secret-name>; this will open the secret in your standard editing environment. Add the line autotype: :otp to the file such that it looks like this:

otpauth://totp/Amazon%20Web%20Services:<AWS-identifier>?secret=<SOME-SECRET>&issuer=Amazon%20Web%20Services
autotype: :otp

Now you can invoke rofi-pass directly from the command line, search for the secret using via the menu and select the secret; you will then be asked what information from the secret you wish to obtain — when you select autotype it will generate the OTP and paste it into your shell environment.

rofi-pass is, of course, intended to be invoked via the window manager, so set up a keyboard mapping which triggers it and your OTP can be easily pasted into your browser when logging into AWS, giving you a Yubikey backed MFA login mechanism which is easy to use and not tied to any specific device.

--

--

Seán Murphy

Tech Tinkerer, Curious Thinker(er). Lost Leprechaun. Always trying to improve.