19 грудня 2012 р.

Одноразові паролі (OTP) та сервер Apache (mod_authn_otp)


Одноразові паролі (One Time Password - OTP) надають можливість підвищити рівень безпеки при доступі до певних веб сторінок з використанням традиційних паролів і ввести двох факторний рівень автентифікації. Тобто якщо ви використали публічне місце для доступу, наприклад до корпоративної web пошти, є ймовірність запису паролів що були Вамі набранні третьою стороною. Використання одноразового паролю не дасть використовувати одноразовий пароль повторно і Ваш набранний пароль до корпоративної пошти не матиме значення без правильного одноразового.
Генерація одноразових паролів може бути зробленна багатьма алгоритмами та пристроями, або комбінацією пристроїів та алгоритмів.
В даній публікації використовую пристрій для генерації одноразових паролів за алгоритмом HMAC-based One Time Password (HOTP) що описаний специфікацією IETF RFC 4226. У моєму випадку це токен "Aladdin eToken NG-OTP".

"Aladdin eToken NG-OTP", у режимі генерації HOTP.
А також можна використовувати інші пристрої з іншими алгоритмами генерації одноразових паролів, наприклад, Mobile-OTP.
Розгляну на прикладі варіанти практичної реалізації для HOTP та Mobile-OTP.



Серверна частина

Налаштовую серверну частину. Використовується сервер FreeBSD 9.0, www сервер "apache-2.2.21".
Для розширення функціоналу www сервера і можливості використовувати автентифікацію одноразовими паролями необхідно встановити додатковий модуль "mod_authn_otp".
Модуль "mod_authn_otp" для сервера "Аpache" встановлюю з портів:
Port:   ap22-mod_authn_otp-1.1.4_1
Path:   /usr/ports/www/mod_authn_otp
Info:   Apache module for one-time password authentication
#cd /usr/ports/www/mod_authn_otp; make instal clean;

В процесі встановлення буде додано модуль"mod_authn_otp.so" сервера "Apache", а також інструмент "otptool" - HOTP/OATH one-time password utility.
Після встановлення, до конфігураційного файлу сервера "Apache" - "httpd.conf", буде додано закоментований рядок з ввімкненням модуля "mod_authn_otp.so", після заняття коментування отримав :
"LoadModule authn_otp_module   libexec/apache22/mod_authn_otp.so"

Надалі знаходжу розділ керування розділом сайту що треба захистити, наприклад
"/usr/local/www/postfixadmin/". Та додаю інформацію про захист цього розділу одноразовим паролем:

 <Directory "/usr/local/www/postfixadmin/">
    AuthType basic
    AuthName "Area protected by OTP"
    AuthBasicProvider OTP
    OTPAuthUsersFile "/usr/local/etc/apache22/otp/users.otp"
    Require valid-user
  </Directory>

Згідно цього налаштування, файл конфігурації з даними про користувачів, директива OTPAuthUsersFile, знаходиться у теці "/usr/local/etc/apache22/otp". Створимо теку, і надамо права запису процесом "Apache" від імені користувача "www" до неї. Також створимо файл в цій теці з даними про користувачів - "users.otp".

#mkdir  /usr/local/etc/apache22/otp
#chmod 700 /usr/local/etc/apache22/otp
#touch  /usr/local/etc/apache22/otp/users.otp
#chown -R www:www  /usr/local/etc/apache22/otp
#chmod -R 600 /usr/local/etc/apache22/otp

Структуру файлу конфігурації описано тут http://code.google.com/p/mod-authn-otp/wiki/UsersFile.

# Fields:
#   1. Token Type         See below
#   2. Username           User's username
#   3. PIN                User's PIN, or "-" if user has no PIN, or "+" to verify PIN via "OTPAuthPINAuthProvider"
#   4. Token Key          Secret key for the token algorithm (see RFC 4226)
#   5. Counter/Offset     Next expected counter value (event tokens) or counter offset (time tokens)
#   6. Failure counter    Number of consecutive wrong OTP's provided by this users (for "OTPAuthMaxOTPFailure")
#   7. Last OTP           The previous successfully used one-time password
#   8. Time of Last OTP   Local timestamp when the last OTP was generated (in the form 2009-06-12T17:52:32L)
#   9. Last IP address    IP address used during the most recent successful attempt
#
#   Fields 5 and beyond are optional. Fields 6 and beyond should be omitted for new users.


