openSSL, recopilem comandes i eines web per securitzar

Tots tart o d’hora ens trobem amb la necessitat d’haber de securitzar comunicacions, i moltes vegades no tens a má la comanda openssl per segons quins casos, és per això que m’he decidit per recopilar-les.

– Per crear petición de certificar (CSR) i clau no signada, demana info per command line:

openssl req -nodes -new -keyout cortinasval.key.pem -out cortinasval.csr.pem
openssl req -nodes -new -keyout cortinasval.key.pem -out cortinasval.csr.pem rsa:2048 

– Per crear petición de certificar (CSR) a partir de clau, demana info per command line:

openssl req -nodes -new -key cortinasval.key.pem -out cortinasval.csr.pem

– Mostra la clau fingerprint d’un clau:

openssl x509 -subject -dates -fingerprint -in cortinasval.key.pem

– Generem clau de 4096 bits

openssl genrsa -out cortinasval.key.pem 4096

– Mostrem informació d’una solicitud de firma (CSR)

openssl req -text -noout -in cortinasval.csr.pem

– Mostrem informació d’un certificat generat

openssl x509 -in cortinasval.crt.pem -noout -text

– Creant fitxers PEM per als servidors

cat cortinasval.key.pem cortinasval.crt.pem cortinasval.dhp.pem > cortinasval.pem

– Firmar e-mails

openssl smine -sign -in msg.txt -text -out msg.encrypted -signer cortinasval.crt.pem -inkey cortinasval.key.pem

– Crear fitxer PKCS12

openssl pkcs12 -export -in cortinasval.crt.pem -inkey cortinasval.key.pem -out fitxer.p12 -name "Marc Cortinas"

– Mostrar certificats utilitzats en la comunicació a un socket

openssl s_client -showcerts -connect marc.cortinasval.cat:443 -CApath /etc/pki/tls/certs

Si volem crear una entitat certificadora ens hem d’assegurar que existeixin els fitxers index.txt(buit) i el serial(posat a 01), a mes, crearem directoris private i network. Editem el fitxer openssl.cnf i configurem default_days_certificate i private_key, finalment posem la cantitat de bits que utilitzarem per a la key (1024..2048)

– Per crear certificat CA

openssl req -new -x509 -days 3650 -keyout private/cortinasval-CA.key.pem -out ./cortinasval-CA.crt.pem 

– Exportar el certificat CA al format DER

openssl x509 -in cortinasval-CA.crt.pem -outform der -out cortinasval-CA.crt

– Revokem un certificat

openssl ca -revoke cortinasval.crt.pem

– Generem la llista de Revocacio de certificats

openssl ca -gencrl -out crl/cortinaslval-CA.crl

– Firmem la petició de certificat (CSR)

openssl ca -out cortinasval.crt.pem -in cortinaslval.req.pem

– Creem el parametre Diffie-Hoffman per l’actual CA

openssl dhparam -out cortinasval-CA.dhp.pem 1536

– Creem certificat auto-signat a partir d’una clau

openssl req -new -x509 -key cortinasval.key.pem -out cortinasval.crt.pem

– Encriptar un fitxer sencill

openssl enc -bf -A -in fitxer_de_test.txt

– Desencriptar un fitxer sencill

openssl enc -bf -d -A -in fitxer_de_test.txt

– Calcul de claus sha1

 openssl speed sha1

Pels servidors Webs que volguem fer ús del httpS, cada proveidor d’entitats certificadores te el seu manual, deixo aquí els 2 que he hagut d’instalar:
Thawte
Startssl

Eines utils per obtener información del nivel de seguretat:
Thhwte tool
SSL Labs

Quins conceptes hem de tenir clar?
– Tamany de Bits utilitzats a l’hora de crear el fitxers .pem
– SAN, noms de dominos acceptats pels certifictats, poden ser N noms, i tambe portar wildcard.

Balancejador HTTP/S econòmic: Nginx+Haproxy+Pacemaker

Destacades

Seguidament us explicaré com es pot montar un balancejador httpS molt econòmic i molt eficient, el qual s’ha implementat tan en entorns productius com no productius, la motivació inicial del qual va ser centralitzar el balanceig dels diferents entorns d’integració continua d’una aplicació web. En entorns productius també l’he implementat després de fer varies probes de rendiment amb el “ab” i el “siege” .

L’únic requeriment que hem d’asumir és allotjar tot tràfic dels diferents entorns en subdominis d’un domini (p.e.example.com), on podem tenir int01.example.com, int02.example.com, test01.example.com, test02.example.com, pre.example.com, etc..

Anàlogament, en els entorns de producció, podem fer la mateixa discriminació diferenciant el tràfic pels paisos(es.example.com,fr.example.com), plataformes(m.example.com), tipus de contingut(static.example.com).

