TLS proporciona confidencialitat i autenticitat entre dos aplicacions a nivell de socket
Seguretat de la capa de transport (TLS)
Transport Security Layer (TLS) és un protocol:
-
Xifrar una connexió de xarxa durant el trànsit mitjançant criptografia simètrica (AES o ChaCha20)
-
Verificar l’autenticitat del servidor mitjançant criptografia asimètrica (RSA o EC) mijançant l’ús de certificats, documents digitals firmats per una autoritat de certificació que garantitza que el servidor és qui diu que és.
Encara que la majoria de connexions TLS són HTTPS, qualsevol aplicació compatible amb TLS pot aplicar TLS a qualsevol connexió de xarxa TCP o UDP.
Història
El primer navegador web el va crear Netscape Corporation.
L’any 1994 van crear un protocol de seguretat de la capa de transport, conegut com Secure Socket Layer, per establir una conexió segura entre el navegador Netscape i els servidors web.
Com sol ser habitual quan una és dissenya un pròtocol nou, aquest tenia bastants defectes, i Netscape va llançara ràpidament la versió 2 de SSL el 1995, i la versió ·el 1996.
De totes maneres el disseny criptogràfic bàsic de SSL era defectuós i molt difícil de solucionar.
L’any 1999 l’IETF va desenvolupar un protocol a partir de SSLv3, que va anomenar TLD per motius legals.
Com és d’esperar van anar apareixent noves versions de TLS: el 2006 TLSv1.1, el 2008 TLSv1.2 i el 2018 TLSv1.3.
I tot això perquè interessa saber-ho?
Perquè quan busques per internet sapigues que quan es parla de SSL o TLS estem parlant del mateix.
Durant molt de temps tothom ha fet servir el nom SSL, i per això l’eina que farem servir i que vas fer servir a criptografia s’anomena OpenSSL encara que fem connexions TLS.
No obstant, cada cop més el nom que es fa servir és TLS, perquè avui en dia només es considera segur la versió 3 de TLS.
Desde el 2021, la NSA i diversos organismes de seguretat d’altres països recomanen de manera molt ferma que ja no es faci servir TLSv2, perquè es considera insegur.
Ara el nom modern que es fa servis és TLS.
Per què TLS?
TLS no és l’únic protocol segur a Internet: tenim IPSec, {% link “/network/wireguard/” %}, OpenVPN i d’altres que ja no es fan servir.
Llavors que té d’especial TLS perqué sigui el protocol de connexió segura més utilitzat a Internet? TLS és un protocol genèric que es va dissenyar per permetre encriptar una connexió entre client i servidor, i que es pogués integrar amb una altre protocol de manera senzilla.
Netscape tenia que crear un protocol que fes que HTTP fos segur, sense tocar el protocol HTTP.
D’aquesta manera un client pot comprobar si el servidor fa servir TLS, si és així encriptar mitjançant TLS, i si no és així seguir amb el protocol sense encriptar si ho considera adient.
A més, d’aquesta manera el protocol TLS pot seguir evolucionat de manera independent del protocol que encripta, ja sigui HTTP, FTP, etc.
Per això, quan parlem de HTTPS potser estem parlant de HTTP sobre SSL (gens segur) o HTTP sobre TLS (més segur, i molt segur depenent de la versió de TLS)
openssl
OpenSSL (i forks com LibreSSL) són llibreries de propòsit general per a tot el que te a veure amb la criptografia i els aspectes relacionats.
Amb openssl pots crear un parell de claus assimètriques, signar fitxers digitalment, llegir fitxers ASN.1 i X.509, generar números aleatoris i verificar certificats TLS.
La majoria d’administradors de sistema no entenen les bases matemàtiques de la criptografia perquè és difícil d’entendre, molt més que les equacions diferencial multivariable.
Però per portar un patinet elèctric no cal conèixer electromècanica, només com fer funcionar el patinet.
L’únic que has d’entendre és que la criptografia és molt complexa, i openssl ha heretat aquesta complexitat i el tenir que ser compatible amb tota la seva història.
De totes maneres, com que avui en dia l’únic “segur” és TLSv1.3, hi ha llibreries noves que només implementes aquest protocol.
Tal com pots apendre a {% link “/security/cryptography/” %} una ordre openssl té aquesta sintaxis: `
El paràmetre subcommand determina amb quin conjunt de funcions criptogràfiques estem treballant.
Per exemple, la subordre genrsap genera un parell de claus assimètriques RSA, mentres que la subordre x509` té a veure amb els X.509.
Moltes subordres fan servir els mateixos flags per funcions semblants: per exepmple -in i -out per input i output, -text per format textual.
Tingues en compte que openssl no permet ajuntar flags com pots fer per exemple amb tar, com quan vols comprimir un conjunt de fitxers amb l’ordre tar -czvfp.
Per veure quina versió d’OpenSSL tens:
La versió final 3.0 d’OpenSSL es va publicar a finals del 2021: OpenSSL 3.0 Has Been Released!.
Per tenir més informació de com s’ha empaquetat i configurat la distribució concreta de openssl que estas fen servir:
Moltes ordres estan dissenyades per funcionar amb altres ordres openssl mijantçant l’ús de pipes ( | ):
|
depth=2
depth=1
depth=0
L’ordre s_client fa una funció semblant a netcat, però amb TLS, negociant una connexió TLS amb el servidor en el host i port que li diguis.
depth=2
Es tracta d’una ordre interactiva com pots veure a continuació:
Amb el text GET / HTTP/1.1 envies una sol.licitut HTTP al servidor amb la ruta /.
Recorda que has de premer dos cops ENTER perquè s’enviï la sol.licitud!
Amb la lletra Q tanquem la sessió:
El flag -showcert fa que es mostrin tots els certificats enviats pel servidor:
;
;
EwO9FwFC4q9WKz7fAanM8Dg=
En l’exemple mostrem el certificat 0 pel domini *.google.es firmat per “Google Trust Services LLC”.
Si no volem una sessió interactiva podem passar com a input /dev/null per tal de que openssl no esperi una entrada per teclat.
Pots veure com la sessió es tanca automàticament.
Si vols fer un “parse” del certificat X.509 pots utilitzar l’ordre x509 amb el flag -noout per indicar que no et mostri el certificat codificat.
|
depth=2
depth=1
depth=0
EwO9FwFC4q9WKz7fAanM8Dg=
D’aquesta manera podem veure de manera resumida la cadena de certificats.
El certificat està codificat en Base64.
Si vols veure el seu contingut pots utilitzar el flag -text:
|
depth=2
depth=1
depth=0
Composant aquestes dues ordres amb una pipe ( | ) pots veure el certificat de qualsevol lloc web que es fa servir per autenticar els llocs web.
TLS versus DTLS
Els dos protocols a nivell de transport que es fan servir a Internet són TCP i UDP.
TLS, com http i altres protocols, només funcionen amb TCP.
No obstant, moltes aplicacions UDP també necessiten encriptar la connexió.
En lloc d’inventar un protocol completament nou, es va afegir un sistema de seguiment de l’estat al protocol TLS per gestionar tota la comptabilitat de la xarxa.
El resultat és el protocol Datagram Transport Layer Security (DTLS).
DTLS va ser dissenyat deliberadament per funcionar exactament com TLS.
El codi és diferent i l’estructura del paquet és diferent, però per a un administrador del sistema és el mateix. Un certificat TLS funciona bé a DTLS.
DTLS s’utilitza principalment en xarxes virtuals privades.
Suite de xifrat
Per establir una connexió segura es necessiten diferents eines criptogràfiques, i cada eina criptogràfica té diferents implementacions, i el client i el servidor s’han de posar d’acord de quines fer servir.
Un protocol TLS específica quines combinaciones es poden utilitzar de clau simètrica, asimètrica i hash.
Per veure tots els ciphers (“xifrats”) que té implementats ( flag -s) la teva distribució OpenSSL:
Mac=AEAD
Mac=AEAD
Mac=AEAD
Com pots veure són uns quants, 30 en total:
|
Els que ens interessa són els ciphers que es poden fer servir en el protocol TLSv1.3:
|
Mac=AEAD
Mac=AEAD
Mac=AEADPots veure que només en tenim tres per escollir:
Si vas a la wiki oficial veurás que el protocol TLSv1.3 inclou cinc xifrats posibles: TLS1.3 - OpenSSLWiki.
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_128_GCM_SHA256
TLS_AES_256_GCM_SHA384
TLS_AES_128_CCM_SHA256
TLS_AES_128_CCM_8_SHA256Però el nostre client openssl només en fa servir tres (considera que les variants de l’AES_128_CCM no aporten res).
Si vol establir una sessió TLSv1.3 amb un servidor haurà de negociar el xifratge amb el servidor i esperar que li accepti algun d’aquest tres
Simplificació
Una manera de que un sistema sigui segur és simplificar, i una de les grans novetats de TLSv1.3 va ser que l’algorisme d’intercanvi de claus (Kx) i el d’autenticacació (Au) no formen part de la Cipher Suite perquè no formen part de la negociació entre client i servidor:
Per aquest motiu en TLSv1.3 els valor de Kx i Au és any:
|
Mac=AEAD
Mac=AEAD
Mac=AEADPer tant, l’únic que s’ha de negociar en TLSv1.3 és si fem servir AES_128, AES_256 o CHACHA20.
Compara aquesta simplicitat amb el protocol TLSv1.2:
|
Mac=AEAD
Mac=AEAD
Mac=AEADHi ha 19 implementacions de xifratges TLSv1.2:
| |
Connexió TLS
Una forma de depurar servei de xarxa és no fer servir una aplicació client i connectar-te de manera interactiva amb el client amb una eina com netcat.
Si vull saber si es pot accedir a un servei SSH o SMTP puc utilitzar netcat per connectar-me al port 22 o 25.
A continuació tens un exemple de connexió a un servei SMTP (port 25):
Tens que buscar a Google o ChatGPT com es fa exactament, però funcionar funciona, l’objectiu era parlar directament amb un servidor SMTP 😀.
Si coneixes el protocol SMTP pots interacturar amb el servidor amb comandes de text.
Pots fer servir netcat amb qualsevol protocol basat en text i interactuar amb ell de manera nativa.
Recorda! La sol.licitud HTTP acaba amb una línia en blanc. Per tant has d’apretar un altre cop ENTER per enviar la sol.licitut.
Però si la connexió està encriptada mitjançant TLS només rebràs dades binaries sense sentit o es produirà un error:
Hi ha variants de netcat, com la de nmap que poden gestionar connexions tls: https://nmap.org/ncat/.
Però nosaltres farem servir s_client per entendre com funciona una connexió TLS.
Connexió a un servei web
openssl et permet amb l’ordre s_client conectar-te a un servidor i interactuar amb ell a nivell de text.
Depuració
L’ordre s_client es va escriure per depurar connexions TLS.
Per tant, l’ordre s_client no fa gaire cas si rep un certificat que no és vàlid: l’accepta i continua.
depth=0
depth=0
Pots veure que openssl només t’informa que s’ha produït l’error num=18:self-signed certificate.
Faig servir el flag -quiet perquè no em mostri tota la informació de l’establiment de la connexió.
D’aquesta manera openssl silencia tot excepte un resum de la cadena de certificats.
En canvi, el comportament general de la majoria d’eines com curl és no acceptar un certificat que no està firmat per una autoritat de certificació:
Si vols el mateix comportament amb openssl utilitza el flag -verify_return_error:
depth=0
Fi de línia
En un text, com es marca una línia nova?
- Unix (i per tant Linux) van decidir que seria amb el caràcter invisible
LF(Line Feed) - Els Macs van decidir que seria amb el caràcter invisible
CR(Carriage Return), però després van passar ràpidament aLF. - Windows va decidir que tots dos a la vegada:
CR+LF.
I quina importància té això en TLS?
Doncs que molts protocols de serveis d’Internet fan servir text (“plain text”), i d’alguna manera s’ha de marcar el fi de línia.
Quan amb openssl et connectes amb l’argument -connect en un servei web, i escrius una ordre i apretes la tecla enter, openssl envia un caràcter LF.
Si el servidor espera un CR+LF això no funciona.
Per aquest motiu tens el flag -crlf per indicar a openssl que envii CR+LF enlloc de LF.
HTTP és un protocol que fa servir CR+LF per indicar una línia nova, ja que és l’estandard a Internet que es va especificar originalment en la RFC 158 com a part del protocol TELNET.
Aquesta convenció també la fant servir protocols com FTP i SMTP.
depth=2
depth=1
depth=0
El servidor respon inmediatament perquè no interpreta lf com una nova linia, i per tant, encara queda un tros de sol.licitud per enviar.
L’error unexpected eof while ... és perqué espera la directiva Host.
Per tant caldrà fer servir el flag -crlf quan et connectes a un servei HTTP que es estricte al respecte:
depth=2
depth=1
depth=0
Encara que moltes vegades no fa falta com havies vist fins ara:
depth=2
depth=1
depth=0
Port dedicat
Els serveis de xarxa comuns com ara web, correu electrònic i FTP escolten en uns ports dedicats.
HTTP
Per exemple el servei HTTP normalment és troba en el port 80.
La manera més senzilla de crear un versió segura d’aquest servei web és utilitzar una altre port on es fa servir TLS per establir una connexió segura entre client i servidor.
El servei protegit per TLS més conegut és HTTPS que escolta al port 443.
HTTP no sap res de TLS, i podem treballar i desenvolupar en HTTP sense ocupar-nos de TLS com hem estat fins ara quan arrequem un servei nginx o apache per fer proves i apendre.
POP3
POP3 és un protocol com HTTP que funciona amb text.
Per realitzar un connexió segura a un servei web POP3 pots conectar al port que fa servir TLS per encriptar la connexió.
Pots mirar quina és la contrasenya a Demonstration server — Mailu.
depth=2
depth=1
depth=0
També pots provar que passa amb gmail:
depth=2
depth=1
depth=0
No és un problema de contrasenya tal com pots veure en aquest article: Sign in with app passwords
Això és molt important, perqè a vegades una llibreria o una aplicació et diu que hi ha un error, però no et diu exactament quin.
Ordres de connexió
La sessió s_client roman oberta fins que la finalitzes.
Si no fas servir l’opció -quiet pots passar ordres a openssl:
Q (“quit”) tanca la connexió TLS de manera “neta” (millor que CTRL-C).
En canvi quan faig servir el flag -quiet no puc.
depth=2
depth=1
depth=0
Si vull puc passar l’ordre k a openssl perqué actualitzi la clau TLS 1.3:
Silenciant s_client
Com hem vist abans amb l’opció -quiet podem ometre tot el procés de negociació:
depth=2
depth=1
depth=0
Però si també vols veure un resum de les característiques TLS que s’han negociat, pots fer servir el flag -brief.
Versions específiques TLS
Quan un client TLS com s_client es connecta per primera vegada a un servidor, el client enumera les versions de TLS que admet, i el servidor tria la versió més alta que admet (la més segura).
Per provar un protocol determinat pots escollir la versió de TLS que vols fer servir-
En aquest exemple demanem al serviror utlitzar la versió TLSv1.2:
Pots veure que la llibreria OpenSSL que tenim instal.lada no implementa el protocol TLSv1.1, ni els protocols SSL que encara estan més obsolets:
Si volem provar el protocol TLSv1.1 tindrem que fer servir una versió antiga d’ubuntu que tingui una versió antiga de openssl.
La manera més fàcil és amb {% link “/linux/docker/” %}:
|
VERSION="14.04.6 LTS, Trusty Tahr"Ja podem realitzar una connexió TLSv1.1:
Pots verificar que la connexió fa servir el protocol TLSv1.1:
I la connexió funciona, puc fer sol.licituts HTTP:
Em puc connectar a www.google.com sense fer servir TLSv1.2:
Doncs si, han negociat fer servir TLSv1.1.
I sense TLSv1.2 i TLSv1.1 que passa?
Doncs llavors TLSv1.
I sense TLSv1.2,TLSv1.1 i TLSv1 que passa?
Que els servidor de Google no admeten els vells protocol SSL, però admeten tots els TLS.
Google necessita que clients antics, sobretot versions antigues d’Android, puguin seguir accedint als seus servidors.
Si tens un mòbil antic amb un Android antic és el teu problema (als clients no els importa tant la seguretat).
En canvi, els servidors de Microsoft són més restrictius:
Ja pots sortir del contenidor:
Selecció de xifratge
També et pot interessar és saber si un servidor pot utilitzar un xifratge específic.
Pots forçar a openssl que en la negociació amb el servidor només accepti un xifratge específic per veure si el servidor el té implementat.
Mira els “cipers” que té TLSv1.3:
|
Mac=AEAD
Mac=AEAD
Mac=AEADEn el protocol TLSv1.3, amb l’opció -ciphersuites pots forçar un protocol concret:
Aquí tens un altre exemple:
En el protocol TLSv1.2 l’opció és -cipher:
| |
Mac=AEAD
Mac=AEAD
Mac=AEAD
Mac=AEAD
Mac=AEAD
En l’exemple anterior has de forçar el protocol TLSv1.2, perquè sinò es negociarà fer servir el protocol TLSv1.3.
Però com hem explicat abans no tots els servidors ho admeten:
Negociació TLS
TLS és un protocol complicat, dissenyat per evolucionar, on cada servidor s’actualitza al seu ritme.
Per tant, quan un client es connecta a un servidor mitjançant TLS han de negociar quina versió de TLS faran servir, i quins algorismes faran servir.
Com qualsevol negociació cada part pot sol·licitar o exigir opcions de protocol específiques. El servidor i el client ofereixen els seus millors algorismes, presenten les seves peticions i demandes i intenten arribar a un acord.
Tant si fem servir TLS 1.2 com 1.3, veureu tres parts principals de la connexió: la validació del certificat, la configuració del protocol i la represa.
Validació del certificat
Cada negociació TLS comença validant tots els certificats implicats.
El certificat del host pot estar validat per un certificat arrel de confiança a través d’un arbre extens de validacions entre el certificat arrel i el del host.
openssl s’atura al primer camí vàlid que descobreix i és el que et presenta
depth=2
depth=1
depth=0
;
;
;
;
depth=0
- Pots veure que el certificat del host sempre es troba a
depth=0. - Aquest certificat autentica el host (
subject) ubuntu.com:s:CN = ubuntu.com - El
CNha de coincidir amb el nom del servidor al qual hem fet la connexió TLS.
Però com sabem que aquest certificat és autèntic?
- L’emissor del certificat (
issuer) és Let’s Encrypt:i:C = US, O = Let's Encrypt, CN = R3 - El certificat està firmat per Let’s Encrypt mitjantçant RSA:
a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256. - Com qualsevol certificat té una data de caducitat:
v:...; NotAfter: Jan 15 09:20:22 2024 GMT
depth=1
Com podem saber que la firma digital de Let’s Encrypt és autèncitca?
Perquè el servidor també ens mostra el certificat de ‘Let’s Encrypt’ que està firmat per ‘Internet Security Research Group’.
depth=3
Com podem saber que la firma digital de ‘Internet Security Research Group’ és autèncitca?
Perquè el servidor també ens mostra el certificat de ‘Internet Security Research Group’ que està firmat per ‘Digital Signature Trust Co’.
Autoritat certificadora
El servidor no envia el certificat de ‘Digital Signature Trust Co’.
No fa falta perquè ‘Internet Security Research Group’ és una autoritat certificadara ( CA: Certificate Authority) i el seu certificat el tenim nosaltres en la nostra distribució ubuntu en el fitxer /etc/ssl/certs/ca-certificates.crt.
Mirem totes les CA en format llegible:
|
subject=CN =
subject=C =
subject=C =
subject=serialNumber =
subject=C =
subject=C =
subject=C =
subject=C =
subject=C =
subject=C = Pots veure que aquest fitxer té una còpia el certificat de ‘Internet Security Research Group’:
|
subject=C =
subject=C = Com que openssl troba aquest certificat en la llista dels que confia, i verifica que la còpia del servidor és la mateixa que la còpia que te ell, valida el certificat.
Com que el certificat de depth=3 està validat, valida també la cadena de firmes digitals que arriben al certificat de depth=0.
Errors de certificat
Els principals motius pels quals falla una connexió TLS és perquè el client TLS no acceptarà un certificat.
Sovint el servidor no configura bé els certificats i el client té tota la raó per rebutjar certificats caducats, autofirmats, revocats i altres errors que fan que el certificat no sigui vàlid.
Per exemple, un error és que el servidor no ofereixi una cadena de certificats:
Si vols procedir de totes maneres pots fer-ho amb el flag -k:
Per conèixer exactament que està passant fem servir openssl:
depth=0
depth=0
depth=0
notAfter=May
notAfter=May
Pots veure que només hi ha un certificat i que presenta diversos problemes: no està firmat per una CA i està expirat.
Per defecte, openssl continua el procés de connexió encara que hi hagi problemes de certificat (el comportament contrari d’eines com curl).
Si vols que no es relitzi la connexió has de passar l’opció -verify_return_error com s’ha explicat abans:
depth=0
Clau compartida (K)
L’algorisme efímer de corba el·líptica Diffie-Hellman (ECDHE - Elliptic-curve Diffie-Hellman Ephemeral) es fa servir per generar una clau privada assimètrica a partir de dos valor númerics que s’intercanvien sense encriptar el client i el servidor, i que només poden utilitzar ell dos per derivar aquesta clau privada assimètrica.
Però per explicar com funciona, farem sevir RSA enlloc de curva elíptica:
El servidor ha generat un nombre primer P i una arrel primitiva de P, G, que qualsevol client pot demar al servidor.
En aquest enllaç pots obtenir les arrels primitives d’un nombre primer: Primitive Roots Calculator
El que fan servidor i client és:
-
El client genera un valor privat
a, a partir del qual genera el valorxque és el que envia al servidor. -
El servidor genera un valor privat
b, a partir del qual genera el valoryque és el que envia al client.
sequenceDiagram
Client->>Server: GET P, G
activate Server
Server->>Client: P = 97, G = 5
deactivate Server
Client-->Client: a = 33
Client->>Server: x = pow(G, a) % G = pow(97, 33) % 5 = 78
activate Server
Server-->Server: b = 8
Server->>Client: y = pow(G, b) % 97 = pow(97, 8) % 5 = 6
deactivate Server
Client-->>Client: k = pow(y,a) % P = 75
Client->>Server: missatge encriptat amb k
Server-->Server: k = pow(x,b) % P = 75
Aquí tens els càlculs amb Python:
Podem crear un programa en Python perquè ens calculi la clau privada k:
= 10007
= 3
=
= %
=
= %
= %
= %
No importa que P i G siguin coneguts, tampoc que x i y s’enviin sense xifrar.
Si P és un número molt gran és gairebé impossible d’adivinar quina pot ser la k a partir de x i y.
;
;
;
; En una connexió TLS la clau pública que envia el servidor és de 253 bits!
La Server Temp Key és fa servir per el que es coneix com Perfect Forward Secrecy.
X25519 és un tipus de corba i un algorisme per a l’acord de clau Elliptic Curve Diffie-Hellman Ephemeral (ECDHE)
El client generarà el seu propi parell de claus X25519 i enviarà la clau pública.
Servior i client faran servir aquestes claus ECDHE per generar una clau simètrica compartida que s’utilitzarà per protegir les dades en trànsit.
Configuració del protocol
A continuació, tenim la configuració acordada per a aquesta sessió TLS.
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384 | Pots veure que estem utilitzant TLS 1.3, amb el xifratgeTLS_AES_256_GCM_SHA384. Aquest xifratge utilitza AES de 256 bits amb mode Galois/Counter (GCM) per a l’encriptació i SHA384 per a MAC. |
Secure Renegotiation IS NOT supported | TLSv1.3 no admet Secure Renegotiation. |
Compression: NONE | TLSv1.3 tampoc adment la compressió de dades perquè posa en risc la confidencialitat i la integritat. |
No ALPN negotiated | La negociació de protocols de capa d’aplicació (ALPN) és un complement de TLS que permet a les aplicacions integrar la configuració de TLS a la resta de la configuració del seu protocol. S’utilitza a HTTP/2. Pots habilitar ALPN amb el flag -alpn |
Early data was not sent |
Compara aquesta configuració amb la que s’acorda en TLSv1.2:
Python
Per treballar amb Python:
- Instal.la {% link “/project/vscode/” %} al Windows.
- Instal.la {% link “/python/poetry/” %} a la màquina Linux, tanca el shell i torna a entrar.
Crea el projecte tls i obre’l amb code:
socket
El primer que farem es generar un certificat pel servidor:
CN és el nom de l’anfitrió.
Ara creem un servidor server.py:
=
, =
=
I el client que ha d’acceptar el certificat del servidor:
=
=
Pots veure que TLS és completament indiferent al protocol subjacent.
Es limitat a crear un wrapper al voltant del socket i enviar i rebre tot el que li passen, això sí, encriptat i protegit:
També ens podem connectar amb el client openssl:
depth=0
Com sempre openssl ens avisa que el certifcat està autofirmat i segueix fent.
Python fa servir la llibreria OpenSSL que tenim instal.lada al sistema operatiu. Per tant el resultat és l’esperat.
El que no li agrada és la resposta del servidor i peta 😅.
A continuació modificarem el client de tal forma que no accepti el certificat del servidor, i es produirà un error perquè el certificat és autofirmat.
És com si tu mateix et firmessis el DNI:
=
# context.load_verify_locations("cert.pem")
...La connexió no es pot establir.
HTTP
Un dels usos més habituals de TLS és per xifrar connexions HTTP.
Amb Python és molt fàcil arrencar un servidor http al port 8000 que escolta en totes les interficies disponibles de la màquina:
Des d’un altre terminal pots verure el contingut del sistema de fitxers:

