Mobil-OTP avagy azonosítás máshogy Debiánon/Ubuntun/Linuxon...

szimszon képe

„So long ago...

Frissítve: 2012.02.07.Készítettem egy új scriptet

...de kezdjük az elején. Két Hacktion rész között mikor felsírt a gyerek és kinn olvadt formában havazott a téli kora őszi tavaszon kinyitottam a böngészőm és azt látom, hogy kedvenc Web2py web frameworkömhöz valaki készített egy Mobil-OTP authentikációs modult...

...hmm, Mobil-OTP, ez azért nem az Országos Takarék Pénztár, mindig is szerettem volna valamit, ha vonaton utazok, vagy nyilvános helyen be kell jelentkezni valahova, a vállam fölött ne lássák már a root jelszót. Mondjuk azt eddig sem, mert rootként nem jelentkezek be sehova. Dehát vannak azért local root exploitok, mint az a napokban kiderüt.

Szóval ha lenne valami, hogy olcsón, értsd 0 költséggel, hogy ne egyből a biztonsági kamera felvételén a tényleges jelszavam jelenjen meg, hanem valami ami már többször nem lesz alkalmas arra, hogy bejelentkezzen vele valaki. Na ilyen nincs. Költsége mindennek van. Ha nem anyagi akkor is a normál felhasználást bonyolító megoldásnak idő vagy egyéb vonzata akár forintosítható is. De törekedjünk a költségek csökkentésére.

Valami több elemes azonosítás kellene. Na de mi a fene az a Mobil-One-Time-Password?

Mobile One Time Passwords

Mobile-OTP

strong, two-factor authentication with mobile phones

Standard phone and BlackBerry (J2ME) iPhone Google Android Windows Phone 7 PalmOS webOS Maemo Openmoko Universal Web App Windows Linux MacOS

Hát ez jó... Legtöbbször akinek olyan gondjai vannak, hogy nehogy a válla fölött nézelődve ellopják a jelszavát ilyen kemény téli időjárásban, ahol még a Mikulás szánkójáról is leolvadnak a sítalpak a kátyúkkal szabdalt magyar aszfalton. És bár nyakunkon a szibériai fagy (a cikkben -11 - -12 Cfokról beszélnek, bár ugyanez az oldal egy másik cikkében így kezdi: „Télen a hőmérő szála gyakran mínusz ötven fok alá is zuhan a közép-szibériai Tuturiban” most akkor a rövid idejű -11 - -12 fok szibériai? Lehet onnan fúj majd a szél:) egyszóval nem bízhatunk abban sem ha csak szuszog mögöttünk valaki. És akkor nem beszéltünk még a keyloggerekről net-cafekről... De vissza az eredeti témához.

Szóval tfh és itt nem a Together For The Harvest -ra gondolok, hanem tegyük fel hogy rendelkezünk legalább egy mobil telefonnal (tulajdonképpen az sem kell, van pc-s kliens is). De ha már Mobile akkor maradjunk a telefonnál.

Most akkor mi is ez?

Ez egy két faktorú beléptetést (azonosítást) megvalósító mifene. Egyrészt szükséged van valamire amit birtokolsz, esetünkben ez a telefon; és szükséged van valamire amit tudsz, ez a PIN kód. Nagyszerű. Akkor ezzel megvagyunk.

Na várjunk csak, honnan tudja a szerver, hogy melyik a telefonunk, meg PIN kódunk? Sehogy. A telefonnak nem ez a szerepe. A telefon tud valamit amit nekünk nem kell tudnunk, legalábbis nem fejből. Esőemberek előnyben.

De akkor ez sms-be adatforgalomba kerül?

