Obtenez le certificat SSL / TLS d'un serveur en utilisant «openssl s_client»

17

J'essaie d'obtenir le certificat SSL / TLS pour l'un de nos équilibreurs de charge (Netscaler) en utilisant:

openssl s_client -showcerts -connect lb.example.com:443

Mais il ne me montrera pas le certificat:

CONNECTED(00000003)
write:errno=54

L'utilisation -servername lb.example.comn'aide pas, et notre administrateur système m'a dit que nos équilibreurs de charge n'utilisaient pas SNI de toute façon.

Edit : le serveur est sur notre intranet et n'accepte pas les connexions de l'Internet public. C'est la sortie de openssl avec -debug:

CONNECTED(00000003)
write to 0x7fec7af0abf0 [0x7fec7b803a00] (130 bytes => 130 (0x82))
0000 - 80 80 01 03 01 00 57 00-00 00 20 00 00 39 00 00   ......W... ..9..
0010 - 38 00 00 35 00 00 16 00-00 13 00 00 0a 07 00 c0   8..5............
0020 - 00 00 33 00 00 32 00 00-2f 00 00 9a 00 00 99 00   ..3..2../.......
0030 - 00 96 03 00 80 00 00 05-00 00 04 01 00 80 00 00   ................
0040 - 15 00 00 12 00 00 09 06-00 40 00 00 14 00 00 11   .........@......
0050 - 00 00 08 00 00 06 04 00-80 00 00 03 02 00 80 00   ................
0060 - 00 ff a6 f7 27 1a a7 18-85 cf b2 03 22 fc 48 3d   ....'.......".H=
0070 - dd a9 2c b7 76 67 62 80-df 85 ed 48 35 c7 d4 87   ..,.vgb....H5...
0080 - 8d d3                                             ..
read from 0x7fec7af0abf0 [0x7fec7b809000] (7 bytes => -1 (0xFFFFFFFFFFFFFFFF))
write:errno=54

Et ceci est la sortie pertinente de curl -v https://lb.example.com/:

$ curl -vI https://lb.exmple.com/
*   Trying 1.2.3.4...
* Connected to lb.exmple.com (10.1.2.3) port 443 (#0)
* TLS 1.2 connection using TLS_RSA_WITH_AES_256_CBC_SHA
* Server certificate: lb.example.com
* Server certificate: RapidSSL SHA256 CA - G2
* Server certificate: GeoTrust Primary Certification Authority - G3
> HEAD / HTTP/1.1
> Host: lb.exmple.com
> User-Agent: curl/7.43.0
> Accept: */*
>

Des suggestions sur la façon d'obtenir le certificat à l'aide de openssl s_client?

Daniel Serodio
la source
2
Vous le faites correctement. Mais sur la base des informations actuelles, il est impossible de dire ce qui ne va pas: peut-être un pare-feu bloquant la négociation TLS, peut-être un problème de protocole TLS .... Il peut être utile de fournir l'URL (publique) que vous essayez d'utiliser comme cible ou d'ajouter la sortie de débogage complète (option -debug) à votre question.
Steffen Ullrich
Comme @SteffenUllrich l'a dit, cela pourrait être TLS. Voir openssl même erreur - solution possible ici .
Zina

Réponses:

21

Après un certain temps, je l'ai compris: cet équilibreur de charge particulier a été configuré pour utiliser uniquement TLSv1.2, que la version d'openssl incluse dans OS X (0.9.8) ne comprend pas. J'ai installé une version plus récente de openssl (> = 1.0.1) en utilisant homebrew donc cela fonctionne:

/usr/local/opt/openssl/bin/openssl s_client -showcerts -connect lb.example.com:443
Daniel Serodio
la source
3

J'essaie d'obtenir le certificat SSL / TLS pour l'un de nos équilibreurs de charge (Netscaler) en utilisant:

 openssl s_client -showcerts -connect lb.example.com:443

Si c'est une configuration moderne (certains renoncent à ce que cela signifie), utilisez:

openssl s_client -connect lb.example.com:443 -tls1 -servername lb.example.com | \
openssl x509 -text -noout

CONNECTED(00000003)
write to 0x7fec7af0abf0 [0x7fec7b803a00] (130 bytes => 130 (0x82))
0000 - 80 80 01 03 01 00 57 00-00 00 20 00 00 39 00 00
...

Il semble qu'il y ait un préambule supplémentaire aux octets 0 et 1. À l'octet 2, il devrait y avoir un type d'enregistrement. Aux octets 3 et 4, il devrait y avoir un numéro de version. Les octets 5 et 6 doivent avoir une longueur de 16 bits de la charge utile.

Voici un exemple de travail:

$ openssl s_client -connect www.googl.com:443 -tls1 -servername www.googl.com -debug
CONNECTED(00000005)
write to 0x7f7fe1c1fa30 [0x7f7fe2022000] (132 bytes => 132 (0x84))
0000 - 16 03 01 00 7f 01 00 00-7b 03 01 71 c0 12 35 98
...

D'en haut, le type d'enregistrement est à la position 0 et sa valeur est 0x16. 0x16 est le type de poignée de main. La version de la couche d'enregistrement est les deux octets suivants aux positions 2 et 3. Leurs valeurs sont 0x03 0x01. La longueur de la charge utile est 0x007f.

Voir également RFC 5246, le protocole TLS (Transport Layer Security) version 1.2 , page 18:

6.2.1.  Fragmentation

   The record layer fragments information blocks into TLSPlaintext
   records carrying data in chunks of 2^14 bytes or less.  Client
   message boundaries are not preserved in the record layer (i.e.,
   multiple client messages of the same ContentType MAY be coalesced
   into a single TLSPlaintext record, or a single message MAY be
   fragmented across several records).

      struct {
          uint8 major;
          uint8 minor;
      } ProtocolVersion;

      enum {
          change_cipher_spec(20), alert(21), handshake(22),
          application_data(23), (255)
      } ContentType;

      struct {
          ContentType type;
          ProtocolVersion version;
          uint16 length;
          opaque fragment[TLSPlaintext.length];
      } TLSPlaintext;

Votre problème pourrait être l'ancien type d'enregistrement compatible SSLv2. Ou ce pourrait être une version de bas niveau d'OpenSSL, disons 0.9.5 ou 0.9.8. C'est difficile à dire, et nous avons probablement besoin de plus d'informations.

Plus d'informations comprendraient OS; Version OpenSSL; si vous avez tenté de remplacer la version d'OpenSSL de la plate-forme par votre propre version d'OpenSSL; s'il y a un pare-feu ou une boîte «Web inspect» ou un autre logiciel intermédiaire en cours d'exécution; et ce que le serveur reçoit.


L'utilisation -servername lb.example.comn'aide pas, et notre administrateur système m'a dit que nos équilibreurs de charge n'utilisaient pas SNI de toute façon.

Cela semble plutôt inhabituel. Mais c'est une extension de TLS, donc elle est ignorée si elle n'est pas utilisée (et ne produira pas d'alerte fatale).

La règle d'or en 2016: utilisez toujours TLS 1.0 ou supérieur et utilisez toujours SNI.

jww
la source