Hacker News new | past | comments | ask | show | jobs | submit login
Add two-factor authentication to your ssh in 30 seconds (authy.com)
240 points by danielpal on Aug 28, 2012 | hide | past | web | favorite | 106 comments



Using a third-party service like authy.com has its advantages, but if you prefer, you can get two-factor authentication in the latest Ubuntu without involving a third party by installing libpam-google-authenticator from Ubuntu's "universe" repository.

Here's how you do it: first, sudo apt-get install libpam-google-authenticator; second, run google-authenticator as the user you will access remotely and follow the instructions; then, edit /etc/pam.d/sshd, and add "auth required pam_google_authenticator.so" in a new line; edit /etc/ssh/sshd_config and add (or change) the ChallengeResponseAuthentication line so it reads "ChallengeResponseAuthentication yes"; and finally, sudo service ssh restart to restart the ssh server.

More info is available from the packager of libpam-google-authenticator[1], and from the Google Authenticator PAM module's README.[2]

--

[1] http://blog.theroux.ca/security/ubuntu-2-step-authentication...

[2] http://code.google.com/p/google-authenticator/source/browse/...

--

Edits: Corrected typos; added more context.


The biggest problems is you can't use ssh_keys with this setup. Its too restrictive, and certificates are a must for ssh.

Also what happens if you loose your cellphone? We thought about this and for us the possibility of loosing access to the server fully was too much.


Unless I am mistaken, it should be possible to configure opensshd to first try using keys, then fall back on UsePAM only if that fails (similar to how sshd will normally fall back on PasswordAuthentication).

If not, it might be possible to configure PAM with some sort of keys module set to 'sufficient', then have PAM fall back on two-factor auth paired with pam_unix.

In fact, I'll see if I can get either of those working a bit later today. Seems like it could be neat.


Another option is to whitelist your ip address, and then require 2-factor auth only when you're connecting from a non-whitelisted ip address.

Of course this leaves you a vulnerable to ip spoofing, but adds a ton of convenience and could be a good trade-off.


Yeah but (blind) IP spoofing over the Internet is infeasible nowadays. Maybe 15 years ago when ISN randomization was not the rule (successful attack described in http://web.textfiles.com/hacking/shimomur.txt)

But that's correct, in recent openssh versions, it seems that you can add specific-host-only rules for authentication etc.


You could probably do a hack to let the user login with ssh key and then immediately force the second factor auth to be run, booting the user out if they didn't pass it. Not the best way, but one option.

I also believe I once ran across a patch someone had done to the login code to allow both to be required, I can't find the link right off though as I'm at work currently. If I find it, I'll add it here


A ForceCommand example (for Yubikey) is documented here: http://www.tuxz.net/blog/archives/2010/03/17/how_to_quickly_...


Yes, I have seen a patch as well that allowed you to require both an ssh key and a password ... it was an old patch, though, and I can't imagine it would apply cleanly to any recent OpenSSH ...

This is on our list to pay for someone to do, and we'll release it when they do ... it will probably be FreeBSD-centric, but if it's against OpenSSH generally, it should be usable by others...


What happens if you lose your normal password? Why you boot up into single user mode using the console like the old days of when you forgot the root password.


And how do you do that with cloud instances? :)


Some VPS providers offer "console" access to the machine, which would probably allow someone to drop down into single user mode.

http://www.linode.com/faq.cfm#do-you-provide-console-access


Same way you do when you forget the root password on a normal configuration.


Install a new instance! Its all disposable hardware.


danielpal: google-authenticator prints out emergency scratch codes you can use if you lose your cellphone :-)


Yeah but in reality no-one writes it down. I actually use Google-Auth for my Gmail, but I forgot were I wrote this number down(it was a couple of years ago). Keeping a scratch code for each new server is a pain.


>Yeah but in reality no-one writes it down.

Then that's a process problem that can be solved. It would take a trivial amount of time to screenshot the page and stash them in your wiki or similar.


Those who don't write it down deserve to be locked out.