Had mondjam végig!

 Szóval letöltjük a telefonra valamelyik MOTP kliens alkalmazást (client-side), nekem Androidra a DroidOTP jött be (csak 4 karakteres PIN-t támogat és csak MOTP-ot) több profilt is kezel. Miért is kell a több profil támogatás? Ugyanis ez a jóképességű eljárás abból áll, hogy indításnak 16 karakterből álló véletlenszerű betű és számsort kell megadni, ez az amire a telefon emlékszik majd helyettünk. 1 ilyen sorozat egy profilhoz tartozik. Ezt a karaktersorozatot a szervernek is ismernie kell. Ha megvan a karaktersorozat az eljárásnak szüksége van a pin kódra. Ezt a szervernek szintén előre ismernie kell. Majd a telefon veszi a UNIX epoch-ot másodpercben - tulajdonképpen 10-es másodperc léptékben -. a pin-t és a véletlen karaktersorozatot. Ebből a három összetevőből képez egy md5 hash-t és a hash első 6 karakterét megjeleníti. Ez a bejelentkezéshez használható jelszó. Szuper. Akkor nincs más hátra, mint előre. A program a telón, jó előre beélesítve, senki nem látta a véletlen karakter sorozatot, akkor mostmár jöhet a belépés bárhol.

Upsz. És a szerver? Ez már keményebb dió. Az motp oldalon több leírás is van Radius-ra és PAM-ra is. Most az utóbbiról beszélnék. Az is több lehetőséget kínál.

Először a natív pam modult próbáltam, de ezt nem sikerült lefordítani.

Másodszor van egy script a pam-script-hez. A libpam-script szépen telepíthető Ubuntun de volt egy apró bökkenő, bizonyos esetekben a pam-script nem adta át a bejelentkezéshez az adatokat az otp scriptnek. Pl. ssh ment de a login, sudo esetében nem mentek át a paraméterek.

Nini lehet egyszerűbben is. Van egy pam-exec és már fenn is volt, nem kellett külön telepíteni. Csakhogy a pam-exec nem környezeti változóban adja át a jelszót (authtok) hanem a script alapértelmezett bemenetére.

 De akkor hogy is van ez? Kezdjük a kályhától.

  • hozzunk létre egy könyvtárat: /usr/local/otp
  • és még egyet: /usr/local/otp/cache
  • chown -R root:root /usr/local/otp
  • chmod -R go-rwx /usr/local/otp
  • kell a kicsit módosított script (otp-auth-exec) -- csatolmány (a .txt kiterjesztést szedjétek le)
  • a pam-script-ből ki kell másolni a otp-secrets fájlt és betenni a /usr/local/otp könyvtárba. Ebben a fájlban van benn a véletlen karaktersor és pin kód a felhasználóhoz a felhasználói névhez.

Wow, ennyi volt.

Hát még nem. Még meg kell gyógyítani a PAM-ot. Ubuntun én a következőket tettem (a módosítás félkövéren):

 --- sshd cut ---


# PAM configuration for the Secure Shell service
auth sufficient pam_exec.so expose_authtok /usr/local/otp/otp-auth-exec
# Read environment variables from /etc/environment and
# /etc/security/pam_env.conf.
auth required pam_env.so # [1]
# In Debian 4.0 (etch), locale-related environment variables were moved to
# /etc/default/locale, so read that as well.
auth required pam_env.so envfile=/etc/default/locale
#
# Standard Un*x authentication.
#@include common-auth
# here's the fallback if no module succeeds
auth requisite pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
auth required pam_permit.so
# and here are more per-package modules (the "Additional" block)
auth optional pam_ecryptfs.so unwrap
auth optional pam_cap.so
#
# Disallow non-root logins when /etc/nologin exists.
account required pam_nologin.so
#
# Uncomment and edit /etc/security/access.conf if you need to set complex
# access limits that are hard to express in sshd_config.
# account required pam_access.so
#
# Standard Un*x authorization.
@include common-account
#
# Standard Un*x session setup and teardown.
@include common-session
#
# Print the message of the day upon successful login.
session optional pam_motd.so # [1]
#
# Print the status of the user's mailbox upon successful login.
session optional pam_mail.so standard noenv # [1]
#
# Set up user limits from /etc/security/limits.conf.
session required pam_limits.so
#
# Set up SELinux capabilities (need modified pam)
# session required pam_selinux.so multiple
#
# Standard Un*x password updating.
@include common-password

