oriolrius.cat

Des del 2000 compartiendo sobre…

Category: Technology

Shellinabox i OTP (One Time Password)

Reading time: 7 – 11 minutes

A vegades cal poder accedir a la shell d’un servidor però no es disposa de cap client SSH ni res semblant, o fins hi tot hi ha casos en que només si pot accedir a través de proxy usant HTTP, ni tan sols es disposa d’HTTPs. Per aquests casos el que he fet és montar el següent:

Un shellinabox que és un dimoni que publica una shell a través d’HTTP, de forma que es pot usar el navegador com a client. A diferència d’altres solucions aquesta esta implementada aprofitant AJAX i no li cal suport de flash, java o d’altres tecnologies similars. Si no l’heu provat, feu-ho perquè és impressionant el bé que arriba a funcionar.

Bé doncs, gràcies al dimoni de shellinabox ja podriem publicar al port 80 la pantalla de login del nostre servidor, però en el meu cas al port 80 hi tinc l’Apache funcionant, així doncs, el que he fet és montar un proxy invers aprofitant les funcionalitats d’Apache, de forma que quan em connecto a un subdomini concret l’Apache redirecciona la meva connexió HTTP al servidor de shellinabox.

Al usar aquest client que funciona sobre un protocol sense xifrar tothom podria aconseguir de forma senzilla l’usuari i password que uso per accedir a la shell. Per tal de solucionar aquest problema el que he fet és instal·lar com a mètode d’autenticació al PAM del servidor suport OTP.

O sigui, que quan l’usuari fa login per qualsevol servei que usi el sistema d’autenticació ‘common-auth’ del PAM aquest podrà fer-ho amb el password del sistema o bé amb un password d’un sol ús. Això em garanteix que després de que jo m’hagi autenticat a la shell amb un password ningú més ho podrà fer amb aquell password.

Esquema de la idea

Configuració d’apache, proxy invers

Primer de tot cal activar el modul ‘proxy’ de l’Apache:

a2enmod proxy

Després creem un subdomini i re-enviem el tràfic cap al servidor de shellinabox:

    
<VirtualHost *:80>
    ServerName elteusubdomini.exmaple.tld

    ProxyRequests Off
    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:4200/
    ProxyPassReverse / http://127.0.0.1:4200/

    LogFormat "%h %l %u %t \"%r\" %>s %B \"%{Referer}i\" \"%{User-Agent}i\" %D" common
    CustomLog /var/log/apache2/elteusubdomini.exmaple.tld.access.log common
    ErrorLog  /var/log/apache2/elteusubdomini.exmaple.tld.error.log
    LogLevel  warn
</VirtualHost>

Després d’això ja podeu reiniciar l’apache, recordeu a crear la corresponent entrada al DNS.

Paràmetres que uso pel shellinabox

Malgrat el manual del shellinabox esta plè d’opcions molt interessants en el meu cas amb els següents paràmetres n’he tingut prou:

/opt/shellinabox/bin/shellinaboxd --no-beep -t -b
  • –no-beep no vull que emeti ‘beeps’, proveu-ho sense això a mi em van fotre un ensurt que encara tremolo
  • -t per deshabilitar l’SSL que s’activa per defecte
  • -b es llença en background

Configuració d’OTP al PAM del linux

El suport OTP que he afegit al PAM és molt limitat i bàsic, ja que no volia afegir més complexitat al sistema, o sigui, que per controlar els usuaris que poden accedir via OTP he usat un simple fitxer de text pla i per validar l’autenticació em recolzo amb el pam_script que és un mòdul de PAM que permet llençar un script arbitrari per validar l’autenticació.

Potser una de les formes més recomanables si voleu usar OTP en un servidor més professional que el que jo he usat seria fer-ho a través de RADIUS, o bé, usant MOAS el qual ofereix una interficie web feta amb PHP i backend MySQL per mantenir una taula d’usuaris i d’altres detalls de configuració.

Tornant al cas que ens ocupa, la configuració de PAM que he usat és tan senzilla com:

# fitxer: /etc/pam.d/common-auth
...
auth    sufficient      pam_script.so onerr=fail dir=/etc/pam-script.d/