O des del navegador:

Però com podem xifrar la connexió?
Doncs hem de fer un “wrap” del socket que fa servir http.server:
Crea el fitxer http-server.py:
=
=
=
Arrenca el servidor:
Conecta’t al servidor amb Lynx:
Podem veure que funciona (si acceptem el certificat autofirmat):

També pots veure que podem interactuar amb el servidor amb el client openssl:
depth=0
PostgreSQL
Crea una base de dades PostgreSQL tal com s’explica a {% link “/data/postgres/” %}:
Et pots conectar a la base de dades amb el shell:
postgres=# \l
| | | | | | | |
| | | | | | | |
| | | | | | | | =c/postgres
| | | | | | | | postgres=CTc/postgres
| | | | | | | | =c/postgres
| | | | | | | | postgres=CTc/postgres
()
postgres=# Per connectar-te a la base de dades faras servir l’adaptador postgres psycopg2 per a Python:
Crea l’script db.py:
=
= True
=
Pots veure que et pots connectar a la base de dades:
()TLS es pot aplicar a qualsevol protocol client-servidor, també a la conexió entre el nostre client i la base de dades PostgreSQL.
Modifica el fitxer db.py afegint l’opció sslmode='require' al crear la connexió:
= Tornar a executar l’script:
Ara es produeix un error en l’script perqué el nostre client només vol utilitzar una connexió TSL i el servidor contesta que no pots: server does not support SSL, but SSL was required.
Hem de crear uns certificats pel servidor postgres:
Ja podem parar el contenidor db i tornar a executar un altre contenidor amb l’opció ssl=on:
L’applicació db.py ja es pot connectar mitjançant una connexió xifrada TLS:
()Pots utilitzar el client openssl amb l’opció -starttls postgres per veure la connexió TLS:
depth=0
mTLS
TODO. Revisar
Mutual Transport Layer Security (mTLS) és un procés que estableix una connexió TLS xifrada en la qual ambdues parts utilitzen certificats digitals X.509 per autenticar-se mútuament.
Diguem l’Alícia i el Bobfer necessita una autenticació més forta. Potser estan tractant amb transferències financeres de gran valor o enviant informació sensible. Potser hi ha una bona probabilitat que un actor maliciós pugui robar la contrasenya d’Alice i ocupar el seu lloc. Bob pot voler onecessitat per comprovar criptogràficament que l’Alícia és realment qui diu que és. En aquest cas, potser voldrienmútuament autenticar-se mútuament. És a dir, l’Alice no només verifica la identitat d’en Bob, sinó que Bob també autentica la identitat d’Alice. A través del web, això es pot realitzar mitjançant certificats digitals i TLS mutus.