I've written down mine on three different pieces of paper (in my wallet, my bag and my closet), and also took a screenshot from it and `gpg`-ed it (with a passphrase, so no one can open it unless they know the password) and stored it in a few online repositories, as well as a friend's mailbox.

So, I'll never be locked out from my account.


It's the only sane thing to do!


My scratch codes are in 1Password (for my personal accounts) and LastPass (for work accounts).


People really should do this. It takes 10 seconds, and eliminates having any paper to lose (or keep secure). Copy and paste, and you're done.


Mine are printed out and stored in my safe. They are never used.


> Yeah but in reality no-one writes it down. I actually use Google-Auth for my Gmail, but I forgot were I wrote this number down(it was a couple of years ago). Keeping a scratch code for each new server is a pain.

This is your problem. I keep mine (for multiple services) in my wallet, and it's worked out excellently.


Mine are written down in a post-it note stuck to the inside back-flap of my passport.


You can use the same key for all the servers. Just copy the files generated by the 'google-authenticator' app. I don't see any less security in that.


I use ssh keys with this setup. If I login with an ssh key, I don't need the OTP.


How did you manage to do this? You'd have to use PAM for this to work, and PAM and key-based authentication is mutually exlusive, as far as I know.


If you use a google voice number you can just point it to a new phone.


Don't you need to login to do that? Using 2 factor auth..


Yes, so use your backup keys, or a secondary phone number, or a secondary email address... plenty of options.


Thanks for the instructions, I like the fact that Google Authenticator doesn't need to contact their servers (or at least that's how I understand it). Sounds like you could preserve the use of SSH public key authentication by using Google Authenticator in combination with a ForceCommand; I'll have to look in to that.

Anyone set up Google Authenticator to only challenge me on a host every N minutes or something like that? I.e., first login requires two-factor auth, subsequent logins don't for at least 30 minutes? Seems like it'd be irritating to keep popping my phone out every time I connect to a remote server.


Partial solution: it may be useful to use Host * and ControlMaster auto in your .ssh/config to reuse connection so you do not need to authorize all the time.


Google Authenticator is pretty much a third-party service as well.

Unless I'm mistaken in how Google Authentiator works - of course. If so, please fill in my blank :-)


Using pam-google-authenticator does not depends on Google, they just wrote widely available apps and a PAM module[0] that implement HOTP[1] and TOTP[2]. Basically, you have a seed and a counter that you hash together. When adding a device, the seed and counter are synced with the device. When logging in, the server generates the proper code, then verifies it got that code. The major difference between the two algorithms is that TOTP uses time as its counter, while HOTP uses a manually increased counter.

[0] http://code.google.com/p/google-authenticator/

[1] http://en.wikipedia.org/wiki/HOTP

[2] http://en.wikipedia.org/wiki/Time-based_One-time_Password_Al...


You are mistaken. I'm not sure what blank to fill in. Google Auth use OATH for their two factor auth. Using the reference package just gives you their PAM module. It doesn't require hitting their servers or anything.

http://code.google.com/p/google-authenticator/


If you run google-authenticator with no arguments it hits Google's servers in order to generate a QRcode for your phone to scan.

So you are in fact handing over your 2-factor auth key to Google when you run google-authenticator. There's no actual need for the binary to do this (although it obviously makes the key entry on the phone much less error-prone) and there don't seem to be any command line arguments that would turn it off either. doesn't do this at all -- see below. (can I do strikethrough on HN?)


    So you are in fact handing over your 2-factor auth key to Google when
    you run google-authenticator
Unless things have changed a lot since I last used this, this is not entirely correct. The binary will print out a URL - the QR code is only generated if you hit this URL.

If you visit this URL, you are sending the "QR-encoded" (not exactly, but you know what I mean) version of the key to Google's servers.

As long as you do not visit this link, you will not send your key to Google's servers.


Can't reply to mryan, but I'd just checked this before coming back to HN & indeed, google-authenticator doesn't make any network connections when invoked & it generates the QR-code locally.

So don't hit that URL if you don't want Google to know your 2-factor auth data!


Interestingly it appears this Authy method does not use PAM. I wonder if there is a reason for that, since a PAM module would be a good deal more flexible (this sort of thing is what PAM is for after all).