auth    sufficient      pam_unix.so nullok_secure try_first_pass
...

La primera línia afegeix suport de pam_script per l’autenticació, a més de posar-hi dos paràmetres que indiquen que si aquesta falla fallarà l’autenticació i també indica a quin directori s’ha d’anar a buscar l’script d’autenticació. Aquí és on es provarà si s’ha introduït un password OTP.

La segona línia és estàndard en l’ubuntu on he fet la configuració, excepte l’últim paràmetre try_first_pass que diu que torni a provar el password que s’ha introduït en el pas anterior, així no l’hem de re-introduïr per validar si el password intruït és un password de sistema.

Ambdues línies usen la ‘flag’ sufficient, o sigui que si algún dambdós es compleix serà suficient per validar positivament l’autenticació.

El pam_script és un mòdul de PAM que al instal·lar-lo ens ha creat la carpeta /etc/pam-script.d amb uns quants fitxers al seu interior. Aquí l’únic que haurem de fer és borrar l’enllaç simbòlic anomenat: /etc/pam-script.d/pam_script_auth. Ja que per defecte aquest apunta a /etc/pam-script.d/pam_script i nosaltres no volem usar l’script per defecte sinó el nostre propi script, o sigui, el que fa la validació OTP.

L’script que fa la validació l’he modificat una miqueta respecte l’script per defecte i l’he col·locat a: /opt/otp/otp-auth. Ara ja podem refer l’enllaç simbòlic que haviem borrat abans:

ln -s /etc/pam-script.d/pam_script_auth /opt/otp/otp-auth

En el directori /opt/otp/ cal que tinguem també:

  • otp-auth – script que fa la validació, fet amb Perl i amb alguna dependència
  • otp-secrets – fitxer de configuració dels usuaris que poden usar OTP
  • cache/ – directori necessari per guardar-hi claus de forma temporal

El fitxer de configuració del /opt/otp/otp-auth el /opt/otp/otp-secrets té aquest pinta:

%users =
(
        username =>
        {
                secret => 'codi_secret_compartit_amb_eina_client',
                pin => ping_acces_eina_client,
                offset => 0,
        },
        anotheruser =>
        {
                secret => 'ZZZZZZZZZZZZZZZZ',
                pin =>  IIII,
                offset => 0,
        },
);
1;

En el meu cas, el secret l’he generat amb l’eina client que m’he instal·lat al mòbil (Android). El pin simplement ús el podeu inventar i és necessari introduir-lo al client que genera les claus.

Client OTP per Android

El client que he usat per Android és el Mobile-OTP, quan l’executeu per primera vegada ús guiarà perquè genereu un secret i un pin quan els tingueu els heu de posar al fitxer de configuració /opt/otp/otp-secrets.

Procés d’ús

Anem a un navegador qualsevol connectat a internet, accedim al subdomini que hem definit i ens surt una pantalla de login, introduïm l’usuari i ens demana el password.

Ara agafem el mòbil i obrim l’aplicació Mobile-OTP, posem el codi PIN i premem el botó ‘Calculate OTP’ inmediatament després ens surt un codi amb números i lletres i una longitud de 6 caràcters, introduïm aquest codi com a password de la nostre compte i ja som dins.

Recordeu que aquest codi és vàlid durant uns 2 minuts aproximadament, després l’haureu de tornar a generar. Aquest codi també deixa de ser vàlid en el moment en que ja l’heu usat un cop, o sigui, que si voleu fer dos logins seguits haureu de generar dos codis.

També es pot usar OTP amb altres serveis

Recordeu que al configurar el sistema d’autenticació OTP al PAM ho he fet a l’arxiu ‘common-auth’, això vol dir que qualsevol servei de la màquina que usi aquest fitxer d’autenticació (la majoria ho fan: SSH, POP3, IMAP, etc) suportarà el sistema d’autenticació OTP.

Així doncs, si feu un SSH dels de tota la vida cap a la vostre màquina però no voleu que ningú sàpigue el vostre password només mirant com escriuen els vostres dits podeu aprofitar aquest sistema.