--- sshd cut ---

Így csak MOTP-vel lehet ssh-n bejelentkezni.

--- common-auth ---


#
# /etc/pam.d/common-auth - authentication settings common to all services
#
# This file is included from other service-specific PAM config files,
# and should contain a list of the authentication modules that define
# the central authentication scheme for use on the system
# (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the
# traditional Unix authentication mechanisms.
#
# As of pam 1.0.1-6, this file is managed by pam-auth-update by default.
# To take advantage of this, it is recommended that you configure any
# local modules either before or after the default block, and use
# pam-auth-update to manage selection of other modules. See
# pam-auth-update(Zsíír! for details.
# here are the per-package modules (the "Primary" block)
auth [success=3 default=ignore] pam_exec.so expose_authtok /usr/local/otp/otp-auth-exec
auth [success=2 default=ignore] pam_unix.so nullok_secure try_first_pass
auth [success=1 default=ignore] pam_winbind.so krb5_auth krb5_ccache_type=FILE cached_login try_first_pass
# here's the fallback if no module succeeds
auth requisite pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
auth required pam_permit.so
# and here are more per-package modules (the "Additional" block)
auth optional pam_ecryptfs.so unwrap
auth optional pam_cap.so
# end of pam-auth-update config

--- common-auth ---

Így minden common-auth-ot importáló pam-ot használó alkalmazás beenged MOTP-vel vagy a rendes jelszóval.

Na álljunk csak meg egy pillanatra. Az elején arról volt szó, hogy a unix timestamp alapján generálódik a belépő kód, akkor most legjobb esetben is 10 másodpercem van belépni (10 mp-es lépték van)?

 Erről szerencsére nincs szó, ha megnézzük a scriptet, látszik hogy van ±3 percünk, egyrészt az eszközök órája nem biztos, hogy pontos másrészt a 10 másodperc nem biztos, hogy elég...

Ühüm... de akkor egy-egy kód összesen 6 percig érvényes?

Nem teljesen. Csak amíg valaki be nem jelentkezik vele. Hogy valóban egy alkalmas jelszó legyen a script eltárolja a már felhasznált kódot és az legközelebb már nem lesz érvényes.

...and thanks for all the fish”

CsatolmányMéret
otp-auth-exec.txt1.69 kB

Hozzászólások

szimszon képe

Nu, egy kicsit kipofoztam a

Nu, egy kicsit kipofoztam a cuccot és python alapokra helyeztem: https://github.com/szimszon/motpy/

szimszon képe

Sajnos úgy tűnik, a

Sajnos úgy tűnik, a pam_exec-es fenti megoldás desktop környezetben nem az igazi. Pl. a gnome-screensaver nem működik megfelelően, és nem fogadja el az OTP-t.

Ez azért van, mert nem root-ként fut Uhhh az otp-s scriptre hiába tesztek setuid-et, mert ezt csak a perl futtatja.

A megkerülő megoldás az lett, hogy felvettem egy sudo sort:

--- cut ---
ALL ALL=(ALL:ALL) NOPASSWD: SETENV:/usr/local/otp/otp-auth-exec
--- cut ---

A pam fájlokban a /usr/local/otp/otp-auth-exec -et kicseréltem /usr/local/otp/otp -re.
És elkészítettem a wrapper scriptet (/usr/local/otp/otp):

--- cut ---
#!/bin/bash
export $PAM_USER
/usr/bin/sudo PAM_USER=$PAM_USER /usr/local/otp/otp-auth-exec
--- cut ---

A /usr/local/otp könyvtárra 711-es jogot állítottam be.

Nem szép, de működik.