Доброго времени суток.
Я хотел бы рассказать вам о проблемах 2FA аутентификации на устройствах Android 4.4.2 KitKat и о решении, которое в нашем случае прекратило долгие поиски.
Некоторое время назад мы с коллегами решили добавить Двухэтапную аутентификацию (Two factor authentication или для краткости 2FA) для нашего маленького офисного сервера на базе Ubuntu Server.
2FA это дополнительный уровень безопасности и приятное дополнение к уже существующему механизму аутентификации. Кроме обычной пары логин + пароль от пользователя, выполняющего авторизацию, требуется цифровой ключ, который динамически изменяется каждые 30 секунд и генерируется устройством, находящимся во владении пользователя. Для генерации ключа мы использовали Приложение Google authenticator и мобильный телефон на платформе Android. После разовой настройки приложение генерирует коды, имеющие срок жизни в 30 секунд, точно такие же коды генерирует сервер. При аутентификации коды сравниваются.
Так как данные не передаются от сервера и хранятся только на устройстве — этот механизм является более безопасным, чем отправка кодов подтверждения (например, как 3D-secure SMS подтверждение в банковских системах).
Пошаговых инструкций о настройках сервера в сети оказалось неожиданно много. В них все очень просто и доходчиво. Я руководствовался этой статьей.
После настроек сервера установили на телефон Lenovo p780 приложение Google Authenticator, «прочитали» телефоном с монитора QR-code и получили заветные циферки для авторизации. Перед тем как перезагрузить SSH не забывайте сохранить резервные ключи для восстановления доступа.
И вот, все готово к использованию! Перезагружаем SSH, заходим на сервер, указываем пароль, после пароля нас просят предъявить Verification code, переписываем его с телефона и… снова просят указать пароль?!!! Выглядит это так:
ssh user@server.ru
Password: <вводим пароль>
Verification code: <вводим код с телефона>
Password: <?!!, вводим пароль еще раз>
Verification code: <вводим код с телефона>
Password: <еще раз вводим пароль>
Verification code: <еще раз вводим код>
user@server.ru's password: <еще раз пароль>
Permission denied, please try again.
user@server.ru's password: <снова вводим пароль>
Received disconnect from xx.xxx.xx.xx: 2: Too many authentication failures for user
Вначале думали, что ошибка допущена в настройках, но испробовав несколько мобильных устройств стало очевидно, что коды генерируемые на Android 4.4.2 KitKat приложением Google Authenticator всегда ошибочны.
«Решения», которые удалось найти и их результаты:
- Если откатить версию Android, начинает работать корректно. (с этим «решением» работали какое то время, но решили двигаться дальше)
- Так как проблема сводится к некорректным часовым поясам — многие решения направлены именно на их исправление. Приложение TimeZone Fixer действительно может помочь с этой проблемой, однако часть приложений после его использования начинает отображать ошибочное время и потребуется чинить их вручную. (решение имеет свои минусы и риски. вся информация о приложении доступна на сайте 4pda)
- Подгонять время вручную. Если честно этот способ у нас так и не заработал. Перевести часы вручную и тем самым синхронизировать время на телефоне и сервере. Увы, все попытки ничего не дали, хотя были люди утверждающие, что у них заработало. В любом случае перспектива потерять функцию часов в телефоне не самая приятная...
- Синхронизация часов внутри настроек приложения Google authenticator (в нашем случае без результатов, однако были комментарии, что кому то помогло)
Финальное решение проблемы: FreeOTP
За время поиска решения в сети я уже натыкался на GitHub приложения Google Authenticator, в трекинге ошибок есть наша, и в качестве решения предложено:
«You can used FreeOTP Authenticator(by Red Hat) instead of Google Authenticator until someone fix it.»
Долгое время мне казалось, что рекомендуется использовать другой механизм-аутентификатор, который нужно ставить на сервер вместо Google, поэтому я усердно искал другие решения. Хотелось заставить работать именно Google authenticator, но на самом же деле рекомендуют использовать другое приложение для Android, а серверная часть остается без изменений.
Приложение FreeOTP Authenticator от компании Red Hat. После настройки по тому же QR-коду все начало работать без необходимости что то корректировать.
К сожалению я не могу указать вам причину возникновения ошибки в приложении Google authenticator, но надеюсь, что мой печальный опыт поможет сэкономить чье-то время.
Буду рад вашим комментариям! Спасибо за внимание.
Комментарии (42)
mikhaelkh
04.05.2015 05:49+2Ну почему сразу всегда ошибочны? В 1/1000000 случаев может и совпасть)
toxicdream
04.05.2015 06:35+2Автору надо было сказать «не рабочий».
По аналогии со сломанными часами — они два раза в сутки показывают точное время.
institor
04.05.2015 09:59+3Использовал это приложение начиная с Android 4.0.4, никогда не было никаких проблем. Странно. Может вы с часовыми поясами напутали?
sergey_dobrodey
04.05.2015 11:38+1Аналогично, 4.4.2 и даже смартфон тот же, lenovo p780. С проблемами в работе приложения не сталкивался.
Kichee Автор
04.05.2015 12:18-2Использовал это приложение начиная с Android 4.0.4, никогда не было никаких проблем. Странно. Может вы с часовыми поясами напутали?
Это маловероятно. Первоначально с ошибкой я сталкнулся, когда устройство работало на своей «заводской» прошивке. Никаких кустомизаций на тот момент не применялось.bormotov
04.05.2015 15:10timezone info в андроидеах отдельно не обновляется, в отличии от реальной жизни.
Я с такой ошибкой как вы не сталкивался, но версию про «что-то с часами», проверил бы детальнееVendict
04.05.2015 20:15+2Я пытался на сходном аппарате на MTK6589 на 4.4.2 экспериментировать. Как только часовые пояса не менял — не подходит код и всё, сегодня же FreeOTP Authenticator сразу сработало.
Kichee Автор
04.05.2015 21:03Я с такой ошибкой как вы не сталкивался, но версию про «что-то с часами», проверил бы детальнее
С изменением времени и часовых поясов предпринималось несколько попыток. В частности на 4pda рекомендуют для этих целей приложение ClockSynk (в той же ветке про timezone fixer). Выставив корректное время без смещения пробывали менять часовые пояса в большую и меньшую сторону. То же самое проделовали с временем на устройстве, но ни одна из комбинаций не дала рабочие коды.
Кстати интересное наблюдение — при «правильном» времени и часовом поясе первые 2 цифры кода всегда совпадают с корректным кодом (открытым в этот момент на FreeOTP).astlock
04.05.2015 22:36Аналогичные опыты делал на Lenovo S860. Ничего не помогло, ни руты, ни клоксинки, ни пояса. И да, первые цифры иногда совпадали с корретными кодами из афйона:) FreeOTP сегодня поставил — как в аптеке.
darkdimius
04.05.2015 10:24Вы пробовали Authy? Я использую его, тк он поддерживает больше типов 2FA.
grossws
04.05.2015 17:51+1И бонусом хранит ваши ключи для 2fa на своих серверах. Это, конечно, упрощает перенос на другое устройство, но является серьезным фактором риска, который стоит учитывать.
darkdimius
04.05.2015 17:53С любыми другими приложениями, у вас также нет никакой гарантии.
Если нужна безопасность повыше — можно использовать YubiKey NEO, он тоже умеет TOTP. И из него ключи не вытянуть никак.grossws
04.05.2015 18:20google-authenticator (для андроида живёт в отдельном репозитории) — это open source, что позволяет посмотреть на его потроха и убедиться, что всё нормально.
Кстати, в версии для андроида они сделали подстройку времени по серверам гугла (т. е. считают разницу времени между их серверами и устройством, и учитывают её при генерации кодов).
Yibikey neo мне более интересен тем, что на нём есть openpgp-апплет (у меня хранятся на нём три rsa2048 ключа: для подписи, расшифровки и ssh). Правда, проблемы с gpg-agent'ом периодически возникают: иногда после очередного отключения/подключения ключа он его не видит (хотя pcsc_scan видит прекрасно).gpg-> % gpg --card-status Application ID ...: D27600012401020000060350xxxx0000 Version ..........: 2.0 Manufacturer .....: Yubico Serial number ....: 0350xxxx Name of cardholder: Konstantin Gribov Language prefs ...: en Sex ..............: мужской URL of public key : http://... Login data .......: xxx Signature PIN ....: принудительный Key attributes ...: 2048R 2048R 2048R Max. PIN lengths .: 127 127 127 PIN retry counter : 3 3 3 Signature counter : xxx Signature key ....: D18B CC7F BA42 15F9 7EE9 FA26 E128 84E1 7319 D40C created ....: 2015-01-09 00:29:29 Encryption key....: 3541 7899 380F 6D25 FA44 56E9 518F C0EA F2C2 628E created ....: 2015-01-09 00:30:05 Authentication key: 131F 0381 D136 B020 5B75 B06F 639A B38B 307F F7C5 created ....: 2015-04-24 13:50:31 General key info..: pub rsa2048/E12884E17319D40C 2015-01-09 Konstantin Gribov <.......@gmail.com> sec# rsa4096/xxxxxxxxxxxxxxxx создан: 2015-01-09 годен до: никогда ssb rsa2048/E12884E17319D40C создан: 2015-01-09 годен до: никогда ssb rsa2048/518FC0EAF2C2628E создан: 2015-01-09 годен до: никогда ssb rsa2048/639AB38B307FF7C5 создан: 2015-04-24 годен до: никогда
darkdimius
04.05.2015 18:26google-authenticator (для андроида живёт в отдельном репозитории) — это open source, что позволяет посмотреть на его потроха и убедиться, что всё нормально.
У вас нет гарантии что он собран из того исходника без патчей.
Yibikey neo мне более интересен тем, что на нём есть openpgp-апплет
Надеюсь вы в курсе developers.yubico.com/ykneo-openpgp/SecurityAdvisory%202015-04-14.html По сути ключи там не защищены PIN-ом.
«Поддержка» totp была и на старых (простых yubikey)
Новые Neo тоже не знают про время и требуют приложение на хосте: github.com/Yubico/yubioath-desktopgrossws
04.05.2015 18:49У вас нет гарантии что он собран из того исходника без патчей.
У большого количества людей есть возможность вытащить соответствующих apk, распаковать и пройтись jad'ом (хз как он для dex называется, но не суть важно). Или собрать из исходников на гитхабе и сравнить получившийся apk (за исключением подписей).
Наличие такой возможности (сравнить) сродни фальсифицируемости в научном познании. В случае отсутствия исходников остаётся только реверс-инжиниринг, который требует существенно больших затрат.
Надеюсь вы в курсе developers.yubico.com/ykneo-openpgp/SecurityAdvisory%202015-04-14.html По сути ключи там не защищены PIN-ом.
В курсе. Печаль для всех, кто наследует эту проблему от javacardopenpgp. Для эксплуатации, правда, требует физического доступа к машине (который точно также позволяет перехватить ввод pin или passphrase для обычного), так что для меня не добавляет и не убавляет ничего в рисках при использовании. В любом случае, токен несколько увеличивает безопасность, т. к. ключ присутствует не всё время, а только при аутентификации/подписи/расшифровке против обычных ключей, доступных всё время.
isden
04.05.2015 22:47> google-authenticator (для андроида живёт в отдельном репозитории) — это open source, что позволяет посмотреть на его потроха и убедиться, что всё нормально.
Не совсем:
This open source project allows you to download the code that powered version 2.21 of the application. Subsequent versions contain Google-specific workflows that are not part of the project
ibKpoxa
04.05.2015 11:28+1Хочу OPT приложение, чтобы при запуске спрашивало дополнительный PIN/пароль, вы не знаете такого?
EminH
04.05.2015 11:42Знаем :)
Token2 Mobile OTP
(пна некоторых андроид-устройствах глюки с расширением, под iphone можете комфортно пользоваться)
astlock
04.05.2015 11:36Ох, черт побери, Спасибо! Я уже и iphone надумал покупать, т.к. по иронии судьбы там все работает.
Andrii_Z
04.05.2015 12:54-1Только вот для Faceboox, Gmail, Dropbox, Live.com (Microsoft), Lastpass Google Authenticator генерирует правильные коды на Kitkat 4.4.2 на Samsung s3
Может, проблема в Lenovo?
stavinsky
04.05.2015 14:09+5Полагаю проблема связана именно с часовыми поясами. У меня например стоит часовой пояс минск и все прекрасно работает.
То есть, если я правильно понимаю, время должно совпадать с часовым поясом. Например если вы ставите Москву и потом корректируете руками время — будет фигня. А если вы правильно подбираете часовой пояс — все будет хорошо
Denai
04.05.2015 14:59т.е. проблема вызвана другой проблемой (часовые пояса), которая решается вайпом или рутованием? А 4.4.2 чем выделается?
mifki
> Долгое время мне казалось, что рекомендуется использовать другой механизм-аутентификатор, который нужно ставить на сервер вместо Google, поэтому я усердно искал другие решения. Хотелось заставить работать именно Google authenticator
Странная мысль — сам протокол никакого отношения к Гуглу не имеет, какое приложение генерирует коды, всё равно. И таких приложений довольно много, причем, по крайней мере на iOS, родное Гугловское из плохих. После того, как при восстановлении из бекапа оно потеряло все коды, никому его не рекомендую.
ssh4
Ну и глупо. Вероятность бага одинакова как в коде от Гугла так и в коде от Васи Пупкина.
Вася Пупкин может оттестировать обновление на 10 девайсах, Гугл на 1000е другой. Да и фикс выкатить быстрее. А один раз наступив на такие грабли, думаю надолго запомнят, что надо обновления такой важной утилиты тестировать тщательнее.
Ну и не говоря о том, что рентабельность «воровать» данные для Гугла близка к нулю, а вот Вася Пупкин, фиг знает, что там решил улучшить для повышения профита.
mifki
Ерунда какая-то, по-вашему приложения от Гугла или другой крупной компании всегда лучше и стабильнее?
ssh4
Я говорю о том, что такому приложению от крупной компании уровня Гугл больше доверия по той причине, что встраивать бэкдоры в подобное приложение им нерентабельно.
Допустить ошибку в коде одинаково могут как неизвестный разработчик так и крупная компания.
И есть шанс, что раз допустив такую ошибку, в дальнейшем они приложат больше усилий для проверки всех возможных вариантов до выпуска релиза. Благо у Гугл на это ресурсов больше.
mifki
Оставив в стороне вопрос бэкдоров (я не из парноиков), есть еще такое дело, как побочные и заброшенные проекты/приложения, и у крупных контор с этим дело даже хуже. Google Authenticator для iOS не обновлялся больше года с октября 2013 до декабря 2014, и до этого больше двух лет с июля 2011 до октября 2013. Причем и это обновления в основном для поддержки новых версий системы и устройств, но ни о каких багфиксах речи не идет. И проверять, не пропадут ли у меня коды опять и с новой версий, у меня никакого желания нет.
ssh4
Почему заброшенное?
Если приложение работает, в нем нет критических багов, и свою функцию оно выполняет на 100%, нужно ли гнаться за ежемесячными апдейтами?
Или вам надо чтобы Google Auth в конечном итоге превратился в тяжеловесного монстра с кучей никому ненужных функций?
А вероятность словить баг при новом обновлении есть у любого приложения.
По уму конечно, стоит иметь резервный вариант на случай сбоя. Но уж лучше на десктопе, а не два идентичных по функциям приложениях на смартфоне. Тем более что можно тупо утопить смартфон в туалете. Даже не дожидаясь граблей от кодеров ;)
mifki
Угу, видимо, они посчитали, что даже защита пин-кодом тоже никому не нужная функция.
ssh4
Я согласен с тем, что оно не идеальное.
С появлением Touch ID проблема непинкодности приложения конечно сильно уменьшилась.
Так как трубка по дефолту залочена и доступ к ней могут иметь только доверенный круг лиц.
Я бы честно после того бага, какой то «внешний» бекап добавил, чтоб точно быть спокойным,
что если что, бекап настроек имеется.
Но тут уже да, включается неповоротливость корпорации. Да и платформа неприоритетная ;)
Kichee Автор
Когда знаете об этом — это действительно логично, а вот когда сталкиваешься с этим в первый раз, а при этом и на сервере и на мобильном устройстве приложение называется одинаково, чувствуется нерушимая связь и четкая зависимость одного от другого.
Спасибо за ваш комментарий. Проблемы, возникающие при восстановлении из бекапа явились для меня новостью. На всякий случай попробую испытать восстановление заранее пока не сталкнулся с проблемой в боевой ситуации.
khim
Не уточняется какие именно проблемы возникают при восстановлении из бекапа. Как известно одноразовые пароли можно генерировать на основе времени (каждые XX секунд — новый OTP), а можно — на основе счётчика (каждое обращение просто «рождает» новый OTP, но они все должны быть использованы, пропуск более 2-3 штук приводит к рассинхронизации клиента и сервера и необходимости сброса всей системы).
Понятно, что во втором случае никакое «восстановление из бекапа» невозмножно — и это не баг, а фича. В самом Гугле Google Authenticator используется, разумеется, только в таком режиме (так как он безопаснее), так что, возможно, о проблемах с восстановлением для «временной» генерации просто никто не подумал.