# Token Type Field:
#
# This field contains a string in the format: ALGORITHM [ / COUNTERINFO [ / DIGITS ] ]
#
# The ALGORITHM is either "HOTP" (RFC 4226) or "MOTP" (http://motp.sourceforge.net/).
#
# The COUNTERINFO is either "E" for an event-based token, or "TNN" for a time based token
# where "NN" is the number of seconds in one time interval. For HOTP, the default is "E";
# for MOTP, the default is "T10".
#
# The DIGITS is the number of digits in the one-time password; the default is six.
#
# Examples:
#
# HOTP - HOTP event-based token with six digit OTP
# HOTP/E - HOTP event-based token with six digit OTP
# HOTP/E/8 - HOTP event-based token with eight digit OTP
# HOTP/T30 - HOTP time-based token with 30 second interval and six digit OTP
# HOTP/T60 - HOTP time-based token with 60 second interval and six digit OTP
# HOTP/T60/5 - HOTP time-based token with 60 second interval and five digit OTP
# MOTP - Mobile-OTP time-based token 10 second interval and six digit OTP
# MOTP/E - Mobile-OTP event-based token with six digit OTP


Для тестування я створив наступну конфігурацію з даними про користувачів - "users.otp": 

HOTP test-h -    a19cdbe8475ccca8cae2d31c798b96b6e2d821f10f0d582f 0  0
MOTP test-m 1111 074581dae926835a 0  0

Де перший рядок, для автентифікації користувача "test-h" з використанням пристрою "Aladdin eToken NG-OTP".
Де другий рядок, для автентифікації користувача "test-m" з використанням програмної реалізації "Mobile-OTP".

Клієнтська частина для HOTP

Для конфігурації користувача "test-h", нам потрібен секретний ключ для токену. У пристроях на кшталт "Aladdin eToken PASS" він фіксований для кожного пристрою, і надається при продажу у вигляді файлу. У "Aladdin eToken NG-OTP" він можу бути змінним. Для ініціалізації  існує програмний комплекс SafeNet Authentication Manager (SAM) - система призначена для впровадження, управління, використання та обліку апаратних засобів аутентифікації користувачів в масштабах підприємства. Продається окремо.
Але для моїх потреб, цей комплекс не потрібен. Після консультації зі службою підтримки компанії "Aladdin", з'ясував що це можна зробити за допомогою SDK. Тому я зробив запит на отримання SDK і отримав його. На основі наданих у SDK прикладів, створив свою програму для ініціалізації об'єкту OTP у токені - "initOTP.exe".
Після отримання дозволу на публікацію програми, я її викладу до публічного доступу.
Використовувати її треба так: 
InitOTP <user-password> [[init counter] [hex secure key string]]
 Examples: 
  Random key usage: InitOTP 1234567890 
  Init count passw: InitOTP 1234567890 55 
  Fixed key usage : InitOTP 1234567890 0 b09cdbe8475ecca8ca22d31c798b96b6e2d831f10f0d581f
Де user-password - пароль доступу до eToken,init counter - початковий номер пароля OTP (0 - по замовчуванню), hex secure key string - бажаний ключ, якщо його не вказувати буде його згенеровано автоматично.
Результатом роботи буде створено новий об'єкт OTP, з заданим ключем або ключем згенерованим автоматично, з визначеним початковим порядковим номером паролю OTP. Надалі програма запросить натиснути клавішу генерації одноразового паролю (на токені) і таким чином перевірить якість згенерованого пароля. По закінченню перевірки видасть ключ у шістнадцятирічному форматі довжиною 24 байти (192 біти), котрий треба зберегти і використовувати у програмах на стороні сервера, наприклад у файлі - "users.otp" для "mod_authn_otp". Після чого токен готовий до використання і його можна витягнути з роз'єму USB.

До уваги, після ініціалізації токену (Initialize Token) засобами PKI, наприклад "SafeNet Authentication Client", об'єкт OTP з токену видаляється, і при спробі запиту на пароль OTP на дисплеї буде показано помилку "Err 14". З цієї помилки у мене і почалася робота над даною публікацією.

Клієнтська частина для Mobile-OTP

Для конфігурації користувача "test-m", нам потрібен секретний ключ що використовується у програмі Mobile-OTP, ця ж програма його і може генерувати.

Я наведу приклад використання Mobile-OTP для ОС Android:
Android 4.1, Play Market, програма Mobile OTP
Створюємо профіль, і вибираємо метод OTP
вибираю метод HOTP, для симуляції роботи як у eToken OTP
seed - ключ токену.
вибираю метод mOTP, seed - випадкові 20 знаків
профіль mobile-otp готовий до використання,
потрібно ввести PIN, отримаю пароль
вибір налаштованих профілів
Якщо довго натиснути на назву профілю то отримаємо меню
для показу секретного коду що потрібен для users.otp модуля mod_authn_otp.
Приклад використання Mobile-OTP , Java MIDlet:


Якщо ввести PIN:0000, то перейдемо до режиму ініціалізації, потрібно ввести 25 випадкових цифр, і отримаємо Init-Secret що потрібен для users.otp модуля mod_authn_otp. У опціях є можливість переглянути поточний відбиток часу Epoch-Time, часовий пояс і за необхідністю можна його змінити (клавіші 1 та 3).

З секретними паролями закінчено, тепер потрібно синхронізувати пристрої.

Синхронізація OTP