Referències

wiki: Notes sobre entorns de programació

Reading time: < 1 minute En un .txt tenia unes notes que havia pres sobre entorns de programació, escencialment la conferència de la que són les notes parlava sobre PHP i diferents formens de fer el desplegament dels projectes. Aquesta informació l'he passat a una pàgina del wiki amb la idea d'anar-la actualitzant per altres llenguatges especialment amb la idea de afegir-hi notes de python. Així doncs l'enllaç del wiki és a: Notes about programming environments and deployment. Tal com podeu deduir amb el títol les notes són amb anglès, sento no recordar la conferència per afegir-hi la presentació.

A continuació enganxo el contingut de la wiki de forma dinàmica, així quan actualitzi la wiki s’actualitzarà l’article:

Què és un WebHook?

Reading time: < 1 minute WebHook logo
Un WebHook és una HTTP callback, o sigui, un HTTP POST que es dona quan algo passa (un event); o sigui, que podem definir WebHook com a sistema de notificació d’events per HTTP POST.

El valor més important dels WebHooks és la possibilitat de poder rebre events quan aquest passen no a través dels ineficaços mecanismes de polling.

Si voleu més informació sobre aquest tema: WebHooks site.

wiki: Glossari de seguretat

Reading time: < 1 minute Al meu wiki he començat a construir un glossari sobre seguretat, com sempre relacionat amb linux. Bàsicament són petits resums, sovint en anglès, sobre com funcionen certs protocols, mecanismes, estàndards, llibreries, software, etc. L'enllaç original del contingut és: Gloassari de seguretat

A continuació incrusto de forma dinàmica la pàgina del wiki, perquè s’actualitzi l’article en temps real. Potser això no serà visible des de l’RSS, ho desconec. Per tant, aquesta pàgina estarà en construcció indefinidament, ja que l’usaré com a quadern de notes per aquests temes. De la definició de certs termes se’n poden derivar, podcasts, screencasts, articles, etc.

Podcast 2×06: Com funciona Kerberos? autenticació i autorització (AA)

Reading time: 4 – 6 minutes

El podcast

[display_podcast]

Notes

Estàndard RFC1510 per l’autenticació, destaquen les funcionalitats de:

  • autenticació mutua
  • temps de connexió ràpids (session tickets)
  • delegació (autenticació recursiva entre serveis)

Esquemes

Simplifiació del funcionament

Hi ha 6 tipus de missatges (5 obligatoris + 1 opcional), agrupats en 3 su-protocols:

  • AS (Authentication Service) – es produeix durant el procés de “login” i li permet al client poder demanar un ticket per accedir als recursos (TGT)
    • KRB_AS_REP
      • Client principal name.
      • Timestamp.
      • Kerberos target principle name (realm).
      • Requested lifetime.
    • KRB_AS_REP
      • La primera part va xifrada usant la clau d’usuari, conté:
        • User-TGS key (generated by the KDC).
        • Kerberos target principle name (realm).
        • Ticket lifetime.
      • La segona part és el TGT, va xifrat usant la clau TGS generada pel KDC només els servidor la poden obrir, malgrat això s’enmagatzema en el client i conté:
        • Client principal name.
        • Ticket lifetime.
        • KDC timestamp.
        • User-TGS key (which is not retained by the KDC, but its presence within the TGT means it is available when required).
        • Client IP address (taken from the initial KRB_AS_REQ).
  • TGS (Ticket Granting Service) – a través del TGT el client poy demanar un “service ticket” (ST) necessari per poder accedir a un servei. El TGT té un funcionament semblant al d’un password (expira amb el temps i no requereix password), el ST obtingut seria semblant a un visat d’accés a un país.
    • KRB_TGS_REQ
      • Service principal name.
      • Requested lifetime.
      • TGT (still encrypted with the TGS key).
      • Authenticator (encrypted with the user-TGS key and containing a client timestamp) – The authenticator guarantees that the request originated from the client.
    • KRB_TGS_REP
      • La primera part va xifrada amb la clau TGS de l’usuari (el KDC l’extreu del TGT) i conté:
        • Service principal name.
        • Ticket lifetime.
        • User service key (encrypted with a user-TGS session key, generated by the KDC).
      • Part dos, és el “service ticket” (ST). Xifrat usant la clau del servei TGS. Conté:
        • User service key (encrypted with a user-TGS session key, generated by the KDC).
        • Client principal name.
        • Ticket lifetime.
        • KDC timestamp.
        • Client IP address.
  • Client/Server (AP) Exchange – per accedir a un servei el client envia al servei un KRB_AP_REQ amb el ST obtingut. El servei pot o no contestar la petició, a vegades, el servei directament comença la seva sessió.
    • KRB_AP_REQ
      • ST xifrat amb la clau TGS del servei
      • Authenticator – encrypted with the user service key
    • KRB_AP_REP