Autenticació bidireccional, o mútua, com es veu quan s’utilitza mTLS, en què tant el client (Alice) com el servidor (Bob) s’autentiquen mútuament.
mTLS no és un protocol nou. L’autenticació mútua forma part de l’estàndard TLS i ha format part de l’especificació des que es va anomenar Secure Sockets Layer (SSL). Qualsevol servidor web que utilitzi TLS per assegurar el seu trànsit hauria de ser capaç d’autenticar-se mútuament. Per tal d’implementar l’autenticació mútua, el servidor ha de demanar específicament al client el seu certificat, però, la majoria dels servidors web no estan configurats per fer-ho de manera predeterminada.
La següent figura mostra una versió simplificada d’una connexió TLS 1.2, coneguda com a “encaixada de mans”. La majoria de llocs web d’Internet salten els passos 4 i 5. Per als llocs i serveis que necessiten realitzar una autenticació mútua, el servidor, al pas 4, enviarà un missatge al client demanant-li que proporcioni un certificat (a més de dir-li de quines CA accepta certificats).

Passos durant una connexió de mans TLS 1.2 entre el client i el servidor quan es configura l’autenticació TLS mútua.
Entorns de malla de servei
Moltes aplicacions modernes utilitzen a arquitectura de microserveis que separa els components de l’aplicació en serveis discrets que s’executen en diversos servidors, sovint dins de contenidors. Per tal d’intercanviar dades i càlculs, aquests serveis s’han de comunicar a través de la xarxa. Compareu això amb les aplicacions monolítices tradicionals que realitzen tota la comunicació en memòria. Els entorns al núvol, amb una escala aparentment il·limitada i una automatització flexible, proporcionen un lloc ideal per desplegar aplicacions basades en microserveis i, tot i que el TLS estàndard pot xifrar la comunicació entre aquests microserveis, encara deixa oberta la possibilitat que algú manipuli qualsevol dels serveis.
L’ús d’una “malla de servei” permet als propietaris d’aplicacions governar el trànsit de servei a servei. Una malla de servei pot centralitzar la gestió dels microserveis i us permet controlar els dos extrems de la connexió, utilitzant mTLS per xifrar i autenticar les dades al cable.
La figura següent mostra les interaccions d’alt nivell de les sessions TLS autenticades mútuament en un entorn de malla de servei.

