Salta el contingut

MP08 - UF1: Configuració bàsica Apache i Nginx (Certificat autosignat)

En aquest exercici veurem com fer una CA i un certificat autosignat per tal d'aplicar-lo a un VirtualHost amb accés HTTPS.

https

Cal recordar que,

en Apache tenim un site no habilitat en el fitxer /etc/apache2/sites-available/default-ssl.conf. Aquest site és el que tenim per habilitar el servidor web pel port segur 443 a través d'accés https.

Podem veure el contingut inicial del fitxer /etc/apache2/sites-available/default-ssl.conf

Fitxer sense les línies comentades
<IfModule mod_ssl.c>
    <VirtualHost _default_:443>
            ServerAdmin webmaster@localhost
            DocumentRoot /var/www/html
            ErrorLog ${APACHE_LOG_DIR}/error.log
            CustomLog ${APACHE_LOG_DIR}/access.log combined
            SSLEngine on
            SSLCertificateFile      /etc/ssl/certs/ssl-cert-snakeoil.pem
            SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
            <FilesMatch "\.(cgi|shtml|phtml|php)$">
                            SSLOptions +StdEnvVars
            </FilesMatch>
            <Directory /usr/lib/cgi-bin>
                            SSLOptions +StdEnvVars
            </Directory>
    </VirtualHost>
</IfModule>

Habiltarem el mòdul ssl i el site https per defecte i hi accedirem...

a2enmod ssl
a2ensite default-ssl
systemctl reload apache2

en Nginx podem crear un site nou o aprofitar el que tenim per defecte. Tenim les línies comentades al fitxer default, que escolti pèl port 443, amb la directiva listen.

Descomentem les línies del fitxer default que fan referència al https (SSL configuration)

Fitxer sense les línies comentades
# SSL configuration
#
listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;

Fixa't que el fitxer /etc/nginx/snippets/snakeoil.conf conté la ruta als certificats.

cat /etc/nginx/snippets/snakeoil.conf
# Self signed certificates generated by the ssl-cert package
# Don't use them in a production server!

ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;

Accedim i el sistema ens avisa del certificat i el perill que tenim en entrar en aquesta web.

Accés https amb certificat inicial

Si revisem les parts importants del fitxer de configuració del site, ens interessen aquestes 3 línies:

  • SSLEngine On: activa el sistema SSL pel virtualhost.

  • SSLCertificateFile: indica on hi ha el certificat a mostrar (clau pública).

  • SSLCertificateKeyFile: indica on hi ha la clau privada per descodificar.

Si revisem les parts importants del fitxer de configuració del site i del que incloem, ens interessen aquestes 3 línies:

  • listen 443 ssl default_server;: activa el sistema SSL pel site.

  • ssl_certificate: indica on hi ha el certificat a mostrar (clau pública).

  • ssl_certificate_key: indica on hi ha la clau privada per descodificar.

Per defecte, la llibreria SSL a Linux porta ja un certificat autosignat que podeu aprofitar. El trobareu a /etc/ssl/certs/ssl-cert-snakeoil.pem.

Si volem veure el contingut, podem llançar la següent comanda:

openssl x509 -in /etc/ssl/certs/ssl-cert-snakeoil.pem -text -noout

Si ens hi fixem, es mostra informació del certificat, però no està validat per cap CA. Per això quan ens connectem per HTTPs, el navegador ens llança un avís de seguretat.