The basic reason is because we don't use passwords. We always use public/private certificates on all of our machines. With PAM you have to use passwords. We'll release a version soon that works with PAM, but I recommend you switch to using authorized_keys with certificates. Not only is it much more secure, it's also much nicer to use.


I do use authorized_keys, though PAM is good for a lot more than just sshd; that's why I say it is more flexible. For example, I could see two factor authentication being used to log into shared workstations through XDM/GDM. This would eliminate the possibility that your users are sharing passwords for their accounts.

Also, the way I would intend on using this is such that if your public key is in authorized_keys, you log in like normal. If not, you authenticate with PAM using both your unix password (or ldap or whatever you have configured) and your 2nd authentication system. I log into one or two of my servers from strange computers often enough that disabling password authentication entirely on those servers is limiting.


Yeah we'll release a PAM module soon so you can do this. If you don't want to wait, you could write one. Just look at this module, it's fairly simple. The API is really straight forward.


Most probably, they didn't know about PAM.


Not at all. We understand PAM and we plan to release a version that works with PAM. But we don't like passwords, we much rather use public/private ssh keys instead of users with passwords. It's not only much better user experience but is also much more secure.


Pretty cool. Google authenticator is another alternative that be used via a pam module, with the additional benefit that it doesn't need to connect to something else for verification.

https://code.google.com/p/google-authenticator/


Seconding the recommendation for PAM/Google Authenticator.

Off-topic: Has anyone ever managed to get PAM/Google Authenticator working with RADIUS? I spent a while messing about with this last year, and never got it working exactly as I had hoped. I'm no longer working with RADIUS, but this post reminded me I never finished scratching that geeky itch.


I wrote a Sinatra app to act as a Google Authenticator backend for our FreeRADIUS instance as well as our web SSO. It also handles enrollment via generating QR codes:

http://it.isevil.org/blog/2011/11/13/authentication-service-...

Code: https://github.com/bithive/example-totp-vault

For FreeRADIUS we use rlm_perl to define our own authenticate() method; it just calls the web service to validate the codes.


Neat solution, thanks for sharing.


I can't speak for Google Authenticator but Duo works great with RADIUS http://www.duosecurity.com/docs/radius


I've been using Duo Security for two factor auth and have been very happy with it (also easy to set up). Free for all open source projects.


the problem is that google authenticator stores the seed in the phone(and the server) so if you lose it basically you lose the server too, right?


If you mean lose access to the server, then the google-authenticator sets you up with a few emergency one-time codes you could write down on a note and keep safe, in case your phone is lost.


Not to mention you can write down the seed itself and simply type it into another phone.


I don't think google-authenticator does that, I think Gmail does that.


There's a bunch of references to scratch codes in the pam google-authenticator module, but I haven't actually tried to run the code.

http://code.google.com/p/google-authenticator/source/browse/...


the problem is that google authenticator stores the seed in the phone(and the server) so if you lose it basically you lose the server too, right?

If you lose your phone and your scratch codes, you've only lost access via SSH. So it's an inconvenience, but one you can overcome with the right setup.


If you are talking about not being able to log into the server anymore, you can make backups of the seed. On android, you just need to pull the file "/data/data/com.google.android.apps.authenticator2/databases/databases" off the phone.


This only works if your phone has been rooted.


It's two-factor authentication: something you have (phone) and something you know (password to your ssh cert). So, you have to lose both in order to lose the server.


No, both authentication factors are required, so either losing your phone or forgetting your password would be sufficient to lock you out. However, the Google authenticator PAM plugin provides emergency access codes to use in the case that the one-time password generator is not available.


I don't think this is the case. Losing either loses the server in the sense that you won't be able to access it. The fix is that the "something you have" is both your phone and emergency codes.


In security, losing the server doesn't mean losing access to the server. Losing the server means that someone else has access to the server, as in an adversary.

Yes, if you lose either factor, you can't access the server. This is why with Google Authenticator you also get a one time pad with emergency codes. However, I don't know how well this would work with two-factor SSH... you'd need a separate one time pad for each server. And I'm not sure how the Google PAM module handles emergency codes.