Característiques

  • Realm‘ es defineix com un domini d’aministració
  • Tots els servidors i participants en les transaccions pertanyen al mateix ‘Realm’
  • Tots els missatges viatgen xifrats usant un codi simètric (no-PKI)
  • La “user key” es genera a partir del “logon password”
  • La “host key” es genera quan el “host” s’uneix al ‘Realm’
  • Si un client vol accedir a un servei i no ha fet el TGS pot enviar el TGT en el “AP exchange” i el servei farà la gestió amb el KDC de forma transparent.
  • Important recordar que:
  • només el KDC pot llegir el TGT
  • només el servei pot llegir el ST

Glossari d’acrònims

  • KDC: Key Distribution Center
  • AS: Authentication Service
  • TGS: Ticket Granting Service
  • SS: Service Server

Referències:

Error coneguts

  • Degut a un error el podcast 2×05 no exiteix. Sento l’error!

Notes sobre Munin i Crontab, problemes amb locales

Reading time: 1 – 2 minutes

muninResum de notes interessants que acabo de descobrir sobre: munin, crontab i locales. Tot plegat corrent amb Ubuntu.

  • crontab, té diversos fitxers de configuració a /etc/cron.d la sintaxis d’aquests és la mateixa que /etc/crontab
  • els fitxers que hi ha a /etc/cron.d sovint pertanyen a serveis que necessiten executar ordres periódicament
  • al llençar munin des de dintre d’aquest directori es generaben correus d’error del crontab, queixant-se de problemes amb les locales
  • dins el fitxer /etc/cron.d/munin podem declarar les locales i així no se’ns tornarà a donar el problema
  • si volem sobrecarregar on s’han d’enviar els correu d’error de cron en un dels fitxers que hi ha /etc/cron.d podem declarar la variable MAILTO=user@domain.tld dins el propi fitxer

Jornades #decharlas sobre #symfony

Reading time: 4 – 6 minutes

symfony logo

Com deia a l’anterior article, el dilluns i dimarts vaig ser per la zona de Castelló per assistir amb el Benja a les jornades de Symfony organitzades per la Universitat de Jaume I de Castelló. Doncs bé, comentar que les jornades em van sorprendre molt positivament, realment hi havia gent amb força o fins hi tot molt nivell en la materia i això sempre és d’agraïr en aquest tipus d’events.

El programa de les xerrades era molt interessant i tret d’algunes xerrades puntuals totes eren del màxim interés per mi. Com molts esteu cansats de sentir jo no sóc programador, però en aquesta vida he picat força codi i concretament amb Symfony vaig començar-ho a fer en la versió 0.6.4, o sigui, molt abans que fos estable. Però de la mà de l’Oriol M. varem fer un projecte amb uns quants megues de codi font per fer recàrregues de mòbil a una cadena de botigues de fotografia, un dels codis dels que estic més orgullós.