Entorns de malla de servei que utilitzen mTLS per xifrar i autenticar serveis.
Exemple
Anem a veure un exemple de mTLS d’ús del navegador web cURL (el client) per connectar-se a un servidor web Node.js (el servidor) que serveix al nom DNSlocalhost. Al fer-ho:
- El client validarà que el servidor és de confiança per oferir contingut per al nom DNSlocalhost
- El servidor validarà que el client és conegut, és a dir, l’autenticarà
El primer pas és crear una autoritat de certificació (CA) en la qual confien tant el client com el servidor. La CA és només una clau pública i privada amb la clau pública embolicada en un certificat X.509 autofirmat. L’ordre que fem servir per fer-ho és:
Això genera dos fitxers, ca.key i ca.crt,en el Format PEM (codificació base64 de la clau privada i del certificat X.509 respectivament).
Mirant la [ocumentació de openssl req documentació, veiem que:
- Les opcions
-newi-x509permeten la creació d’un certificat arrel CA X.509 autofirmat. - L’opció
-nodes(Sense DES) desactiva la seguretat de la clau privada amb una contrasenya; aquesta opció és opcional. - L’opció
-subjectproporciona la identitat de l’AC; en aquest cas el Nom Comú (NC) deel meu-ca. La resta d’opcions s’explica per si mateix.
Podem donar la volta i inspeccionar el certificat mitjançant l’ordre següent:
Les opcions aquí s’expliquen per si mateixes tal com es documenta a la pàgina openssl x509.
Mirant la sortida, podem confirmar una sèrie de coses:
-
Tant el
Issuercom elSubjecttenen elCN = xtec; això indica que aquest certificat està autofirmat. -
Validityindica que el certificat té una validesa d’un any. -
El valor
CA:TRUEdeX509v3 Basic Constraints: criticalindica que aquest certificat es pot utilitzar com a CA, és a dir, es pot utilitzar per signar certificats.
A continuació creem la clau i el certificat del servidor; començant per la clau:
Les opcions aquí s’expliquen per si mateixes tal com es documenta a openssl genrsa.
Recordeu que el nostre objectiu aquí és crear un certificat de servidor per al nom DNS localhost signat per la CA.
Ara creem una sol·licitud de signatura de certificat (CSR) amb el nom comú (CN)localhost:
Utilitzant la CSR, la CA (realment utilitzant la clau i el certificat de la CA) crea el certificat signat:
La sortida és el certificat del servidor signat, servidor.crt, en format PEM.
La majoria de les opcions són familiars (des de dalt) o s’expliquen per si mateixes, tal com es documenta a openssl x509.
L’única excepció és l’opció -CAcreateserial que gestiona un fitxer creat recentment, ca.srl, que permet que cada certificat creat per aquesta CA tingui un número de sèrie únic.
Com abans, inspeccionem el certificat mitjançant l’ordre següent:
Mirant la sortida, podem confirmar una sèrie de coses:
-
El
Issuerté el valorCN = xtecque és l’autoritat certificadora que firma aquest certificat. -
Validityindica que el certificat té una validesa d’un any. -
El
Subjecttè el valoraCN = localhost; això indica que aquest certificat es pot enviar a un client per validar que el servidor és de confiança per oferir contingut per al nom DNSlocalhost.
A continuació hem de crear una clau i un certificat pel client.
Començem per crear la clau del client:
Creem el CSR amb un nom comú arbitrari de client:
I finalment creem certificat del client:
Inspecciona aquest certificat i observa que el Serial Number és diferent del Serial Number del certificat del servidor:
|
|
Observació. Tant els certificats de servidor com de client són certificats X.509 v1 més simples; el certificat CA, però, és un certificat X.509 v3. Això es deu al fet que OpenSSL crea automàticament certificats autofirmats X.508 v3 (certificat CA) i no hem subministrat cap extensió v3 en signar els certificats de servidor i client (utilitzant elfitxer ext iextensions opcions).
Amb totes les nostres claus i certificats (ca, servidor i client) creats podem configurar el nostre servidor i client.