I think it still requires your normal password as well, so the server wouldn't be lost unless someone had both.


Well, if that were the case, when I lose my phone (sadly, not if), I would be locked out of years of Google account data. Fortunately there are backup codes. (And for Google a phone number call/text recovery path).


You should really package this up, and provide a signed repo instead of relying on the busted SSL infrastructure and GitHub to provide security to your users.

While this one isn't quite as offensive as some, all these curl/sudo/bash combos really make me sad, particularly when used to "increase" security.


You are right. Best for your infrastructure is to fork it and modify it. We for example have a different version we use for chef and that already include everyone's keys.


SMS is not secure. It can be faked. It goes through multiple networks. It's not encrypted. And if you use a GSM phone, this could be owned two years ago at DEF CON: http://www.pcmag.com/article2/0,2817,2367247,00.asp Not to mention the provider-specific attacks, cloning, etc.

If you start pushing insecure technologies like this, people will just get really comfortable with them and eventually get taken advantage of.


Don't let the perfect be the enemy of the good.


Can I quote you on that when the first "flaw in SMS used to circumvent two factor authentication" article comes out?

A secured data connection is much better than SMS and easy to implement. But this is still a 'something you send' factor, which can be intercepted. A physical token or 'something you have' is more secure, and can also be easily implemented with a YubiKey, a paypal/ebay authentication card, etc.

If you think your data is so valuable someone might install a keylogger to get it, you might as well secure it as well as you reasonably can.


In order for a flaw in SMS to break someone in, the attacker would need to break both SMS and the traditional authentication channel.

Yes, SMS can be broken. I'm sure Google Authenticator is vulnerable to certain attacks, too. Using them is better than throwing your hands up in the air and saying "it's not perfect, we'd better not implement it because then people will act as if they have perfect security!" Because people are already acting like they have perfect security.


You know this is the same reason people keep using telnet to manage their routers. "To attack the protocol would be like totally hard, and upgrading the routers to use ssh would be a pain in the ass. Telnet isn't perfect but it's better than nothing!"