Tornant a les jornades, volia destacar el meu ranking particular de ponents, es tracta d’un petit TOP 3 que des de la meva més extrema modèstia preten classificar en base a uns criteris totalment subjectius les persones que van saber transmetre els valors més importants que jo busco en una xerrada:

  • Javier Eguíluz (Symfony 2) – a destacar la gran capacitat d’enfocar la conferència cap als items més importants a resaltar, sense oblidar els detalls rellevants en cada moment, tot això sense perdre un fil conductor clar en tota la xarrada. També s’ha de dir que el tema li donava molt de joc per fer embadalir a l’audiència; però va saber com treure-li el suc i tenir-nos a tots ben enganxats malgrat estar molt cansats després de dos dies de conferències sense parar, aquesta va ser l’última conferència.
  • José Antonio Pío (Vistas y sfForm) – cal deixar-ho clar, una màquina té tota la pinta de ser un programador com la copa d’un pi i els típics defectes i virtuts de ser un professor (ho és?). Malgrat sembla que és molt bo i sap explicar-se la densitat del seu contingut i complexitat del mateix, feien complex seguir-lo tota l’estona ja que exigia molt a la concentració. Cosa gens senzilla en una marató de conferències com el que ens ocupa.
  • Jordi Llonch (Plugins) – aquest representant de les nostres terres diria que també ha fet una molt bona feina explicant-nos la potència dels plug-ins de Symfony, potser a nivell personal no m’ha aportat tan com les altres dues xerrades però la qualitat de les transparències, l’oratòria i la bona organització dels continguts diria que l’han convertit en una referència de com fer les coses, sota el meu punt de vista, és clar.

Comentar que la resta de ponències també han estat molt bé, obviament algunes amb més qualitat que d’altres i amb temes que per mi tenien un major interés que altres. Però en conjunt dono una nota altíssima al contingut de les xerrades. Pel que fa a la organització i les instal·lacions un 9, més que res per donar-los marge a millorar. Impresionant el complexe universitari, res a envejar a d’altres que he vist.

Abans de tancar aquest article tan poc ortodoxe per descriure les jornades comentar en forma de punts algunes notes mentals que me n’he emportat:

  • Hauria de posar-me amb Doctrine, però al coneixer Propel mai trobo el moment.
  • Mirar-me a fons referències sobre integració continua amb PHP i eines de gestió de projectes
  • Dona gust adonar-se que moltes pràctiques que has adoptat unilateralment també es comparteixen en la comunitat: temes d’sfForm, vistes, pugins, web escalables, cloud computing, etc.
  • Pel que fa al tema de la web escalable, m’agradaria agafar els ‘slides’ del ponent Asier Marqués i fer el meu propi screencast del tema, comparteixo quasi tot el que va dir a la conferència però em quedo amb les ganes d’aportar-hi el meu granet de sorra.
  • Mirar-me el tema d’ESI que ja l’havia oblidat.
  • MongoDB, com dic cada dia… una passada! i si a sobre es soporta a Doctrine això ja no té preu. Interessant el tema de Mondongo.
  • i l’estrella de tot plegat!!!! Symofny2… estic impacient!!!!

UPDATE: presentacions de les jornades.

dbus+python: emetent i rebent senyals

Reading time: 2 – 2 minutes

Feia massa temps que no jugava amb DBUS i les he passat una mica negres aquesta tarda intentant recordar com funcionava tot plegat. La qüestió de base és molt senzilla, com que el codi parla per si mateix. Simplement adjuntaré els dos codis.

Receptor de senyals DBUS, rep la senyal amb format ‘string’ i la mostra:

#!/usr/bin/env python
#--encoding: UTF-8--
"""
entra en un loop esperant senyals emeses a:
  dbus_interface = cat.oriolrius.prova
  object_path = "/cat/oriolrius/prova/senyal"
amb nom de senyal: 'estat'
quan es rep la senyal la mostrem
"""
import gobject
import dbus
import dbus.mainloop.glib

def mostra(m):
    print m

dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SessionBus()
bus.add_signal_receiver(
                 mostra,
                 path="/cat/oriolrius/prova/senyal",
                 dbus_interface="cat.oriolrius.prova",
                 signal_name = "estat"
                )
loop = gobject.MainLoop()
loop.run()

Emisor de senyals DBUS, envia una senyal de tipus ‘string’ amb el contingut ‘hola’:

