Генерация одноразовых паролей в Linux

()

Есть различные алгоритмы генерации одноразовых паролей. В настоящий момент наиболее популярными являются алгоритмы TOTP и HOTP. В качестве примера реализации можно упомянуть такие мобильные приложения как Google Authentificator и Яндекс.Ключ.

В большинстве случаев установленных на мобильном телефоне приложений вполне достаточно. Однако иногда возникает потребность в приложении для компьютера. Особенно если ввод одноразового пароля необходимо делать по ходу выполнения какого-либо скрипта. К счастью на этот случай есть реализация TOTP и HOTP в виде утилиты для командной строки с открытым исходным кодом. О ней и будет рассказано ниже.

Для начала установим утилиту. В Debian/Ubuntu это можно сделать командой:

apt install oathtool

Перейдём к использованию. Часто для инициализации генератора ключей предлагается отсканировать QR-код. Этот QR-код содержит ссылку со схемой "otpauth". Описание протокола можно найти тут. После получения ссылки можно составить строку запуска для oathtool, опираясь на man-страницу утилиты. В остальных случаях придётся разбираться с набором параметров самостоятельно.

Например при настройке одноразовых паролей в VK для начальной настройки приложения предлагается четыре группы по четыре символа. Это base32-кодированный ключ для вычисления кодов по алгоритму TOTP. Получить одноразовый код на его основе можно так:

oathtool --totp -b "ABCD EFGH IJKL MNOP"

Здесь "ABCD EFGH IJKL MNOP" полученный от VK. Обратите внимание что его надо брать в кавычки. Если использование кавычек неудобно (например в скрипте) то стоит удалить пробелы и можно использовать без кавычек:

oathtool --totp -b ABCDEFGHIJKLMNOP

Facebook предлагает уже восемь групп по четыре знака, но это всё равно base32-кодированный ключ. Собственно если не указано другое то используется base32-кодированный ключ.

Одним из самых больших удобств oathtool является возможность использования в скриптах. Рассмотрим небольшой пример: необходимо подключиться к L2TP-серверу с PSK, зазщищённому с помощью одноразовых паролей. В реализации, с которой столкнулся автор этих строк, пароль от аккаунта являлся конкатенацией двух частей: статичной, и переменной (одноразовый код).

В итоге был написан вот такой скрипт, использующий возможности Network Manager:

#!/bin/bash

# First install network-manager-l2tp and oathtool!


#####################################
# Settings 
#####################################

# Имя соединения
S_NAME="MYL2TPVPN"

# Параметры соединения
# Хост, к которому будем подключаться
S_HOST="some.vpn.host"

# Pre-shared ключ
S_PSK="pR3Sh4rdKey"

# Логин
S_USER="vpn-user"

# Статичная часть пароля
S_PASS="vpn-p4ss"

# Ключ для генерации кодов по алигоритму TOTP
S_S0="ABCDEFGHIJKLMNOP"
######################################


# Проверяем что установлены необходимые утилиты
NEEDEXIT="0"
for tool in "nmcli" "oathtool"; do
        which ${tool} > /dev/null
        if [ "$?" != "0" ]; then
                echo "${tool} not found!"
                NEEDEXIT=1
        fi
done

# Чего не хватило? - Завершаемся
if [ "${NEEDEXIT}" != "0" ]; then
        exit 1
fi

# Функция создания нового соединения
connadd() {
        VPNDATA="gateway = ${S_HOST}, \
                        ipsec-enabled = yes, \
                        ipsec-forceencaps = yes, \
                        ipsec-psk = ${S_PSK}, \
                        user = ${S_USER}, \
                        password-flags=2"
        nmcli connection add \
                save yes \
                type vpn \
                vpn.service-type "org.freedesktop.NetworkManager.l2tp" \
                con-name "${S_NAME}" \
                vpn.data "${VPNDATA}"
}

# Функция проверки существования соединения
conncheck() {
        nmcli connection show "${S_NAME}" > /dev/null 2>&1
}

# Функция подключения к серверу
connup() {
        OTPKEY=`oathtool --totp -b ${S_S0}`
        VPNPASS="${S_PASS}${OTPKEY}"
        PASSFILE=`mktemp`
        echo "vpn.secrets.password:${VPNPASS}" > ${PASSFILE}
        nmcli connection up "${S_NAME}" passwd-file ${PASSFILE}
        rm -f ${PASSFILE}
}


# Проверяем наличие соединения
# Если нет - создаем
conncheck
if [ "$?" != "0" ]; then
        connadd
fi

# Поднимаем соединение
connup

Этот скрипт удобен как минимум тем что не надо спешить. При ручном получении кода, объединении с базовой частью и вводе пароля можно банально не успеть уложиться в одну минуту. Обратной стороной такого удобства является необходимость тщательно охранять этот скрипт от попадания в чужие руки: как минимум располагаться он должен внутри VeraCrypt-контейнера, encFS-директории или любого другого хранилища, обеспечивающего надёжное шифрование.

На этом пока всё. Приятной работы!

Ключевые слова: oathtool, totp, hotp, l2tp, одноразовые пароли, otp.

Подписаться на обновления: RSS-лента Канал в TamTam Telegram канал Канал в ICQ

Комментарии:

Anonymous 2020-10-25 03:50:05 (#)

Следующая статься должна быть про veracrypt и encfs. Интересненько.
Новый комментарий

Жирный текстКурсивный текстПодчёркнутый текстЗачёркнутый текстПрограммный кодСсылкаИзображение




© 2006-2024 Вадим Калинников aka MooSE
Политика конфиденциальности