Two-factor authentication
Telegram uses the Secure Remote Password protocol version 6a to implement 2FA.
To login to an account protected by a 2FA password or to perform some other actions (like changing channel owner), you will need to verify the user’s knowledge of the current 2FA account password.
To do this, first the client needs to obtain SRP parameters and the KDF algorithm to use to check the validity of the password via account.getPassword method. For now, only the passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow algorithm is supported, so we’ll only explain that.
Then, after the user provides a password, the client should generate an InputCheckPasswordSRP object using SRP and a specific KDF algorithm as shown below and pass it to appropriate method (e.g. auth.checkPassword in case of authorization).
This extension of the SRP protocol uses the password-based PBKDF2 with 100000 iterations using sha512 ( PBKDF2HMACSHA512iter100000 ).
PBKDF2 is used to additionally rehash the x parameter, obtained using a method similar to the one described in RFC 2945 ( H(s | H ( I | password | I) | s) instead of H(s | H ( I | «:» | password) ) (see below).
Here, | denotes concatenation and + denotes the arithmetical operator + .
In all cases where concatenation of numbers passed to hashing functions is done, the numbers must be used in big-endian form, padded to 2048 bits; all maths is modulo p .
Instead of I , salt1 will be used (see SRP protocol).
Instead of s , salt2 will be used (see SRP protocol).
The main hashing function H is sha256:
The salting hashing function SH is defined as follows:
- SH(data, salt) := H(salt | data | salt)
The primary password hashing function is defined as follows:
- PH1(password, salt1, salt2) := SH(SH(password, salt1), salt2)
The secondary password hashing function is defined as follows:
- PH2(password, salt1, salt2) := SH(pbkdf2(sha512, PH1(password, salt1, salt2), salt1, 100000), salt2)
Client-side, the following parameters are extracted from the passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow object, contained in the account.password object.
p := algo.p
The client is expected to check whether p is a safe 2048-bit prime (meaning that both p and (p-1)/2 are prime, and that 2^2047 ), and that g generates a cyclic subgroup of prime order (p-1)/2, i.e. is a quadratic residue mod p. Since g is always equal to 2, 3, 4, 5, 6 or 7, this is easily done using quadratic reciprocity law, yielding a simple condition on p mod 4g — namely, p mod 8 = 7 for g = 2; p mod 3 = 2 for g = 3; no extra condition for g = 4; p mod 5 = 1 or 4 for g = 5; p mod 24 = 19 or 23 for g = 6; and p mod 7 = 3, 5 or 6 for g = 7. After g and p have been checked by the client, it makes sense to cache the result, so as to avoid repeating lengthy computations in future. This cache might be shared with one used for Authorization Key generation.
If the client has an inadequate random number generator, it makes sense to use the secure_random of account.password as additional seed.
password := (user-provided password)
srp_B and srp_id are extracted from the account.password object.
The k parameter is generated, both on client and server:
The shared param u is generated: the client does this, and the server does the same with the g_a we will send him later (see below)
The final parameters are generated client-side only:
- x := PH2(password, salt1, salt2)
- v := pow(g, x) mod p
The server already has v , from when we set the password.
A final shared param is generated, for commodity:
Finally, the key exchange process starts on both parties.
The client computes a 2048-bit number a (using sufficient entropy or the server’s random; see above) and generates:
The server computes a 2048-bit number b using sufficient entropy and generates the g_b parameter that was sent to us (see above).
- g_b := (k_v + (pow(g, b) mod p)) mod p
Finally, the SRP session keys are generated:
- t := (g_b — k_v) mod p (positive modulo, if the result is negative increment by p )
- s_a := pow(t, a + u * x) mod p
- k_a := H(s_a)
- s_b := pow(g_a * (pow(v, u) mod p), b) mod p
- k_b := H(s_b)
- g_b := (k_v + (pow(g, b) mod p)) mod p
- t := (g_b — k_v) mod p
- t := ((k_v + (pow(g, b) mod p)) — k_v) mod p
- t := pow(g, b) mod p
- s_a := pow(t, a + u * x) mod p
- s_a := pow(pow(g, b) mod p, a + u * x) mod p
- g_a := pow(g, a) mod p
- v := pow(g, x) mod p
- s_b := pow(g_a * (pow(v, u) mod p), b) mod p
- s_b := pow((pow(g, a) mod p) * (pow(pow(g, x) mod p, u) mod p), b) mod p
- s_b := pow(pow(g, a + x * u) mod p, b) mod p
s_b := pow(pow(g, b) mod p, a + u * x) mod p
s_a := pow(pow(g, b) mod p, a + u * x) mod p
Finally, as per SRP:
- M1 := H(H(p) xor H(g) | H(salt1) | H(salt2) | g_a | g_b | k_a)
M1 is passed to inputCheckPasswordSRP, along with g_a (as A parameter) and the srp_id , extracted from the account.password object.
The server then computes:
- M2 := H(H(p) xor H(g) | H(salt1) | H(salt2) | g_a | g_b | k_b)
Since we said that:
This means, if everything was done correctly,
If the password isn’t correct, 400 PASSWORD_HASH_INVALID will be returned.
To set a new 2FA password use the account.updatePasswordSettings method.
If a password is already set, generate an InputCheckPasswordSRP object as per checking passwords with SRP, and insert it in the password field of the account.updatePasswordSettings method.
To remove the current password, pass an empty new_password_hash in the account.PasswordInputSettings object.
To set a new password, use the SRP parameters and the KDF algorithm obtained using account.getPassword when generating the password field.
Then generate a new new_password_hash using the KDF algorithm specified in the new_settings , just append 32 sufficiently random bytes to the salt1 , first.
Proceed as for checking passwords with SRP, just stop at the generation of the v parameter, and use it as new_password_hash :
As usual in big endian form, padded to 2048 bits.
When setting up two-factor authorization, it is recommended to set up a recovery email, to allow recovery of the password through the user’s email address, in case they forget it.
Источник
Настройка двухфакторной аутентификации на сервере CentOS
В статье описывается настройка сервера CentOS для включения двухфакторной аутентификации с Telegram ботом при подключении через ssh терминал.
Как правило, для подключения к терминалу используется приватный ключ, сохраненный на клиенте, без ввода пароля, потому что никто не любит вводить пароли. Такая конфигурация реализует только один фактор проверки подлинности и уязвима настолько, насколько надежно хранится ключ на клиентском устройстве. Кроме того, ключи часто пересылаются по незащищенным каналам связи, лежат в сетевых или облачных папках, что совсем не добавляет защиты.
Использование второго фактора на 99% сокращает риск неправомерного доступа и совершенно не усложняет процесс подключения для пользователей.
Возможные способы аутентификации:
- Мобильное приложение MultiFactor
- Telegram
- SSHD использует модуль PAM_RADIUS для второго фактора проверки подлинности
- Модуль подключается через RADIUS протокол к сервису Мультифактор
- Мультифактор отправляет через Telegram бота сообщение пользователю с подтверждением доступа
- Пользователь подтверждает в Telegram чате запрос доступа и подключается к терминалу
Перед началом работы
Не закрывайте текущую ssh сессию, пока не убедитесь, что все работает.
- Зайдите в систему управления Мультифактором, зайдите в раздел «Ресурсы» и создайте новый Linux сервер. После создания вам будут доступны два параметра: Client ID и Shared Secret, они потребуются для последующих шагов.
- В разделе «Группы», зайдите в параметры группы «All users» и уберите флаг «Все ресурсы», чтоб только только пользователи определенной группы могли подключаться к Linux серверам.
- Создайте новую группу «Linux users», отключите все способы аутентификации кроме Telegram и укажите, что пользователи имеют доступ к созданному ресурсу Linux сервер.
- В разделе «Пользователи» создайте пользователей, которые будут иметь доступ к Linux серверам, добавьте в группу «Linux users». Логин пользователя должен совпадать с логином на Linux сервере.
- Отправьте пользователям ссылку на почту для настройки второго фактора аутентификации.
Установка и настройка модуля PAM_RADIUS
Далее создайте файл конфигурации
Впишите в него настройки RADIUS сервера Мультифактора, сохраните и закройте редактор (:x)
- radius.multifactor.ru: адрес сервера
- SHARED_SECRET: скопируйте из соответствующего параметра настроек Linux ресурса Мультифактор
- 40: таймаут ожидания запроса с запасом
В файле хранится секретный ключ, поэтому установите на него права доступа на чтение только пользователю root
Настройка PAM модулей ssh
Откройте для редактирования файл /etc/pam.d/sshd
В файле закомментируйте строку auth substack password-auth и добавьте в конец следующую настройку:
- NAS_Identifier: скопируйте из соответствующего параметра настроек Linux ресурса Мультифактор.
Сохраните и закройте файл (:x). В итоге он должен выглядеть подобным образом:
Закомментированная строка отключает проверку пароля, а добавленная подключает второй фактор.
Настройка службы SSHD
Отредактируйте файл /etc/ssh/sshd_config
- Включите PAM интерфейс
- Добавьте способы аутентификации
Сохраните файл (:x) и перезапустите ssh демона
Не закрывая текущую сессию, подключите новую.
От Telegram бота придет сообщение с запросом подтверждения доступа.
Одна кнопка разрешает доступ, вторая блокирует.
Если что-то не работает
Последовательно проверьте, что вы ничего не упустили:
- На сервере с Linux есть пользователь с заданным логином
- С сервера открыт доступ по UDP порту 1812 на адрес radius.multifactor.ru
- Параметры Client ID и Shared Secret указаны корректно
- В системе Мультифактор заведен пользователь с таким же логином и ему предоставлен доступ в группу пользователей Linux users
- Пользователь настроил способ аутентификации через Telegram
- Проверьте журнал «Запросы доступа» в личном кабинете Мультифактора.
Если ничего не сработало, обращайтесь, поможем.
Источник
Настройка двухфакторной аутентификации в OpenVPN
В статье описывается настройка сервера OpenVPN для включения двухфакторной аутентификации.
OpenVPN — широко известный, бесплатный VPN сервер с открытым исходным кодом, который повсеместно используется для предоставления защищенного доступа сотрудников к внутренним ресурсам организации.
В качестве проверки подлинности для подключения к VPN серверу, как правило используется комбинация из ключа и логина/пароля пользователя. При этом, сохраненный на клиенте пароль превращает весь набор в единый фактор, не обеспечивающий должный уровень безопасности. Злоумышленник, получив доступ к клиентскому компьютеру, получает доступ и к VPN серверу в том числе. Особенно это касается подключения с машин под управлением Windows.
Использование второго фактора на 99% сокращает риск неправомерного доступа и совершенно не усложняет процесс подключения для пользователей.
Возможные способы аутентификации:
- Мобильное приложение MultiFactor
- Telegram
- Звонок (нужно принять вызов и нажать #)
- Аппаратные OTP токены
- Приложения OTP: Google Authenticator или Яндекс.Ключ
- OpenVPN использует плагин openvpn-plugin-auth-pam для проверки подлинности
- Плагин запрашивает второй фактор через RADIUS протокол в сервисе Мультифактора
- Пользователь подтверждает в телефоне запрос доступа или вводит одноразовый код и подключается к VPN
OpenVPN можно настроить в двух конфигурациях: с проверкой логина и пароля пользователя на сервере и без проверки. Во втором случае, одним из факторов аутентификации будет являться сертификат пользователя.
Установка OpenVPN сервера
В интернете множество статей, описывающих процесс установки и настройки OpenVPN, поэтому мы не будем их дублировать. Если вам нужна помощь, в конце статьи есть несколько ссылок на обучающие материалы.
Зайдите в систему управления Мультифактором, зайдите в раздел «Ресурсы» и создайте новый OpenVPN. После создания вам будут доступны два параметра: NAS-IDentifier и Shared Secret, они потребуются для последующий настройки.
Настройка OpenVPN сервера
Откройте файл /etc/openvpn/server.conf и добавьте плагин для аутентификации с помощью PAM модуля
Плагин может находиться в директории /usr/lib/openvpn/plugins/ или /usr/lib64/openvpn/plugins/ в зависимости от вашей системы.
Далее создайте файл для service-type openvpn
Источник