Yeah, SMS isn't perfect, and yeah, it's better than nothing. But you know what else is better than nothing? Properly implemented TLS from an app or website on the phone. Of course that has holes too, but it's encrypted and (hopefully) authenticated unlike SMS. And it's available in every phone that can do SMS (unless you don't pay for data).

You can do whatever you want. But if you give people a crappy option and a good option, and the crappy option is slightly easier, they'll use the crappy option. But if they want the extra security they'll use the extra click it takes to make the good option work. Most people will just reason that nobody will ever use a keylogger on them and keep using keys with passwords.


You are not forced to use SMS, you can always use the smartphones apps.


That's why it's used as a second factor, not the only one.


> It can be faked. Not in the way that matters in this case - it's prohibitively difficult to receive someone else's text messages.


In the video I see a private key coming from a Dropbox folder :(

Missing. The. Point.


I didn't watch the video, but if the key is encrypted (password protected) like it should be, what's the problem?


ssh key encryption isn't "lengthened" (it turns the password into the encryption key in the most obvious way possible). Unless your password is of the epic norse poem variety, it's crackable.


In the comments the author states that his private key is inside a TrueCrypt-folder, and that folder is on Dropbox.

I know that's reasonably secure but it feels terrible.


One more option is Barada PAM module+Android app. http://barada.sourceforge.net/ It is basically a HOTP implementation, where the token is protected by PIN (with PIN being a missing part of the shared secret stored on the token) and the original password is reserved only to be used on trusted machines (or) in case of losing token.


Does this mean that you ping them whenever you ssh? Does this mean that if their service is down you won't be able to ssh anymore?


From https://github.com/authy/authy-ssh/blob/master/authy-ssh#L11...:

    Default action when api.authy.com cannot be contacted:
    
      1. Disable two factor authentication until api.authy.com is back
      2. Don't allow logins until api.authy.com is back


What?! This is an online method? Why don't people just use Google Authenticator? It's totally offline, on both ends.


The video shows two options for this situation. Either allow access despite the outage, or deny access due to the outage.


If you are looking for a clean reliable two-factor auth system, I highly recommend Duo: http://www.duosecurity.com/

I've been using them across a half dozen personal machines for quite a while now, looking to roll it out at work as well.


Right, Duo is great. Love the fact you can install it over the whole enterprise including applications, blogs (Wordpress), vpns, and ssh.


Has anyone added this to other than a server? Seems like this could be added to a notebook or desktop running OS X. (And for that, I would actually prefer Google Authenticator.)

Also, it occurs to me: With TFA, it finally makes sense to periodically change passwords.


Seriously? Another (virtual) token-based 2FA solution? What is your competitive advantage against Duo, Authentify, Entrust, and the thousand other SMS or virtual token 2FA solutions out there?


We make it really easy for anyone to use 2FA. The reason 2FA is not popular is not because there aren't enough solutions out there, it's because all of them are basically really hard to use. Specially those that claim to be easy, they are the opposite.


A valid goal, but I think you're misunderstanding your market: in your words, people don't use 2FA because it's hard to use -- not hard to implement. Organizations who have IT teams are fully capable of implementing reasonable APIs like what Duo or Google offers. But you'll realize that enterprises don't even care about the architecture, because they'll be paying you to implement it anyway.

No, the reason nobody (in and only in the US) uses 2FA (because nearly every other country in the world uses it widely) is because it's a pain to use for the end user. No enterprise is going to invest their time and energy into a solution unless they're either required to by regulations or is truly better, easier, more secure, or whatever than competing solutions to make it a compelling sale.

If this were a hobby project then I'd be cheering you on -- why not make a token 2FA with a slightly better API? But as a YC-funded company whose likely avenue of success will be through the enterprise market, you NEED to develop a product that is better, faster, easier, more secure, etc than your (rather formidable) competition.

Trust me, I'm familiar with this market ;).


Been using this for around a month and it's great. Highly recommended.


Hm, can somebody explain what threat two-factor ssh-login is a response to?

If somebody went through the trouble of owning your machine, can't they bypass the two-factor as well? Yes, it requires a more "live" and target attack, but one would think ssh attacks like these are pretty targeted in the first place. Or? What am I missing?


Maybe I'm missing some assumptions of yours, but for me the reason to do that is to .. protect the ssh login.

Who talks about a machine that is owned? This is about an additional requirement to log on to a service, be it ssh or email. Whether you're reusing your password, sharing it or just use a really bad one this adds an additional step to impersonate you.


Yeah, but you can log-in with private keys instead of passwords, so that problem was solved a long time ago.


This is great but one thing bugs me. When you add a new user, you have to restart SSH? Wouldn't that prevent people from connecting every time a new user is added?


Even if you restart the ssh server it won't prevent people from connecting to the server because SSH forks the clients.


Ah, that clears it up. Thank you!


No, when you add a new user you don't need to restart. Only restart the server when you install the plugin.


The video in your blog post makes this murky to understand. First, the screen says "Restart the server to apply any changes". Second, you enable Authy for root, and then restart the server and say "Remember to restart ssh so the new configuration takes effect". Perhaps I'm not linux-oriented enough, but for me "configuration" doesn't just mean system config - adding a user could be part of that definition.

Otherwise though, I do think that this is an awesome idea. It only needs apps for smarphones instead of sending an SMS and you're on part with Google and Battle.net :)


Authy offers apps for smartphones. I think you can see the Authy app running on an iphone in the video.


What about two-factor authentication for sudo? I'd rather start my users off with sudo 2 factor auth, and grow them into two-factor auth for ssh and other stuff.


Fairly certain port forwarding still works while a command specified in ForceCommand is still running or if you specify a non-interactive shell.

Though I haven't checked ;)


I added support for yubikey to my installation. That thing's always on my keychain and can be used as second factor or otp generator (or both).


This is awesome. I wish the people at Authy the best. Now I'm gonna 2-factor auth the hell out of everything.


yes exactly what I've been looking for, awesome tool! Thanks for sharing.


I can't wait until three-factor authentication!!!


Great idea


Simple and great idea




Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: