Мне надоело постоянно использовать Google Authenticator и переключаться между ПК и телефоном для подтверждения двухфакторной (мультифакторной) аутентификации. Красивых и функциональных TOTP (Time-based one-time password) хранилок в терминале я не нашел, поэтому сделал эту TUI, которая позволит хранить, управлять, просматривать, копировать 2FA ключ в пару нажатий с поддержкой VIM управления. Ну и просто мне было интересно, каково это создавать свои TUI приложения.
Начем с того, что такое TUI?
TUI - Terminal User Interface. Это когда мы пытаемся сделать что-то похоже на GUI интерфейс, но в терминале. В последнее время это становится все более привлекательным и удобным, появляется много реализаций опенсорсных инстументов, например такие как gopass, lazygit, lazydocker
Вы можете сказать, что я изобретаю велосипед, это действительно так, но для себя отмечу несколько пунктов:
Первое, и самое главное, я пишу в vim и использую tmux, а это значит, что 90% времени провожу на клавиатуре и в терминале, поэтому логичнее сделать инструмент там, где будешь пользоваться.
Второе, я не нашел красивых и функциональных туишек для работы с TOTP ключами. Все решения представляли из себя просто набор команд, которые требуется вводить и потом еще руками копировать этот ключ. А мне хотелось решение, которое будет постоянно обвовлять ключи и не будет проблем с копированием.
Ну и третье, мне было очень интересно создать свою TUI, понять, как это работает и какие открывает возможности для творчества. А потом уже поделиться с другими.
Одной из главной цели я ставлю создание быстрого приложения, для максимально короткой трудозатраты при копировании двухфакторного ключа.
На чем можно сделать TUI
На самом деле, много на чем, хоть на shell или php, но я бы не сказал, что для меня это было бы удобно. Решил взять за основу язык Go, так как частенько его использую для скриптинга и давно хотел попробовать сделать tui на Bubbletea - фреймворк для реализации TUI приложение.
Что нужно реализовать
Нужно было реализовать следующее:
Главный экран, где можно будет выбрать что мы делаем, смотрим ключи или добавляем новые
В просмотре ключей должна быть таблица с фильтрацией, сразу должен быть показ ключей и анимация протухания. Когда ключи свежие, то индикация белая, когда переходят 15 секунд, то желтая и если осталось 5 секунд до протухания, то красная. Должен быть выбор через стрелочки и hjkl (кнопки управления в vim), а также, скрывать ключи, которые не выбраны.
На странице просмотра мы должны иметь возможность сразу поместить ключ в буфер обмена (скопировать) и удалить
Для удаления отдельный экран с подтверждением
Отдельный экран для создания ключей, где можно задать название, описание и сам SecretKey на основе которого генерируются TOTP ключи, естественно с валидацией, если ключ не подходит по формату или что-то не заполнили
Сохранение в локальное хранилище и шифрование этого хранилища
Бекапы при создании новых ключей, чтобы можно было откатиться обратно, если вдруг удалили то, что не должны были удалять
Вся реализация заняла примерно пару дней по несколько часов. Дальше расскажу чуть подробнее те моменты, про которые есть что рассказать.
TOTP
TOTP - Time-based one-time password - одноразовые пароли для двухфакторное или любой другой аутентификации. Тут нужно понимать только базу, что у вас есть какой-то Secret Key и временная метка, для генерации этих паролей и валидации данных использовалась либа - https://github.com/xlzd/gotp, там можете подробнее прочитать про сам TOTP.
В коде для этого всего пару строк:
func GenerateTOTP(utf8string string) (string, int64) {
return gotp.NewDefaultTOTP(utf8string).NowWithExpiration()
}
в utf8string помещается ваш секретный ключ и все прекрасно работает.
Хранилище
Хранилище представляет из себя json файл, которые располагается в директории $HOME/.local/share/go2fa/stores/vault.json
Где iterator - это текущая степень итерации, а db - основное зашифрованное хранилище.
{
"iterator": 29,
"db": "bJvzEpGPZFG2hS0LI3pYOoDHP/5kLO23E9IKEpsUrt6mSL/HudDftPwlUcnCeKBQCaJ0zmpPQpmcw+3IFlPv6+VMJmK7cSgyoHh7JBFwHW2oqBUfemU1wk+/mfBu4HEtD+HoV/XR6XRl+P/tzMBenUkVMzmw1WPCE4U2NOtTkEojxIb6lsi+72GpDGTY3W8namNwWq9i8IoSkIBKVcVhew3sPkW8nTHwz3fEDDnBWDxhEQsViUdrLvxmgX34sBTDlu6v1DZ4R9+Hwd2eGoTZ/mBOGGqI3NGxW/yShIPpy0VrW2uSUasLdc51bAsKxc5fK7EQm1KFchpk1H4N36Dh06Kqmzf/irLJQCPPVr1v5QtpHtCzJm4mEb5ZVZmr+gEz9oIJw6pOztk4UDVw3YDa/7SBSfoxqBW/Mm1DuXJxH/prbCLrKqxr+CcqIasI8H6KcQm2AIRBuKwkR8MaBRpV85rN+XOtWapd/W8LzFbHqy1mDTm7DznC4ZoXIjBDdYNbwwi/zcR7ID4le1TMOszXZtA4l0XThxuk5MqdwBB8sCy4Xe1BxZ6Kf0q0MNlx89gnlRjEE5Ym+Ven5Rqiea+YoNM7Uq0t9o2SoddgvPz+0NvzaPnU4342ukRm0r5wmHvmqoBxdeYC1VkQXI72dPjMWrBloybnLsSDwaoLxhyCA="
}
Такой формат был выбран, чтобы использовать дополнительную мета-информацию. Сейчас это iterator, но в будущем можно расширять как-угодно.
Самое db - это base64 байтовое значение, которое зашифровано с помощью RSA.
Слишком заморачиваться с шифрование я не хотел, да и работа должна оставаться быстрой. С учетом того, что это можно закинуть в репозиторий, главное не закидывать туда приватный ключ. Считаю, что вполне нормальная реализация. Хотя понятие "нормально" будет отличаться от каждого человека, вы можете сами сделать так, как нравится. Да и не особо я знаток шифрования, если есть полезная информация, поделитесь, изучу.
Помимо самого хранилища, при создании новых ключей или при удалении, в $HOME/.local/share/go2fa/backups
сохраняются бекапы и вы можете восстановить любую предыдущую итерацию, конечно же, если есть приватный ключ.
А сами ключи хранятся в $HOME/.local/share/go2fa/keys
, если будете что-то дропать с системы, не забудьте про этот момент.
Немного про Bubbletea
В целом, делать tuiшки на основе данного фреймворка прикольно, сначала не очень понятно, особенно когда дело доходит до смены экранов и состояний, но после просмотра examples все более менее становится на свои места.
У них действительно много примеров, если есть вопросы, то можно залезть в issue и попробовать найти их там. А так, все дело в попытках. Но, как рекомендацию, я бы посоветовал сначала ознакомиться с архитектурой Elm, так как фреймворк основан на ней и потом все проще понимать.
Очень полезно, что есть готовые модули (экраны) в виде списков, таблиц, то есть вам не особо надо задумываться над тем как реализовать фильтрацию и пролистывание с пагинацией, немножно допилите модуль под себя и все.
На что хотел бы обратить внимание - это смена экранов, так как может вызывать трудности.
У меня в проекте есть папка go2fa/internal/screens
, здесь находятся все реализованные экраны. Переключение между ними происходи следующим образом:
В main.go начинаем с:
func main() {
screen_y := screens.ListMethodsScreen()
...
if _, err := tea.NewProgram(screen_y).Run(); err != nil {
fmt.Println("Error running program:", err)
os.Exit(1)
}
Где ListMethodsScreen - это метод, который возвращает модель экрана.
func ListMethodsScreen() ListMethodsModel {
items := []list.Item{
item{ title: "Show keys", alias: "show_keys" },
item{ title: "Add key", alias: "add_key" },
}
const defaultWidth = 20
l := list.New(items, itemDelegate{}, defaultWidth, listHeight)
l.Title = "GO2FA"
l.Styles.Title = titleStyle
l.Styles.PaginationStyle = paginationStyle
l.SetShowStatusBar(false)
l.SetFilteringEnabled(false)
output := termenv.NewOutput(os.Stdout)
return ListMethodsModel{list: l, output: output}
}
type ListMethodsModel struct {
list list.Model
quitting bool
output *termenv.Output
}
Здесь как раз задается структура модели list, в моем случае это просмотр ключей и добавление новых, прописывается размеры, стили и заголовок, выключается статус бар и фильтрация.
Кстати, задавать стили одно удовольствие
var (
paginationStyle = list.DefaultStyles().PaginationStyle.PaddingLeft(4)
)
l.Styles.PaginationStyle = paginationStyle
После этого мы возвращаем саму модель
return ListMethodsModel{list: l, output: output}
Теперь, когда вы запустили программу, мы попадаем сразу в первый экран. В самом файле описываем метод Update, где отслеживаем нажатие клавиш или изменение размера терминала.
func (m ListMethodsModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.WindowSizeMsg:
m.list.SetWidth(msg.Width)
return m, nil
case tea.KeyMsg:
switch msg.String() {
case "q", "esc":
m.quitting = true
m.output.ClearScreen()
return m, tea.Quit
}
switch msg.Type {
case tea.KeyCtrlC:
m.quitting = true
m.output.ClearScreen()
return m, tea.Quit
case tea.KeyEnter:
item, ok := m.list.SelectedItem().(item)
if ok {
if item.alias == "add_key" {
screen_y := ScreenInputSecret()
return RootScreen().SwitchScreen(&screen_y)
}
if item.alias == "show_keys" {
screen_y := ListKeysScreen()
return RootScreen().SwitchScreen(&screen_y)
}
}
}
}
var cmd tea.Cmd
m.list, cmd = m.list.Update(msg)
return m, cmd
}
Если было событие Enter и был выбран один из элементов модели, то мы выбираем следующий экран
if item.alias == "add_key" {
screen_y := ScreenInputSecret()
return RootScreen().SwitchScreen(&screen_y)
}
И таким образом, через SwithScreen происходит вся магия переключения экранов.
// this is the switcher which will switch between screens
func (m rootScreenModel) SwitchScreen(model tea.Model) (tea.Model, tea.Cmd) {
m.model = model
return m.model, m.model.Init() // must return .Init() to initialize the screen (and here the magic happens)
}
Чтобы сильно не растягивать статью, я привожу только базовый пример реализации, подробнее можно посмотреть в репозитории.
Публикация TUI в brew
Это был мой первый опыт публикации go приложения в brew репозитории. Homebrew я выбрал, потому что оказалось туда запушить очень просто, для этого нужно репозиторий homebrew-public и использовать goreleaser.
После в директории с вашим приложением, запускаете:
goreleaser init
у вас создастся файл .goreleaser.yaml
там будут все необходимые настройки, главное удостоверьтесь, что репозиторий подходящий.
Дальше выполняем и у вас происходит релиз. Автоматика, удобно.
goreleaser check
goreleaser release
Прикладываю статью, которой пользовался: https://dev.to/aurelievache/learning-go-by-examples-part-9-use-homebrew-goreleaser-for-distributing-a-golang-app-44ae
Итог
После создания прошло уже пол года и я ей пользуюсь ежедневно на работе, так как для безопасности требуется каждый день входить в разные сервисы и вводить ключи. И по сути, это просто превращается в несколько нажатий:
Ctrl + t - открыть новое окно терминала
go2fa - открыть tui для ключей
enter - выбираем просмотр ключей
jk - выбираю ключ
enter - копирую ключ и дальше просто вставляю в нужном сервисе
На автомате это происходит действительно за пару секунд. Раньше это занимало гораздо больше времени, особенно когда ты хранишь это в телефоне.
Есть небольшой недостаток того, что с Google Authentificator нельзя экспортировать ключи в каком-либо формате, чтобы потом их адекватно перенести в go2fa, поэтому приходится заново подключать 2FA в сервисах. Это занимает определенное время в самом начале, зато потом не требуется никаких действий. Ну и лучше все-таки задублировать в какую-то хранилку на телефоне или на ПК, где вы еще пользуетесь, так как бывает требуется входить в сервис и с телефона, да и безопаснее.
Если вы хотите попробовать, то достаточно поставить через brew:
brew install curkan/public/go2fa
# и запустить
go2fa
Только убедитесь, что стоит Xclip или Xsel. Иначе не будет работать копирование.
Для себя понял, что в текущих реалиях не сложно создавать tui приложения, которые вам помогают в будущем удобнее чем-то пользоваться, много разных решений и на разных языках. Я был вдохновлен gopass, lazygit, lazydocker - все это TUIшки, которые делают наши программисткую жизнь удобнее, если ты пользователь терминала.
Спасибо за прочтение, буду рад ответить на замечания и предложения. Ну и если хотите поддержать, то просто подпишитесь на телегу, я там часто рассказываю про свои проекты: https://t.me/tsurkan_hut
С Уважением, Никита Цуркан
Комментарии (61)
grigoryvp
04.01.2025 07:30keepassxc умеет в TOTP
ritorichesky_echpochmak
04.01.2025 07:30И к нему есть браузерный плагин, keepassxc-cli для консольщиков, автоэкспорт ключей SSH в SSH-агента... непонятно, чего людям не хватает.
Хотя, строго говоря, с точки зрения безопасности 2FA лучше хранить не с паролями, а на отдельном устройстве (чем и является телефон с его Google Authenticator, который при желании можно заменить на Aegis)
grigoryvp
04.01.2025 07:30Полагаю, мало кто знает, что менеджеры паролей поддерживают TOTP. В том же keepassxc эту функцию нужно включать. Если не знать о ее существовании, то шансы случайно наткнуться ноль шансов.
По безопасности есть консёрны. Потерять телефон с TOTP несоизмеримо проще, чем лежащую в каком-нибудь дропбоксе базу keepassxc. Поэтому TOTP с телефона приходится бэкапить, и тогда это передстает отличаться от бекапа keepassxc.
Второй фактор хорошо защищает от ситуации передачи пароля по ненадежному каналу в ненадежное место (MITM с корневыми сертификатами, слив сайтом паролей в плейн тексте и все вот это). Насколько я понимаю, основная защита второго фактора - она для обычных пользователей с одним слабым паролем на все сайты. Если мы используем менеджер паролей - то у нас уже очень высокий уровень безопасности. Заморачиваться с разными бэкапами паролей и TOTP это, ИМХО, уже оверкилл.
dartraiden
04.01.2025 07:30Бэкапить нужно всё, так что это не аргумент.
Если вы не делаете бэкапы чего-то ценного под предлогом "да это сложно потерять" - по закону Мерфи именно это вы потеряете.
А раз так, то хранить лучше на телефоне, чтобы факторы были физически разнесены. Храня всё на ПК вы сознательно ослабляете второй фактор.
ritorichesky_echpochmak
04.01.2025 07:30Потерять телефон с TOTP несоизмеримо проще
Поэтому у Aegis есть возможность сбэкапить и перенести всякое, да и Google Authentificator впроде вполне переносибельный между "своими" должен быть (но зачем, если есть Aegis). Вот хардверными ключами я так и не проникса.
И не помню чтобы прям включал ручками TOTP или сильно страдал, вопрос лишь в "поинтересоваться как сделать", вот SSH-ключи залить или сканер пальцев да, троху надо поковыряться... особенно если SSH-агента ещё прокидывать куда-нибудь внутрь WSL на фортках.
"высокий уровень" - понятие относительное. Любой залётный троян может утащить что нажимали на клаве и все найденные *.kbd(x). Троян чуть посложнее даже сможет пройтись по настройкам менеджера паролей и прихватить файл-пароль использованный вторым фактором к .kbd(x). Поэтому для ключевых учёток лучше перебздеть. Тем более что 2FA редко повторно спрашивается для сайтов с которыми работаешь регулярно.
нуу... если вам принципиально TUI, то и сделали бы его над keepassxc-cli. KeePassXC что-то да знают про безопасность, аудиты там какие-то проходили, а главное - всё уже сделано в лучшем виде.
С другой стороны я так и не понял откуда у вас в консоли постоянная необходимость дёргать муторный 2FA. Для браузеров обычно 2FA спрашивается крайне редко, при первой авторизации "с этого хоста на сайте". Для cli обычно генерятся токены. А 2FA прям в консоли я что-то и не припомню чтобы мне хоть раз был необходим. Это точно не история про tmux и vim)
tsurkan_n Автор
04.01.2025 07:30ну почему история не про tmux и vim, если эти инструменты я использую постоянно, то почему бы не сделать в их системе и управлении. У меня много всяких TUI для работы с разными направленями, от теста, до работы с БД, докером
Мне приходится день начинать всегда с TOTP, и это примерно около 6-7 сайтов, плюс бывает приходится из разных браузеров. Нетривиальные задачки, когда под эмуляторами сидишь или в виртуализации и прям оттуда приходится вводить.
Вообще данная туишка появилась, когда мне в одном сервисе требовалось прикрутить 2Fa, что для дебага требуется постоянно добавлять новые секреты и удалять их. Понятно, что не каждый день прикручивается 2Fa, но спустя пол года пользования вижу только плюсы от использования в терминале - так как это основная моя среда пребывания :D
HSerg
04.01.2025 07:30С другой стороны я так и не понял откуда у вас в консоли постоянная необходимость дёргать муторный 2FA.
Пример из жизни - у одного из клиентов был OpenVPN с TOTP и ограничением времени сессии.
lolikandr
04.01.2025 07:30Если мы используем менеджер паролей - то у нас уже очень высокий уровень безопасности.
Менеджер паролей надо уметь
готовитьиспользовать, вот я помню как-то поставил галочку "не спрашивать пароль при открытии окна" и через пару месяцев забыл мастер пароль... Как я задолбался потом восстанавливать пароли на каждом используемом сервисе!
tsurkan_n Автор
04.01.2025 07:30в gopass вроде как тоже) проблематика не в этом стояла. Я хотел простую и легкую TUI под управлением vim, о чем писал в статье. keepassxc-cli - управлять именно командами, то есть их необходимо писать ручками, либо забивать алиасы, для быстрого доступа. keepassxc - gui, которое в моем случае только будет больше времени занимать.
Как и все возможные браузерные расширения - это все есть, кому-то удобно, но реализации TUI я нормальной не нашел
aborouhin
04.01.2025 07:30Bitwarden / Vaultwarden тоже умеет, и это будет свой сервер, что задачу синхронизации/бекапа решает оптимально.
Но для консоли там именно CLI, а не TUI, т.е. надо или помнить название конкретной записи, или сначала выполнять команду list и просматривать список, а потом get - и получать код.
Хотя вообще я с трудом представляю себе потребность в TOTP в консоли, по-моему, в 95% случаев оно надо в браузере - так браузерным плагином коды заполнять и удобнее всего.
tsurkan_n Автор
04.01.2025 07:30Command + tab - go2fa уже открыт, дальше просто накликиваю клавиатурой hjkl и на Enter копирую и обратно Command + tab + Enter.
Тут все происходит без мышки и тачпада, что в моем случае очень удобно, так как не переключается контекст клавиатуры и мыши (тачпада)
У браузерных плагинов есть проблема - они ставятся в браузер, для работы я использую Safari, Chrome, Firefox и Firefox Dev - поэтому тут либо ставить и синхронить на все, а скорее всего под каждый браузер еще разное расширение будет, либо использовать мобилку, либо использовать GUI, что в данном случае звучит более логично.
Ну и опять же, мы делаем и подбираем софт под себя, чтобы было удобно, в моем случае использовании TUI обосновано привязкой к терминалу и вводу VIM, я не задумываюсь, когда использую такое управление и происходит это максимально быстроaborouhin
04.01.2025 07:30У Bitwarden есть расширения под все перечисленные браузеры плюс мобильное приложение, надо всего лишь один раз их установить и залогиниться на свой сервер (ну или на сервер Bitwarden, если нам нечего скрывать :). После чего при автозаполнении логина и пароля (что в десктопных браузерах делается по хоткею) TOTP код для соответствующей записи автоматически копируется в буфер обмена. Или сразу автозаполняется, если поле для его ввода на той же форме, что и логин с паролем (но такое редко встречаю). Понимаю, что каждому привычнее своё, но тут по скорости вне конкуренции :)
bilayan
04.01.2025 07:30Если не свой сервер, то тотр в bitwarden доступен только в премиуме
aborouhin
04.01.2025 07:30Ну Vaultwarden есть, хвала его создателям. А сторонний облачный сервис для столь чувствительной задачи в любом случае как-то некомфортно (умом понимаю, что для меня с нероссийским сервисом риски минимальны, но паранойя не дремлет)
Stanislavvv
04.01.2025 07:30с трудом представляю себе потребность в TOTP в консоли
teleport, который централизованная замена индивидуальных ssh, вполне себе консольный и умеет в 2FA. Для случая, когда надо дать доступ многим людям на сервера без ввода пароля и не раскладывая их ключи на сотни серверов — вполне.
adrozhzhov
04.01.2025 07:30В keepassXC создаём новую запись, сохраняем, кликаем правой кнопкой мыши
Выбираем TOTP/Set up TOTP... (оно не даёт себя скриншотить, так что только основная менюшка, без настройки)
Вводим секретный ключ. Ключ можно извлечь из аутификатора так https://habr.com/ru/articles/802953/comments/#comment_26655983
tsurkan_n Автор
04.01.2025 07:30За инструкцию извлечения секретов спасибо, учту)
По поводу keepassXC писал выше, что мне не нужны GUI, я 90% времени нахожусь в терминале и требуется TUI, keepassXC-cli - это решение чисто под команды, что тоже не особо ускоряет процесс получения TOTP ключейegribanov
04.01.2025 07:30Экспорт ключей в гугл аутентификаторе есть, только он переносит их qr кодами, для чтения можно использовать вот это. Работает через вебку
scito/extract_otp_secrets
Не знаю почему ссылку не разрешает вставить редактор текста
Gorthauer87
04.01.2025 07:30Вот мне кажется, что основная линия защиты в двухфакторной авторизации это как раз наличие двух различных устройств. Просто если злоумышленник таки получил доступ к устройству, то если на нём есть и второй фактор, то он не будет работать. Ну разве что задержит злоумышленника минут на 15.
aborouhin
04.01.2025 07:30Мне кажется, что путать "разные факторы" и "разные устройства" - очень популярное заблуждение. Разные факторы - это знание или владение. Пароль можно знать и узнав (подсмотрев, скачав из утечки и т.п.) использовать повторно. Код TOTP знать бесполезно, он каждый раз разный, надо владеть (иметь доступ) генератором этих кодов. А вот секрет TOTP - тот же фактор, что и пароль, но он более защищён от перехвата, т.к. в явном виде не отображается и не используется. А разные устройства - это дополнительный способ обезопасить себя, но совершенно параллельный наличию разных факторов.
sobeskiller
04.01.2025 07:30А вот секрет TOTP - тот же фактор, что и пароль, но он более защищён от перехвата, т.к. в явном виде не отображается и не используется.
Так и пароли уже давным давно передаются по защищённым каналам, либо в защищённом виде. О массовых атаках MITM пока не особо слышно.
Главный канал их утечки - локальное и серверное хранилище. И вот не совсем понятно чем тут поможет TOTP, если секрет точно так же могут слямзить как и пароль/хеш. Пароль даже надёжнее если он рандомный и длинный - такой брутом по хешу фиг восстановишь. А вот секрет он ж прям в открытом виде должен лежать. Либо ключи его дешифрации точно где-то рядом.
aborouhin
04.01.2025 07:30Вообще менеджеры паролей изрядно спутали всю концепцию многофакторной аутентификации. И пароль стал не вполне фактором знания (никто его не вводит и не помнит, для его заполнения нужен доступ к менеджеру паролей), и TOTP - не вполне фактором владения (т.к. секрет можно перехватить, хоть и не так просто).
Без менеджера паролей главный канал утечки, мне кажется, - по-прежнему вне конкуренции стикер на мониторе :) Ну может утечки ещё для пользователей, у которых все пароли одинаковые, и во взломанном интернет-магазине игрушек он тот же, что и на корпоративную почту. И именно этот вектор атаки замечательно прикрывает TOTP.
А с менеджером паролей нет готовых рецептов, что вот тут такой фактор, тут такой, - надо индивидуально оценивать векторы атаки и риски.
sobeskiller
04.01.2025 07:30Ну может утечки ещё для пользователей, у которых все пароли одинаковые, и во взломанном интернет-магазине игрушек он тот же, что и на корпоративную почту. И именно этот вектор атаки замечательно прикрывает TOTP.
Чем именно он прикрывает? Только тем что секрет обязан быть рандомным. Но с таким же успехом можно обойтись и без одноразовых TOTP, просто обязывать пароли быть рандомными.
Насколько я слышал историю, концепция HOTP иначально для того и создавалась чтобы вынудить юзера использовать спецжелезо/софт, чтобы юзер не мог сам придумывать и использовать всякие 1234 и приклеивать их на стикерах и хранить в текстовых файтах. Т.е. временный пароль не предназначался для предотвращения кражи или перехвата, он только для принуждения пользоваться спецсредством. А уж TOTP и использование как второй фактор - это "постольку поскольку".
xSVPx
04.01.2025 07:30Причем это должно быть устройство ключ из которого не скопировать даже получив доступ.
Конечно оно должно быть аппаратно отдельным.
К сожалению, удачных сходу найти не удалось. В целом народ не озабочен безопасностью совершенно. Энтузиасты делают всякие мультипассы, но они сыроваты.
jackgrebe
04.01.2025 07:30раз: https://www.passwordstore.org/
два: https://github.com/tadfisher/pass-otp#readme
три: велосипед ?tsurkan_n Автор
04.01.2025 07:30не увидел тут TUI :)
jackgrebe
04.01.2025 07:30а он там есть ! попугайские раскраски не обязательны.
и немного хулиганства: https://www.youtube.com/watch?v=xzb9anBoEtU
eigrad
04.01.2025 07:30Круто, если бы не сидел на 1password family account (который идёт бесплатно к рабочему), то заюзал бы. Хотя наверное всё-таки нет, потому что до 1password был pass, скорее все таки туда бы добавил otp плагин.
lolyamyaumyauka
04.01.2025 07:30Так-то круто, не желаете сделать ссылку на файл с инструкцией по использованию внутри?
tsurkan_n Автор
04.01.2025 07:30постараюсь описать в ближайшее время, там по сути все просто для тех, кто знаком с vim
j - вниз
k - вверх
enter - выбрать
esc - отменить или назад
? - помощь (help)
g - наверх
G - вниз
q - выйти
d - если в просмотре ключей, то удалить ключ
/ - если в просмотре ключей, то фильтрация, дальше вводите название
n0dwis
04.01.2025 07:30Да и не особо я знаток шифрования, если есть полезная информация, поделитесь, изучу.
Читаю книгу по криптографии, так что немного подушню.
Здесь нет смысла использовать RSA. Во-первых, всё хранится локально, так что симметричного шифрования вполне достаточно. Во-вторых, асимметричное - это долго и ограниченно. Думаю, AES будет достаточно.
tsurkan_n Автор
04.01.2025 07:30Возьму на заметку. Какую книгу читаешь?
strvv
04.01.2025 07:30Немного позанудствую.
В принципе любую, как с дистрибутивами линукса - лучшая книга та, к которой прилагается знакомый, разобравшийся в теме, или же самый дорогой фактор - время и тетрадка с ручкой.
Здесь или может быть в другом месте попадалась шпаргалка по криптографии.
Там коротко, без математики объяснялось различные методы - симметричное, ассиметричное, подпись, имитозащита...
Чуть глубже базовые методы. (S-block, ...)
Осознание что, как и насколько сложно/долго и т.д. - уже помогает при выборе в конечном счёте.
А за решение - большой плюс, натолкнул меня на решение другой моей задачи!
siberianlaika
04.01.2025 07:30Bubbletea выглядит привлекательно, но при ближайшем рассмотрении не так уж очевиден. Кому как, а мне их примеры слабо помогли -- обходил либу стороной, пока не попался детальный разбор с советами, как строить приложение на Bubbletea: https://leg100.github.io/en/posts/building-bubbletea-programs/ -- тут все в одной статье и мне оно показалось более понятным, чем доки в проекте. Во всяком случае по этой статье получилось сделать что-то себе полезное и рабочее на этой либе.
Здесь в статье на хабре тоже часть нюансов работы с либой освещена, за что автору отдельное спасибо!
tsurkan_n Автор
04.01.2025 07:30благодарю) с ссылкой тоже ознакомлюсь, согласен, что не все очевидно у них и вызывало определенные сложности
pavelmakis
04.01.2025 07:30Использую Bitwarden. Нужно купить подписку, что-то вроде 10$ в год и тогда появится возможность добавлять TOTP коды к записям паролей.
У них также есть CLI, можно в консоли что-то получать (все) ну и автоподстановка на сайтах по горячим клавишам. После подстановки пароля TOTP код копируется в буфер чтобы сразу его вставить на следующем этапе.
А вообще TUI – топ!
tsurkan_n Автор
04.01.2025 07:30Спасибо, с Bitwarden не знаком, сам пользуюсь gopass для хранения паролей, там тоже вроде как можно в totp, но нетривиальная задача)
aamonster
04.01.2025 07:30Есть небольшой недостаток того, что с Google Authentificator нельзя экспортировать ключи в каком-либо формате, чтобы потом их адекватно перенести в go2fa
В смысле? Бутерброд – Transfer codes – Export codes. Правда, выдаст QR-код, но его перевести в текст несложно.
miss_polly
04.01.2025 07:30Крутая идея для любителей терминала! Но хотелось бы увидеть больше деталей по безопасности: как именно шифруется локальное хранилище, что делать в случае потери приватного ключа и как предотвратить утечку TOTP при копировании в буфер обмена? Интересно было бы узнать и о способах автоматической миграции с Google Authenticator, чтобы не пришлось вручную переоформлять все 2FA
tsurkan_n Автор
04.01.2025 07:30Спасибо) не вижу смысла переживать из-за безопасности отечки TOTP в буфер обмена, так как его время жизни очень ограничено. В основном до 30секунд, но бывает окна в пару минут до и после. Плюс, если вы уже использовали TOTP, то обычно один и тот же нельзя использовать дважды. Когда вы копируете с Google Authenticator TOTP, то он так и будет висеть в буфере до момента, пока его не затрут.
В случае потери приватного ключа потеряете возможность расшифровки секретов, поэтому лучше такого не допускать.
Вот на счет автоматической миграции @aamonsterи @adrozhzhov писали, как можно получить ключи из Google Authenticator, что упрощает процесс переноса. Но я пока не ознакамливался, как руки дойдут, то смогу посмотреть и может получится сделать авто-импорт
evgeniy_kudinov
04.01.2025 07:30Тоже стараюсь использовать TUI приложения в sway (console, tmux), если есть возможность. Но мне gopass + rofi вполне достаточно, и есть вроде для мобильных клиентов(на Аврору пока нет). Думаю, надо добавить в ваше приложение возможность безопасного расшаривания(переноса) секретов между хостами.
SemyonVyatskov
04.01.2025 07:30TUI — отличная идея! Нечто среднее между CUI и GUI, а то первый нужен только программистам, а второй каждый раз напоминает переусложненное собирание велосипеда.
erley
04.01.2025 07:30А stoken не подошёл бы?
Консольный, стабильный как кирпич :) Может чего-то не хватает конечно...UPD: да, он похоже только RSA умеет, так что это не совсем то же самое
tester12
04.01.2025 07:30Много ли смысла во "втором факторе", который располагается на том же устройстве, что и "первый фактор" (т.е. пароль в каком-нибудь Keepass)?
tsurkan_n Автор
04.01.2025 07:30Там где-то выше уже происходит по этому поводу дискуссия, можете присоединиться :D
Я считаю должна быть какая-то грань между безопасностью и удобством. Можно зашиться в безопасность, понаставить тройных мультифакторок и на каждый ввод TOTP еще добавлять пароль для подтверждения, что это вы, который будет меняться каждый час, в зависимости от времени суток. Как минимум, если вы по какой-либо случайности слили пароль или кто-то (имеется ввиду сервис) слил ваш пароль, то 2Fa, где бы хранилка не находилась, обеспечит эту безопасность.
А так, что устройство могут скомпрометировать, что файлы слить. Осторожность должна быть, но не уходить же в крайности. Тут уже лично решайте, как вы обеспечиваете себе безопасность, хранить это на разных устройствах или нет.xSVPx
04.01.2025 07:30Внешнее устройство скомпрометировать можно, но при настоящем 2фа вам придется скомпрометировать и его и компьютер. А это уже совершенно другой уровень геммороя.
А так да. Или некоторые неудобства или относительное отсутствие безопасности.
kujoro
04.01.2025 07:30когда смотрел, думал что уже давно твоим https://github.com/eklairs/tlock пользуюсь, оказывается перепутал
tsurkan_n Автор
04.01.2025 07:30Тоже решение на bubbletea, интересно будет посмотреть реализацию папок - а так концепция похожа, кто-то сталкивался с той же болью, что и я)
YegorP
А импорт ключей из него при этом есть?
tsurkan_n Автор
В хранилище есть БД, если у вас есть приватный ключ, то сможете его расшифровать и достать ключи
tsurkan_n Автор
В целом, можно экспорт ключей сделать - не особо сложна задачка, но вот целесообразность ее - тут надо подумать, мне пока приходилось только в нее импортить, но не экспортить :D