Для коректного функціювання режиму "Mobile-OTP" треба перевірити синхронізацію часу на клієнті та на сервері. Отримаємо час на сервері: #date +%s : 1355944678. Беремо перші 9 знаків з отриманого часу віднімаємо від значення "Epoch-Time" що бачимо у програмі "Mobile-OTP". Різницею буде час у секундах, вона повинна бути не більш ніж 10 секунд. Якщо вона за велика і кратна 3600, то потрібно пропорційно змінити часовий пояс у програмі "Mobile-OTP" і перевірити відповідність "Epoch-Time". Або синхронізувати час на мобільному пристрою та сервері за NTP.

У файлі конфігурації користувача присутній 5й параметр що відповідає за значення лічильника одноразового паролю або корекція часу клієнта на основі останнього прийнятого паролю.

Для  режиму "HOTP".  Якщо у Вас є тільки що проініціалізований токен, то ви можете знати значення лічильника одноразового паролю і прописати його значення у 5му параметрі файлу конфігурації користувача.
У випадку якщо ви його не знаєте значення лічильника одноразового пароля то його треба з'ясувати і записати це значення у 5му параметрі.

Є декілька методів:
  1. Використати дописану мною програму на PHP, на основі цієї публікації. Програма запитує у користувача два послідовно отриманих від токену паролі, знаючи ключ токену (прописаний у тілі програми), методом перебору визначає який поточний номер паролю. Ця програм також може використовується для автентифікації введеного одноразового паролю.
  2. Використати функцію модуля "mod_authn_otp" - автосинхронізацію. У параметрах "mod_authn_otp" є директива "OTPAuthMaxOffset", по замовчуванні це значення 4, що дозволяє підкорегувати значення лічильника паролів на стороні сервера якщо користувач натискав кнопку генерування пароля на токені, але не вводив їх під час автентифікації до сервера. Якщо тимчасово прописати директиву "OTPAuthMaxOffset" у файлі httpd.conf розділ потрібної теки :<Directory> з великим значенням наприклад 5000, то "mod_authn_otp" буде робити спробу коригування і сам визначить і запам'ятає наступне значення лічильника. Після цієй опреції директиву  "OTPAuthMaxOffset" треба повернути у попередній стан.
  3. Використати інструмент otptool , що є складовою частиною "mod_authn_otp"
    Usage: otptool [-fht] [-c counter] [-d digits] [-i interval] [-m PIN] [-w window] key [otp]
    Options:
    -c Specify the initial counter value (conflicts with `-t')
    -f `key' refers to the file containing the key
    -h Display this usage message
    -i Specify time interval in seconds (default 30)
    -m Use mOTP algorithm with given PIN; also implies `-d 6' and `-i 10'
    -t Derive initial counter value from the current time (conflicts with `-c')
    -n Specify number of digits in the generated OTP(s) (default 6)
    -w Specify size of window for additional counter values (default 0)

    #otptool -w 5000 a19cdbe8475ccca8cae2d31c798b96b6e2d821f10f0d582f 314090
    592
    Результат, номер для пароля "314090" є 592

Тестування сервера

Після налаштувань файлу конфігурації сервера "Apache" - httpd.conf, та файлу конфігурації користувача модуля "mod_authn_otp" - "/usr/local/etc/apache22/otp/users.otp", необхідно перезавантажити службу сервера "Apache". I спробувати зайти на ресурс сервера що було захищено. Ось приклад запиту на автентифікацію.

Запит автентифікації для введення паролю OTP
Якщо на дисплеї ви бачите 500 помилку сервера, замість запиту автентифікації - зверніть увагу на файл протоколу помилок "apache", можливо потрібно звернути увагу на права доступу до теки з даними користувачів, так як модуль "mod_authn_otp" повинен мати права запису та створення.

Після першої коректної автентифікації файл конфігурації - зімнеться, і додадуться додаткові параметри такі як, корекція часу, або наступний номер пароля, кількість невдалих спроб, останній пароль, час використання паролю та IP адреса кліента що його використовував.
MOTP  test-m  1111 074581dae926835a -23 0  2d843b  2012-12-19T20:01:12L 172.16.1.133
Додатково для захисту є директива "OTPAuthLogoutOnIPChange" , що зробить неможливість використання одноразового паролю якщо IP адреса клієнта була змінена протягом часу життя одноразового паролю, що визначається директивою "OTPAuthMaxLinger" і по замовчуванню становить 600 секунд.


P.S. Для швидкого завантаження на мобільному, ось QR - код з прямим посиланням на завантаження - Mobile-OTP - Java MIDlet:

http://motp.sf.net/MobileOTP.jad




Немає коментарів:


Коли забув ти рідну мову, біднієш духом ти щодня...
When you forgot your native language you would become a poor at spirit every day ...

Д.Білоус / D.Bilous
Рабів до раю не пускають. Будь вільним!

ipv6 ready