Ejecutar chequeos de SSL Labs desde CLI

La herramienta Qualys SSL Labs es sin duda de lo mejor que hay en Internet para auditar el estado de los servicios SSL/TLS y PKI de un servidor. Como es lógico, ejecutar la herramienta via web genera ciertas limitaciones, como por ejemplo la ejecución masiva o automatizada de tests. A través de la API y la herramienta ssllabs-scan podemos evitar estas restricciones.

Dependencias de ssllabs-scan

Esta herramienta de línea de comandos requiere la instalación de la versión 1.3 o superior de «go» (lenguaje de programación concurrente y compilado inspirado en la sintaxis de C). Podemos instalarlo de una forma muy sencilla. Revisad el enlace de descarga en función de vuestro SO y arquitectura:

# instalacion de GO
########################

# wget https://storage.googleapis.com/golang/go1.2.2.linux-amd64.tar.gz
# tar -xzvf go1.2.2.linux-amd64.tar.gz
# mv go/ /opt
# export PATH=$PATH:/opt/go/bin
# export GOROOT=/opt/go

Instalacion de SSLlabs scan CLI

Para instalar la herramienta, simplemente bajamos el proyecto de github y lo compilamos con go:

# wget https://github.com/ssllabs/ssllabs-scan/archive/stable.zip
# unzip stable.zip
# cd ssllabs-scan-stable/
# go build ssllabs-scan.go

Cómo usar ssllabs-scan CLI

Una vez compilado, el binario ssllabs-scan estará disponible en la misma ruta donde lo hemos compilado. La explicación de cada opción es lo suficientemente descriptiva en la ayuda como para entenderla.

# file ssllabs-scan
ssllabs-scan: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), not stripped

# ./ssllabs-scan  --help
Usage of ./ssllabs-scan:
  -api="BUILTIN": API entry point, for example https://www.example.com/api/
  -grade=false: Output only the hostname: grade
  -hostcheck=false: If true, host resolution failure will result in a fatal error.
  -hostfile="": File containing hosts to scan (one per line)
  -ignore-mismatch=false: If true, certificate hostname mismatch does not stop assessment.
  -insecure=false: Skip certificate validation. For use in development only. Do not use.
  -json-flat=false: Output results in flattened JSON format
  -maxage=0: Maximum acceptable age of cached results, in hours. A zero value is ignored.
  -quiet=false: Disable status messages (logging)
  -usecache=false: If true, accept cached results (if available), else force live scan.
  -verbosity="info": Configure log verbosity: error, notice, info, debug, or trace.
  -version=false: Print version and API location information and exit

El siguiente ejemplo hace un scan de https://google.com dejando todas las opciones por defecto. En el ejemplo no muestro todo el contenido del test:

# ./ssllabs-scan https://google.com
2016/07/03 18:21:15 [INFO] SSL Labs v1.23.46 (criteria version 2009l)
2016/07/03 18:21:15 [NOTICE] Server message: This assessment service is provided free of charge by Qualys SSL Labs, subject to our terms and conditions: https://www.ssllabs.com/about/terms.html
2016/07/03 18:21:18 [INFO] Assessment starting: https://google.com
2016/07/03 18:23:24 [INFO] Assessment complete: https://google.com (2 hosts in 123 seconds)
    216.58.194.174: B
    2607:f8b0:4005:804:0:0:0:200e: B
[
{
  "host": "https://google.com",
  "port": 443,
  "protocol": "HTTP",
  "isPublic": false,
  "status": "READY",
  "startTime": 1467562878309,
  "testTime": 1467563001943,
  "engineVersion": "1.23.46",
  "criteriaVersion": "2009l",
  "endpoints": [
    {
      "ipAddress": "216.58.194.174",
      "serverName": "sfo07s13-in-f14.1e100.net",
      "statusMessage": "Ready",
      "grade": "B",
      "gradeTrustIgnored": "B",
      "hasWarnings": false,
      "isExceptional": false,
      "progress": 100,
      "duration": 62523,
      "eta": 1,
      "delegation": 1,
      "details": {
        "hostStartTime": 1467562878309,
        "key": {
          "size": 256,
          "alg": "EC",
          "strength": 3072
        },
[...]

Si quisieramos hacer un escaneo masivo a un listado de hosts, podemos cargarlos a partir de un archivo de texto plano:

# ./ssllabs-scan -hostfile="./hosts.txt"

El resultado queda presentado en formato json, pudiendo elegir la opción -json-flat=true para que la salida sea plana en lugar de anidada:

# ./ssllabs-scan -json-flat=true https://google.com
2016/07/03 18:34:50 [INFO] SSL Labs v1.23.46 (criteria version 2009l)
2016/07/03 18:34:50 [NOTICE] Server message: This assessment service is provided free of charge by Qualys SSL Labs, subject to our terms and conditions: https://www.ssllabs.com/about/terms.html
2016/07/03 18:34:52 [INFO] Assessment starting: https://google.com
2016/07/03 18:34:53 [INFO] Assessment complete: https://google.com (2 hosts in 122 seconds)
    216.58.194.174: B
    2607:f8b0:4005:804:0:0:0:200e: B
["criteriaVersion": "2009l"
 "endpoints.0.delegation": 1
 "endpoints.0.details.cert.altNames.0": "*.google.com"
 "endpoints.0.details.cert.altNames.1": "*.android.com"
 "endpoints.0.details.cert.altNames.10": "*.google.com.ar"
 "endpoints.0.details.cert.altNames.11": "*.google.com.au"
 "endpoints.0.details.cert.altNames.12": "*.google.com.br"
 "endpoints.0.details.cert.altNames.13": "*.google.com.co"
 "endpoints.0.details.cert.altNames.14": "*.google.com.mx"
 "endpoints.0.details.cert.altNames.15": "*.google.com.tr"
 "endpoints.0.details.cert.altNames.16": "*.google.com.vn"
 "endpoints.0.details.cert.altNames.17": "*.google.de"
 "endpoints.0.details.cert.altNames.18": "*.google.es"
 "endpoints.0.details.cert.altNames.19": "*.google.fr"
 "endpoints.0.details.cert.altNames.2": "*.appengine.google.com"
 "endpoints.0.details.cert.altNames.20": "*.google.hu"
 "endpoints.0.details.cert.altNames.21": "*.google.it"
 "endpoints.0.details.cert.altNames.22": "*.google.nl"
 "endpoints.0.details.cert.altNames.23": "*.google.pl"
 "endpoints.0.details.cert.altNames.24": "*.google.pt"
 "endpoints.0.details.cert.altNames.25": "*.googleadapis.com"
 "endpoints.0.details.cert.altNames.26": "*.googleapis.cn"
 "endpoints.0.details.cert.altNames.27": "*.googlecommerce.com"
 "endpoints.0.details.cert.altNames.28": "*.googlevideo.com"
 "endpoints.0.details.cert.altNames.29": "*.gstatic.cn"
 "endpoints.0.details.cert.altNames.3": "*.cloud.google.com"
 "endpoints.0.details.cert.altNames.30": "*.gstatic.com"
 "endpoints.0.details.cert.altNames.31": "*.gvt1.com"
 "endpoints.0.details.cert.altNames.32": "*.gvt2.com"
 "endpoints.0.details.cert.altNames.33": "*.metric.gstatic.com"
 "endpoints.0.details.cert.altNames.34": "*.urchin.com"
 "endpoints.0.details.cert.altNames.35": "*.url.google.com"
[...]