Els objectius que em vaig marcar van ser:

  • Baix cost econòmic: utilitzarem programari de codi obert des dels operatius fins als dimonis: CentOS, Nginx, Haproxy, Pacemaker, Corosync.
  • Alta disponibilitat de maquinari i programari: a nivell de maquinari ho montarem en una infraestructura virtualitzada amb varis nodes físics i implemtarem el pacemaker+corosync per a tenir alta disponibilitat en els dimonis.
  • Centralitzar la negociació SSL de tota la plataforma en un punt inicial i alliberar càrrega SSL del reste de la plataforma.
  • Permetre més flexibilitat i control en els balancejos de cadascún dels entorns: haproxy permet fa possible controlar en un pool de balanceig si un frontal hi està activat segons el seu nivell de càrrega o si te connexió contra la base de dades, per exemple.
  • Tenir una plataforma securitzada, requeriment essencial sobretot en entorns productius.
  • Els dimonis que utilitzarem serà Nginx, Haproxy, Pacemaker i Corosync, tot programari lliure on abarata el cost considerablement.

    En el següent esquema es veu clarament l’arquitectura de tot el montatge.

    fisicalLB

    El comento breument, no entraré en detall en tot, em centro en lo important d’aquest post. Els navegadors dels usuaris fan les peticions a les empreses que fan de CDN, després aquestes peticions van a parar en la nostra plataforma on filtrarem el tràfic amb un firewall. Un cop les peticions són filtrades van a parar un nginx. La finalitat del nginx es discriminar el tràfic segons el entorn i centralitzar totes les negociacions SSL del tràfic HTTPS. Seguidament, les peticions passen a un haproxy on aquest balanceja entre els diferents frontals de cadascun dels entorns.

    Per tal de securitzar-ho tot, definirem 3 VLAN’s, dmz, frontend i backend. Tot el tràfic és filtrat pel firewall, el tràfic sortint, el entrant i el tràfic entre zones. En la DMZ posarem 2 maquines virtuals CentOs on tindrem els serveis de Nginx i Haproxy en actiu-passiu utlitzant pacemaker-corosync. En el frontend tenim els frontals de cadascun dels entorns i en el backend tenim les dades, mysql, cassandras, mongos, nfs, cifs, etc….

    Per exemplificar-ho millor, ens centrarem només en un entorn, int01.example.com.

    Primerament en la DMZ montarem una 2 màquines virtuals on hi tindrem 2 ip flotants, una per el nginx i l’altre pel haproxy. Jo ho he implemetat en una infraestructura virtualitzada vmware però també es poden montar solucions més econòmiques com XenServer, KVM, etc… Evidentment, sigui quina sigui la solució de virtualització, hem d’assegurar-nos que les màquines virtuales sempre estàn corrent en màquines físiques diferents.

    Les peticions entraran en la ip flotant del nginx, el nginx té dues funcions, centralitzar la negociació SSL i discriminar el tràfic per entorns. En el tràfic HTTPS afegirem una capçalera HTTP “X-forwarded-proto: https”, on l’apache la recollirà i activarà la variable HTTPS emmascarant-li a la aplicació. El tipus de certificat que afegirem en el nginx serà un certificat signat per una entitat certificadora oficial on el Common-Name que utilitzarem serà de tipus wildcard, es a dir, per aquest exemple, “*.example.com”, això ens facilitza molt la gestió del certificats i ens dona molta facilitat de gestió. En entorns de producció ho dimensionem assignant els valors correctes de worker_processes i worker_connections tenint en compte la formula: max clients = worker_processes * worker_connections/4.

    Seguidament les peticions passen al haproxy on aquest balanceja entre els diferents frontals de cadascun del entorn. El haproxy ens permet estriar l’algorisme de balanceig, jo acostumo a utilitzar Round Robin. A més, podem prefixar els rangs de IPs dels frontals que hi hauran en cadascun dels entorns, així podem desplegar més frontals en el cas que sigui necessari sense haber de reinicilitzar el dimoni.
    Haproxy fara una petició a un php que hi ha en cadascun dels frontals on retorna un “OK” si no està swapejant, no té molta càrrega i té conectivitat en les bases de dades. Cal remarcar que haproxy també ens permet realitzar balancejos “sticky” tan en aplicacions JAVA com PHP, depenentment d’una capçalara HTTP, habitualment les capçaleres JSESSIONID i PHPSESSID respectivament. (en apps ASP teniem ASPSESSIONID). En entorns de producció fixarem la variable maxconn tenim en compte que cada petició consumeix 17kb.

    Finalment les peticions arriben als frontals on primerament passen pel varnish i les peticions que no siguin cachejables arribaran finalment al apache, crec que aquests dos dimonis es mereixen un post especial per ells dos, que ja tinc en el backlog del blog.

    En el següent diagrama clarifica tota l’arquitectura:

    Diagrama Lògic

    Diagrama Lògic

    Seguidament posaré les configuracions més importants, Nginx, Haproxy, Pacemaker:

    Parametres del Nginx

    ....
    upstream http-example-int01 {
        server lb2-vip.example.com:8080;
        keepalive 16;
    }
    server {
            listen lb1-vip.example.com:80;
        server_name int01.example.com ~^.*-int01\.example\.com$;
    
            location / {
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header Host $host;
                    proxy_pass http://http-example-int01/;
                    proxy_redirect off;
            }
    }
    server {
            listen lb1-vip.example.com:443 ssl;
        server_name int01.example.com ~^.*-int01\.example\.com$;
    
            ssl on;
            ssl_certificate /etc/nginx/ssl/crt/concat.pem;
            ssl_certificate_key /etc/nginx/ssl/key/example.key;
    
            location / {
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header X-Forwarded-Proto https;
                    proxy_set_header Host $host;
                    proxy_pass http://http-example-int01/;
                    proxy_redirect off;
            }
    }
    ....
    

    Parametres del Haproxy

    ...
    frontend example-int01 lb2-vip.grpprod.com:8080
        default_backend example-int01
    backend  example-int01
            option forwardfor
            option httpchk GET /healthcheck.php
            http-check expect string OK
            server  web01 x.y.z.w:80 check inter 2000 fall 3
            server  web02 x.y.z.w:80 check inter 2000 fall 3
            server  web03 x.y.z.w:80 check inter 2000 fall 3
            server  web04 x.y.z.w:80 check inter 2000 fall 3
            server  web05 x.y.z.w:80 check inter 2000 fall 3
    ...
    

    Parametres del Apache

     ServerName int01.example.com
        DocumentRoot "/srv/www/example/fa-front/public"
    
       <Directory "/srv/www/example/fa-front/public">
          Options -Indexes FollowSymLinks
          AllowOverride None
          Allow from All
          Order Allow,Deny
          RewriteEngine On
          RewriteCond %{HTTP:X-Forwarded-Proto} https
          RewriteRule .* - [E=HTTPS:on]
    
          RewriteCond %{REQUEST_FILENAME} -s [OR]
          RewriteCond %{REQUEST_FILENAME} -l [OR]
          RewriteCond %{REQUEST_FILENAME} -d
          RewriteRule ^.*$ - [NC,L]
          RewriteRule ^.*$ index.php [NC,L]
    
       SetEnv APPLICATION_ENV int01
       DirectoryIndex index.php
    
       LogFormat "%v %{Host}i %h %l %u %t \"%r\" %>s %b %{User-agent}i" marc.int01
       CustomLog /var/log/httpd/cloud-example-front.log example
    
    

    Parametres del Pacemaker

    node balance01
    node balance02
    primitive nginx lsb:nginx \
            op monitor interval="1s" \
            meta target-role="Started
    primitive haproxy lsb:haproxy \
            op monitor interval="1s" \
            meta target-role="Started"
    primitive lb1-vip ocf:heartbeat:IPaddr2 \
            params ip="x.x.x.x" iflabel="nginx-vip" cidr_netmask="32" \
            op monitor interval="1s"
    primitive lb2-vip ocf:heartbeat:IPaddr2 \
            params ip="y.y.y.y" iflabel="haproxy-vip" cidr_netmask="32" \
            op monitor interval="1s"
    group haproxy_cluster lb2-vip haproxy \
            meta target-role="Started"
    group nginx_cluster lb1-vip  nginx \
            meta target-role="Started"
    property $id="cib-bootstrap-options" \
            dc-version="1.1.7-6.el6-148fccfd5985c5590cc601123c6c16e966b85d14" \
            cluster-infrastructure="openais" \
            expected-quorum-votes="2" \
            stonith-enabled="false" \
            last-lrm-refresh="1355137974" \
            no-quorum-policy="ignore"
    rsc_defaults $id="rsc-options" \
            resource-stickiness="100"
    

    blog personal amb domini .CAT propi, distribució i hospedatge per menys de 7€/any

    Avui és un dia trist professionalment parlant perquè el passat divendres en Tomas Nuñez, company de feina amb qui m’ho he passat molt bé durant els darrers 2 anys, va finalitzar el contracte i ha marxat al Canada a començar una nova experiència  aprofito el post per desitjar-li tota la bona sort en la seva nova aventura on estic convençut que s’ho passarà molt bé!

    A més, també cal remarcar que la motivació inicial de trastejar tot l’esmentat en aquest post va néixer sopant amb els ex-companys de la EGB, on un d’ells, l’Estanis Plantada, un geògraf viatger apassionat de la bicicleta vol fer montar-se un site per anar publicant les seves experiències.

    Dit això, vaig per feina, en aquest post us explicaré com publicar un blog (en el meu cas el que tenia en la RaspberryPi) en el “cloud” (Amazon) on l’hi traurem un millor rendiment per menys de 8€ el primer any, no entraré molt en detall tècnic, únicament el que és important és tenir recopilades TOTES les funcionalitats implementades amb un cost molt baix, alhora, recopilo els links de les diferents fonts que he anat coneixent i jugant. Per a cada punt teniu el link de les fonts consultades on he tret la informació.

      • Registre de domini

    En poc menys d’uns mesos els dominis .puntCAT han baixat molt el seu preu, vaig repassar els registradors i el més econòmic va ser CDMON que per 6.95€. Els amics de Google han llençat als EUA, Canada i ha algun país més el projecte GYBO, on pots conseguir gratis el primer any el registre de un 1 domini amb TLD del tipus .ORG .COM .CA .IN, després val 5$/mes.

      • Distribució i securització del blog gràcies a la CDN de CloudFlare

    Si volem minitzar el trafic entre el usuari final i el hosting que tindrem en Amazon, podem activar gratuitament la funcionalitat de CDN de Cloudfare, a més, també hi afegim un petit control de seguretat. L’unic inconvenient és que la versió gratuita no soporta la distribució de continguts utilitzant el protocol segur HTTPS.

    Muntem un node virtual en Amazon EC2 on hi posarem el blog (en el meu cas he migrat el blog de la RaspberryPi), aquí és on els tècnics posem més de la nostre part :). A més, cal remarcar que tindrem control total d’una maquina virtual en 1 dels CPD’s, molt útil per qualsevol tècnic que ho munti on ho aprofitarà per trastejar i implementar altres eines (ja podeu estar segurs). A destacar! tenim gratis fins a un volum de 30GB en Amazon S3! (podem muntar un owncloud i ja tenim més que GoogleDrive i Dropbox!)

    Doncs tot això ho tenim muntat en poc més d’unes hores on només hi hem invertit menys de 7€!

    Publicant Jira per httpS

    Si mai heu de publicar la aplicació de ticketing de l’empresa a internet, aqui us deixo un petit how-to de com ho he fet amb el JIRA.

    Els objectius, per variar, son principalment tenir alta disponibilitat i securitzar la publicació. Per aquest motiu ho podem fer com a minim amb 2 VLAN’s, frontend i backend, on en el frontend posarem un nginx i en el backend posarem la aplicació de JIRA.

    En el frontend posarem un servidor nginx que farà de proxypass cap el backend, en ell delegarem la negociació SSL del httpS. Aquest servidor nginx el posarem a sobre d’una plataforma virtualitzada on hi aplicarem HA, a més, podem afegir tenir un actiu-passiu utilitzant pacemaker o keepalived. Finalment hi posarem un filtrat per accedir a la part de administració de la aplicació.

    En el backend hi tindrem el servidor JIRA, on aqui la alta disponibilitat només la hem aplicat a nivell de màquina virtual, ja que la aplicació JIRA no està preparada per tenir-la clusteritzada.

    Finalment us deixo els fitxers de configuració, el del virtualhost del nginx:

    server {
        listen x.y.z.w:80;
        server_name jira.example.com;
        rewrite        ^ https://$server_name$request_uri? permanent;
    }
    server {
        listen x.y.z.w:443 ssl;
        server_name jira.example.com;
        ssl on;
        ssl_certificate /etc/nginx/ssl/crt/concat.pem;
        ssl_certificate_key /etc/nginx/ssl/key/example.key;
        location / {
            client_max_body_size 10M;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto https;
            proxy_set_header Host $host;
            proxy_pass http://http-jira/;
            proxy_redirect off;
        }
        include security_jira.conf;
    }
    

    Per tal de securitzar l’accés a la part de administració del Jira, us adjunto el fitxer security_jira.conf

    Finalment en el servidor de java-standalone hem de indicar que el les url’s les ha de montar amb el https, indicant el nom de domini i el port el cual faran les seguents peticions:

    scheme="https"
    proxyName="jira.example.com"
    proxyPort="443"
    

    Quedarà el fitxer així:

    ...
        <Service name="Catalina">
            <Connector port="8080"
                       maxThreads="150"
                       minSpareThreads="25"
                       maxSpareThreads="75"
                       connectionTimeout="20000"
                       enableLookups="false"
                       maxHttpHeaderSize="8192"
                       protocol="HTTP/1.1"
                       useBodyEncodingForURI="true"
                       redirectPort="8443"
                       acceptCount="100"
                       disableUploadTimeout="true"
                       scheme="https"
                       proxyName="jira.example.com"
                       proxyPort="443"
    />
    ....
    

    A disfrutar!