#!/usr/bin/env python
#--encoding: UTF-8--
"""
Emet una senyal a dbus, al bus 'session' amb destí:
  dbus_interface = cat.oriolrius.prova
  object_path = "/cat/oriolrius/prova/senyal"
amb nom de senyal: 'estat'
"""
import gobject
import dbus
from dbus.service import signal,Object
import dbus.mainloop.glib

class EmetSenyal(Object):
    def __init__(self, conn, object_path='/'):
        Object.__init__(self, conn, object_path)

    @signal('cat.oriolrius.prova')
    def estat(self,m):
        global loop
        print("senyal emesa: %s" % m)
        gobject.timeout_add(2000, loop.quit)

dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
loop = gobject.MainLoop()
bus = dbus.SessionBus()
o = EmetSenyal(bus,object_path='/cat/oriolrius/prova/senyal')
o.estat('hola')
loop.run()

Usant el ‘dbus-monitor’ es pot veure la traça del missatge:

signal sender=:1.634 -> dest=(null destination) serial=2 path=/cat/oriolrius/prova/senyal; interface=cat.oriolrius.prova; member=estat
   string "hola"

Cheetah – the python powered template engine

Reading time: 2 – 3 minutes

Un article ‘fast-n-dirty’ sobre potser la millor llibreria que he trobat per treballar amb templates i python: Cheetah. Es tracta de poder generar fitxers de texte de forma senzilla: fitxers de configuració, pàgines web, emails, etc. a partir de plantilles. Realment útil en molts entorns.

Les funcionalitats (copy-paste de la web):

  • is supported by every major Python web framework.
  • is fully documented and is supported by an active user community.
  • can output/generate any text-based format.
  • compiles templates into optimized, yet readable, Python code.
  • blends the power and flexibility of Python with a simple template language that non-programmers can understand.
  • gives template authors full access to any Python data structure, module, function, object, or method in their templates. Meanwhile, it provides a way for administrators to selectively restrict access to Python when needed.
  • makes code reuse easy by providing an object-oriented interface to templates that is accessible from Python code or other Cheetah templates. One template can subclass another and selectively reimplement sections of it. Cheetah templates can be subclasses of any Python class and vice-versa.
  • provides a simple, yet powerful, caching mechanism that can dramatically improve the performance of a dynamic website.
  • encourages clean separation of content, graphic design, and program code. This leads to highly modular, flexible, and reusable site architectures, shorter development time, and HTML and program code that is easier to understand and maintain. It is particularly well suited for team efforts.
  • can be used to generate static html via its command-line tool.

a qui va orientat (copy-paste de la web):

  • for programmers to create reusable components and functions that are accessible and understandable to designers.
  • for designers to mark out placeholders for content and dynamic components in their templates.
  • for designers to soft-code aspects of their design that are either repeated in several places or are subject to change.
  • for designers to reuse and extend existing templates and thus minimize duplication of effort and code.
  • and, of course, for content writers to use the templates that designers have created.

My Workspace

Reading time: 2 – 2 minutes

Aquest és el meu entorn de treball a dia d’avui, de fet, he volgut mostrar-lo perquè volia provar de fer una petita integració entre jquery-notes i wordpress. Ja que jo diria que malgrat aquesta funcionalitat és típica de flickr quan s’exporten imatges des d’aquest sistema al nostre blog les notes de la imatge es perden. Així doncs, he pensat que era una bona idea tenir el meu propi sistema de posar notes a les imatges.
La cosa ha estat senzilla només:

  • he creat un directori al servidor del blog on he posat el jquery-notes, jquery-ui i jquery he posat els permisos corresponents als directoris.
  • he modificat les headers del wordpress perquè incloguin el codi de jquery-notes, jquery-ui i jquery. A més del CSS propi del jquery-notes i un petit script per declarar el comportament de jquery sobre la classe “jquery-note”.
  • després al crear un article amb la imatge i afegir-li la classe “jquery-note” automàticament s’afegeixen les notes que li he posat a la imatge.
  • per posar-li notes a les imatges calen els paràmetres corresponents al script afegit a les headers del wordpress.

UPDATE: casualment avui al blog: freelance switch han pubilcat un article amb diversos workspaces.