Node-Red Problemas-Renovar-Certificado-Ssl

Para no variar otra vez me da problemas la renovacion de certificados.
Esta vez son los certificados de la red de sensores/honeypots.

Los analisis de la red los hago en node-red. y para publicarlos de foma segura hace poco le añadi un certificado.


Error Al renovar el certificado de un servidor certbot renew

Certbot Avisa 30dias antes de vayan ha caducar los certificados.
Si la renovacion de certificados es automatica y funciona correctamente.
Luego no deberia haberme llegado el aviso.




Indice:

Problema1
Bateria de pruebas para acotar el problema)

Solucion Problema1

Problema2
Solucion Problema2

Apendice1 Salida servidor Web
Apendice2 Comprobar certificados desde linea de comandos

Notas
Referencias




Problema1

root@serv1:/etc/letsencrypt/live# certbot renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/serv1.jejo.es.conf
-------------------------------------------------------------------------------
Cert is due for renewal, auto-renewing...
Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for serv1.jejo.es
Waiting for verification...
Cleaning up challenges
Attempting to renew cert from /etc/letsencrypt/renewal/serv1.jejo.es.conf 
produced an unexpected error: Failed authorization procedure. serv1.jejo.es 
(http-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: 
Fetching http://serv1.jejo.es/.well-known/acme-challenge/XXXX: Connection refused. Skipping.

All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/serv1.jejo.es/fullchain.pem (failure)
1 renew failure(s), 0 parse failure(s)

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: serv1.jejo.es
   Type:   connection
   Detail: Fetching
   http://serv1.jejo.es/.well-known/acme-challenge/XXXX:
   Connection refused

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A record(s) for that domain
   contain(s) the right IP address. Additionally, please check that
   your computer has a publicly routable IP address and that no
   firewalls are preventing the server from communicating with the
   client. If you're using the webroot plugin, you should also verify
   that you are serving files from the webroot path you provided.

Al renovar el certificado a mano por linea de comandos.
vemos que hay un problema al renovar.




Comencemos con la Bateria de Pruebas
Para acotar el problema:

Hay muchos articulos (aunque en ingles) que explican como crear certificados.
Pero hay menos articulos que den un metodologia de pruebas cuando los certificados fallan.

  • Prueba1: Haciendo un tcpdum no veo trafico

    tcpdump -lnnA -s256 "(inbound and dst port 80)or(outbound and src port 80)"

    root@serv1:~# tcpdump -lnnA -s256 "(inbound and dst port 80)or(outbound and src port 80)"
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on venet0, link-type LINUX_SLL (Linux cooked), capture size 256 bytes
    

  • Prueba2: curl desde un ordenador externo: Observo que no hay conexion con el puerto 80(http)

    curl -kvs http://serv1.jejo.es/.well-known/acme-challenge/XXXX

    jejo@em50l:/$ curl -kvs http://serv1.jejo.es/.well-known/acme-challenge/XXXX
    *   Trying 95.46.198.26...
    * TCP_NODELAY set
    * connect to 95.46.198.26 port 80 failed: Conexión rehusada
    * Failed to connect to serv1.jejo.es port 80: Conexión rehusada
    * Closing connection 0
    

  • Prueba3: Compruebo que el puerto 80 no esta bloqueado por otro programa.

    ss -natolup |grep 80 || echo puerto 80 libre




  • Prueba4: Lanzo un servidor web python en el puerto 80 y pruebo distintas formas de conectarme.

    python3 -m http.server 80

    root@serv1:/etc/letsencrypt/live# python3 -m http.server 80
    Serving HTTP on 0.0.0.0 port 80 ...
    

  • Pruebo conectarme al servidor con la url de letsencript de varias formas.

    • Prueba4.1: Desde el propio servidor (localhost) (funciona)
      root@serv1:~# curl -kvs http://localhost/.well-known/acme-challenge/
      * Connected to localhost (127.0.0.1) port 80 (#0)
      > GET /.well-known/acme-challenge/ HTTP/1.1
      > User-Agent: curl/7.38.0
      > Host: localhost
      > Accept: **
      > 
      * HTTP 1.0, assume close after body
      < HTTP/1.0 404 File not found
      < Server: SimpleHTTP/0.6 Python/3.4.2
      

    • Prueba4.2: Desde el propio servidor (usando su nombre) (funciona)
      root@serv1:~# curl -kvs http://serv1.jejo.es/.well-known/acme-challenge/
      * Connected to serv1.jejo.es (192.168.1.105) port 80 (#0)
      > GET /.well-known/acme-challenge/ HTTP/1.1
      > User-Agent: curl/7.38.0
      > Host: serv1.jejo.es
      > Accept: **
      > 
      * HTTP 1.0, assume close after body
      < HTTP/1.0 404 File not found
      < Server: SimpleHTTP/0.6 Python/3.4.2
      

    • Prueba4.3: Desde VPN (funciona)
      jejo@em50l:~# curl -kvs http://10.8.0.1/.well-known/acme-challenge/
      * Connected to 10.8.0.1 (10.8.0.1) port 80 (#0)
      > GET /.well-known/acme-challenge/ HTTP/1.1
      > User-Agent: curl/7.58.0
      > Host: 10.8.0.1
      > Accept: **
      > 
      * HTTP 1.0, assume close after body
      < HTTP/1.0 404 File not found
      < Server: SimpleHTTP/0.6 Python/3.4.2
      

    • Prueba4.4: Desde IPV6 en local (NO funciona)
      curl -kvs http://[::1]/.well-known/acme-challenge/

    • Prueba4.5: Desde IPV6 desde fuera (NO funciona)
      curl -kvs http://[2a00:1630:6:6::2]/.well-known/acme-challenge/




    ¿Es posible que el servidor web python solo escuche en ipv4? En efecto:

    root@serv1:~# netstat -putonl
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name Timer
    tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      4687/python3     off (0.00/0/0)
    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      298/sshd         off (0.00/0/0)
    tcp6       0      0 :::22                   :::*                    LISTEN      298/sshd         off (0.00/0/0)
    

    Como se ve el servicio ssh esta en ip4 y en ip6 pero el python3 solo en ip4
    Descarto pruebas Ipv6




    Conclusiones de las pruebas.

    Parece que las conexiones HTTP no entran al puerto 80
    Es una maquina NAT luego no serviria hacer una prueba TCP al puerto 80.




    Investigando con el panel vps

    me doy cuenta de que han desaparecido los proxy-domains.
    El problema es del anfitrion. Mal asunto….




    Solucion: Problema1

    Para renovar este dominio (mientras no solucionan lo de la redireccion de dominios via proxy en panel) Tendre que usar un metodo para renivar el certificado que no use el puerto 80
    Por ejemplo el metodo DNS-challenge

    Pero esto ya daria para otro articulo.




    Apendice1 Salida servidor WEB

    Aqui esta la salida del servidor web en el que se ven las 4 peticiones que han entrado.

    root@serv1:/etc/letsencrypt/live# python3 -m http.server 80
    Serving HTTP on 0.0.0.0 port 80 ...
    127.0.0.1 - - [08/Dec/2019 13:02:40] code 404, message File not found
    127.0.0.1 - - [08/Dec/2019 13:02:40] "GET /.well-known/acme-challenge/ HTTP/1.1" 404 -
    192.168.1.105 - - [08/Dec/2019 13:01:13] code 404, message File not found
    192.168.1.105 - - [08/Dec/2019 13:01:13] "GET /.well-known/acme-challenge/ HTTP/1.1" 404 -
    10.8.0.2 - - [08/Dec/2019 13:06:12] code 404, message File not found
    10.8.0.2 - - [08/Dec/2019 13:06:12] "GET /.well-known/acme-challenge/ HTTP/1.1" 404 -
    



    Apendice2 Comprobar certificado desde linea de comandos

    Leyendo las cabeceras del comando curl se puede obtener info de un certificado.

    • Con el comando curl -kvs
      curl -kvs https://serv1.jejo.es
      * successfully set certificate verify locations:
      *   CAfile: /etc/ssl/certs/ca-certificates.crt
      * Server certificate:
      *  subject: CN=ne.jejo.es
      *  start date: Sep 28 16:30:14 2019 GMT
      *  expire date: Dec 27 16:30:14 2019 GMT
      *  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
      

    • Con el comando openssl
      openssl s_client -showcerts -connect serv1.jejo.es:10520
      CONNECTED(00000005)
      depth=0 CN = serv1.jejo.es
      verify error:num=20:unable to get local issuer certificate
      verify return:1
      depth=0 CN = serv1.jejo.es
      verify error:num=21:unable to verify the first certificate
      verify return:1
      ---
      Certificate chain
       0 s:CN = serv1.jejo.es
         i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
      -----BEGIN CERTIFICATE-----
      MIIFTTCCBDWgAwIBAgISA6Q86RcjT3lCyxZd+f6eTL8SMA0GCSqGSIb3DQEBCwUA
      MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
      ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xOTA5MjgxNjMwMTRaFw0x
      OTEyMjcxNjMwMTRaMBUxEzARBgNVBAMTCm5lLmplam8uZXMwggEiMA0GCSqGSIb3
      ZEmlJdlIVdpaS9QIjmnGa/0=
      -----END CERTIFICATE-----
      ---
      Server certificate
      subject=CN = serv1.jejo.es
      
      issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
      
      ---
      No client certificate CA names sent
      Peer signing digest: SHA512
      Peer signature type: RSA
      Server Temp Key: ECDH, P-256, 256 bits
      ---
      SSL handshake has read 2063 bytes and written 438 bytes
      Verification error: unable to verify the first certificate
      ---
      New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
      Server public key is 2048 bit
      Secure Renegotiation IS supported
      Compression: NONE
      Expansion: NONE
      No ALPN negotiated
      SSL-Session:
          Protocol  : TLSv1.2
          Cipher    : ECDHE-RSA-AES128-GCM-SHA256
          Session-ID: 3C0DBD639C81838
          Session-ID-ctx: 
          Master-Key: 8D27265542AD452
          PSK identity: None
          PSK identity hint: None
          SRP username: None
          TLS session ticket lifetime hint: 300 (seconds)
          TLS session ticket:
          0000 - 79 31 83 77 b3 1e 5f ff-e1 c4 1a 22 ac 2a 5c e7   y1.w.._....".*\.
          0010 - 80 4f 17 63 49 d6 c6 e6-e8 f4 e4 19 db 7e 39 f6   .O.cI........~9.
          00b0 - 75 94 21 23 30 c3 77 06-77 fe 4d 28 e7 7d d4 f6   u.!#0.w.w.M(.}..
          00c0 - 96 cf 4d cb 60 34 f1 2d-88 a4 06 74 ce b0 5b 33   ..M.`4.-...t..[3
      
          Start Time: 1575819798
          Timeout   : 7200 (sec)
          Verify return code: 21 (unable to verify the first certificate)
          Extended master secret: no
      ---
      



    Problema2

    root@serv2:~# certbot renew
    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    
    -------------------------------------------------------------------------------
    Processing /etc/letsencrypt/renewal/sg.jejo.es.conf
    -------------------------------------------------------------------------------
    Cert is due for renewal, auto-renewing...
    Could not choose appropriate plugin: The manual plugin is not working; there may be problems with your existing configuration.
    The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',)
    Attempting to renew cert from /etc/letsencrypt/renewal/sg.jejo.es.conf produced an unexpected error: The manual plugin is not working; there may be problems with your existing configuration.
    The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',). Skipping.
    
    All renewal attempts failed. The following certs could not be renewed:
      /etc/letsencrypt/live/sg.jejo.es/fullchain.pem (failure)
    1 renew failure(s), 0 parse failure(s)
    



    Solucion: Problema2

    Esta es mas facil
    certbot renew -v --standalone

    root@serv2:~# certbot renew -v --standalone                
    Root logging level set at 10
    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    certbot version: 0.10.2
    Arguments: ['-v', '--standalone']
    
    -------------------------------------------------------------------------------
    Processing /etc/letsencrypt/renewal/serv2.jejo.es.conf
    -------------------------------------------------------------------------------
    Should renew, less than 30 days before certificate expiry 2019-12-27 09:20:37 UTC.
    Cert is due for renewal, auto-renewing...
    
    
    Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
    "GET /directory HTTP/1.1" 200 658
    "POST /acme/chall-v3/1617607204/n-kB8A HTTP/1.1" 202 298
    "GET /acme/authz-v3/1617607204 HTTP/1.1" 200 1214
    "POST /acme/new-cert HTTP/1.1" 201 1359
    "GET /acme/issuer-cert HTTP/1.1" 200 1174
    
    
    Writing new private key to /etc/letsencrypt/archive/serv2.jejo.es/privkey2.pem.
    Writing certificate to /etc/letsencrypt/archive/serv2.jejo.es/cert2.pem.
    Writing chain to /etc/letsencrypt/archive/serv2.jejo.es/chain2.pem.
    Writing full chain to /etc/letsencrypt/archive/serv2.jejo.es/fullchain2.pem.
    Writing new config /etc/letsencrypt/renewal/serv2.jejo.es.conf.new.
    
    -------------------------------------------------------------------------------
    new certificate deployed without reload, fullchain is
    /etc/letsencrypt/live/serv2.jejo.es/fullchain.pem
    -------------------------------------------------------------------------------
    
    Congratulations, all renewals succeeded. The following certs have been renewed:
      /etc/letsencrypt/live/serv2.jejo.es/fullchain.pem (success)
    no renewal failures
    

    OK CERTIFICADO RENOVADO




    Apendice: Comprobar el nivel de seguridad SSL TLS de un certificado/servidor.

    https://www.ssllabs.com/ssltest https://www.ssllabs.com/ssltest/analyze.html?d=jejo.es https://www.sslshopper.com/ssl-checker.html?host=jejo.es#hostname=jejo.es




    Apendice: comprobar historial de certificados para un dominio.

    https://crt.sh/