Si volguéssim fer-lo vàlid, cal que una CA autoritzada ens el firmi. Això té un cost. És bo que sapiguem, que des de fa uns anys, existeix una entitat, Let`s Encrypt -> letsencrypt.org, que ofereix certificats gratuïts plenament vàlids. Aquesta vegada no ho farem servir perquè, un dels requisits, és que la pàgina ha d'estar penjada sota un domini DNS vàlid, i fins ara estem treballant amb IP privades.

Per tant, el que podem fer és, crear-nos una CA nosaltres, i firmar-nos el nostre certificat autosignat nou que farem. Així i tot, evidentment, com que la CA no serà autèntica, us donarà un avís, però, sobre com evitar-ho, en parlarem més endavant.

Primer de tot, doncs, ens crearem una CA pròpia:

openssl req -nodes -x509 -newkey rsa:2048 -days 1460 -keyout <ca_name>.key -out <ca_name>.crt

amb aquesta comanda podem definir l'algorisme de xifratge, la longitud de la clau, els dies de validesa que tindrà la CA, i amb <ca_name> definim el nom de la CA.

Exemple d'execució
openssl req -nodes -x509 -newkey rsa:2048 -days 1460 -keyout servidor-apache.key -out servidor-apache.crt

Quan es crea una CA, ens demana unes dades d'identificació de la mateixa:

  • Country Name: ES

  • State or Province Name: Girona

  • Locality: Girona

  • Organization Name: Institut Montilivi

  • Organization Unit Name: DAW-MP08

  • Common Name: Grup X (on X és el vostre número de grup al projecte).

  • Email Address: l'adreça d'un dels membres del grup.

Ara hem creat els certificats <ca_name>.crt i <ca_name>.key de la CA.

  • Paràmetres

    • -nodes: no demana clau o paraula de pas per generar la clau privada.

    • -x509: indica que serà un certificat autosignat. L'X.509 és un estàndard d'infraestructura de claus públiques al que s'adhereixen SSL i TLS per l'administració de claus i certificats.

    • -newkey rsa:2048: especifica que volem generar un nou certificat i una nova clau a la vegada. No creem la clau necessària per a signar el certificat en un pas anterior, per tant, cal crear-la amb el certificat. La part rsa:2048 indica que creï una clau RSA de 2048 bits d'extensió.

    • -keyout <ca_name>.key: indica a OpenSSL el nom del fitxer de clau privada que ha de generar.

    • -out <ca_name>.crt: indica a OpenSSL el nom del certificat.

Per altra banda, cal que generem un nou parell de claus privada-pública que ens permetrà generar el certificat per després signar-lo. Per això executarem:

openssl genrsa -out <server_name>.key 2048
Exemple d'execució
openssl genrsa -out apache.key 2048

Acabem de crear la clau <server_name>.key. Amb això haurem fet la nostra clau privada. Ara caldrà fer el CSR (Certificate Signing Request), que és una petició de certificat per tal que una CA el validi. Si no l'haguéssim de signar. ja podríem fer el certificat directament, però aquí cal que la CA ens retorni un certificat firmat, i per això ho ha de fer la CA amb la seva clau privada. Per això executarem:

openssl req -new -key <server_name>.key -out <server_name>.csr
Exemple d'execució
openssl req -new -key apache.key -out apache.csr

Per posar el valor de <server_name>.key, feu igual que ho heu fet a la part anterior. Aquí també us demanarà unes dades, que són clau. Podeu posar-ho tot igual, però sobretot, a Common Name hi ha d'anar el nom del host (el ServerName de l'apache o el server_name del nginx) pel qual funcionarà el certificat. També us preguntarà si voleu associar un password al certificat. En aquest cas s'ha de deixar en blanc, ja que si el poséssim tindríem un problema. Com que això és un certificat web cada cop que arranqués el servei web no podria funcionar fins a introduir la passphrase de la clau privada, i això està molt bé si estem al davant, però no pas tant si hi ha un reinici espontani del servei a les 4.00AM d'un diumenge.

Abans d'enviar-lo és interessant veure el contingut del CSR per repassar si tot està correcte, o en el cas que fóssim nosaltres la CA, verificar que està tot correcte. Això ho podem fer amb:

openssl req -text -noout -verify -in <server_name>.csr
Exemple d'execució
openssl req -text -noout -verify -in apache.csr

Ara ja tenim el CSR a punt perquè la CA el firmi. En aquest cas com que nosaltres actuem tant com a servidor com a CA ho fem nosaltres mateixos, però en un cas normal, és quan enviaríem el CSR a una entitat certificadora perquè ens generés el certificat firmat, i el que ens retornés seria el que posaríem al servidor web.

openssl x509 -CA <ca_name>.crt -CAkey <ca_name>.key -req -in <server_name>.csr -days 365 -CAcreateserial -sha256 -out <server_name>.crt
Exemple d'execució
openssl x509 -CA servidor-apache.crt -CAkey servidor-apache.key -req -in apache.csr -days 365 -CAcreateserial -sha256 -out apache.crt

Aquesta comanda cal realitzar-la com a superusuari, per tant, cal afegir sudo al davant.

Per acabar, és interessant revisar la informació del certificat que tenim sota CRT. Per això podem llançar:

openssl x509 -in <server_name>.crt -text -noout
Exemple d'execució
openssl x509 -in apache.crt -text -noout

Ara ja tenim tot el necessari en l'ambit de SSL per tenir servei HTTPS i fer servir el certificat al servidor web. Només ens faltarà posar els fitxers on toca i assignar-ho a la configuració del servidor.

La llibreria SSL de Linux treballa amb una estructura determinada dins de /etc/ssl/ on trobareu la carpeta private, que és on van les claus, i la carpeta certs, que és on van els certificats. Si ho voleu posar tot on toca, caldrà que els certificats de la CA i del servidor vagin a la carpeta de certs, i les claus, a la carpeta de private.

Si feu la prova amb el navegador, igualment us donarà un avís de seguretat. Això és perquè el nostre navegador no coneix la CA, i per tant no li dona validesa. Caldrà doncs dir-li al firefox que confiï en aquesta CA. Per això caldrà que aneu als paràmetres el Firefox a la part de privadesa i aneu a l'apartat de Certificats. Hi hauria d'haver un botó que digui Gestor de certificats o Mostra els certificats. Hi aneu i busqueu la pestanya de les Entitats. Aquí caldrà afegir el certificat (no la clau) de la CA creada anteriorment i donar-li confiança.

Certificats d'Entitat CA al Firefox

Això us hauria de validar l'entrada directament per HTTPs. Sinó, evidentment, sempre podeu afegir l'excepció i llestos.

I si no t'e n'has sortit

Copiem els fitxers de les claus a /etc/ssl/private, però, fixeu-vos ens el permisos i propietats que té el fitxer que ara hi ha: -rw-r----- 1 root ssl-cert 1704 Jul 17 10:12 ssl-cert-snakeoil.key, per tant, deixarem els nostres fitxers iguals:

chmod g+r *key
sudo chown root:ssl-cert *key
sudo cp -a *key /etc/ssl/private

sudo ln -s /home/isard/ssl/server_name.crt /etc/ssl/certs/server_name.crt

Suposant que hem creat els certificats al directori $HOME/ssl

i modifiquem el fitxer /etc/apache2/sites-enabled/default-ssl.conf apuntant als nous certificats, tant el públic com el privat.

# SSLCertificateFile      /etc/ssl/certs/ssl-cert-snakeoil.pem
# SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
SSLCertificateFile      /etc/ssl/certs/<server_name>.crt
SSLCertificateKeyFile /etc/ssl/private/<server_name>.key

i modifiquem el fitxer /etc/apache2/sites-enabled/default-ssl.conf apuntant als nous certificats, tant el públic com el privat.

# Self signed certificates generated by the ssl-cert package
# Don't use them in a production server!

# ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
# ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
ssl_certificate /etc/ssl/certs/<server_name>.crt;
ssl_certificate_key /etc/ssl/private/<server_name>.key;

Resumint

Al final, tenim les dues claus del nostre site. Una és el certificat i l'altra la clau privada. Aquesta darrera no s'ha de donar mai a ningú.

-rw-rw-r-- 1 isard isard    1379 Mmm dd hh:mm <server_name>.crt
-rw-r----- 1 root  ssl-cert 1704 Mmm dd hh:mm <server_name>.key

Per tenir el parell de claus, pública (<server_name>.crt) i privada (<server_name>.key), hem generat la clau privada amb una pública sense signar (<server_name>.csr) i l'hem enviada a l'entitat certificadora, nosaltres mateixos, que ens ha generat la clau pública definitiva (<server_name>.crt).

Com que no ho hem volgut enviar a cap entitat certificadora, hem hagut de fer-nos la nostra pròpia CA per tal de signar-nos la clau pública. Aquesta nostra CA, són les claus <ca_name>.crt i <ca_name>.key.

isard@ubuntu:~$ ls -l ~/ssl
total 20
-rw-rw-r-- 1 isard isard    1489 Mmm dd hh:mm <ca_name>.crt
-rw-r----- 1 root  ssl-cert 1704 Mmm dd hh:mm <ca_name>.key
-rw-rw-r-- 1 isard isard    1379 Mmm dd hh:mm <server_name>.crt
-rw-rw-r-- 1 isard isard    1090 Mmm dd hh:mm <server_name>.csr
-rw-r----- 1 root  ssl-cert 1704 Mmm dd hh:mm <server_name>.key

Podríem haver fet un certificat sense necessitat de signar-lo per cap CA

Amb una sola comanda podríem haver generat un certificat sense haver-lo signat ningú. Només calia executar la comanda següent:

openssl req -new -x509 -nodes -days 365 -keyout fitxerClauPrivada.key -out fitxerCertificat.crt

i haver posat els fitxers generats al seu lloc amb els permisos i propietats pertinents.