web-dev-qa-db-fra.com

Obtenir un certificat SSL / TLS d'un serveur en utilisant "openssl s_client"

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

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

Mais cela ne me montrera pas le certificat:

CONNECTED(00000003)
write:errno=54

Utiliser -servername lb.example.com n'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 à partir de l’Internet public. Voici 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 voici le résultat pertinent 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: */*
>

Avez-vous des suggestions pour obtenir le certificat en utilisant openssl s_client?

15
Daniel Serodio

Après un moment, je l'ai compris: cet équilibreur de charge particulier a été configuré pour utiliser uniquement TLSv1.2, ce que la version d'OpenSl 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
19
Daniel Serodio

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

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

Si sa configuration est moderne (une main sur 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 y avoir 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 correspond aux 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, 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 bien il pourrait s'agir d'une version de niveau inférieur d'OpenSSL à partir de 0.9.5 ou 0.9.8. C'est difficile à dire, et nous avons probablement besoin de plus d'informations.

Plus d'informations incluraient le système d'exploitation; 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 une autre qualité de middleware en cours d'exécution; et ce que le serveur reçoit.


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

Cela semble un peu inhabituel. Mais c'est une extension de TLS, donc il est ignoré s'il n'est pas utilisé (et ne produira pas d'alerte fatale).

La règle empirique en 2016: utilisez toujours TLS 1.0 ou supérieur, et utilisez toujours SNI.

2
jww