[SOLVED] SSL: UNKNOWN_PROTOCOL error

I have a custom ACME client, written in Python - https://github.com/ipilcher/acme/blob/master/le-update-cert.

This was working fine until a couple of days ago. Now I’m getting an “unknown protocol” error when creating the acme.client.Client.

[root@asterisk system]# le-update-cert --production --debug --tty www.penurio.us
Updating certificate for www.penurio.us                                                                                                                                                                                                          
  certificate file: /var/lib/acme/www.penurio.us.crt                                                                                                                                                                                             
  new certificate symlink: /var/lib/acme/www.penurio.us.new                                                                                                                                                                                      
  CSR file: /etc/acme/www.penurio.us.csr                                                                                                                                                                                                         
  client key file: /etc/acme/client.key                                                                                                                                                                                                          
  ACME URL: https://acme-v01.api.letsencrypt.org/directory                                                                                                                                                                                       
  ACME challenge directory: /var/www/acme-challenge                                                                                                                                                                                              
Loaded client key from /etc/acme/client.key                                                                                                                                                                                                      
Traceback (most recent call last):                                                                                                                                                                                                               
  File "/usr/local/bin/le-update-cert", line 99, in <module>                                                                                                                                                                                     
    acme_client = client.Client(ACME_URL, client_key)                                                                                                                                                                                            
  File "/usr/lib/python2.7/site-packages/acme/client.py", line 267, in __init__                                                                                                                                                                  
    net.get(directory).json())                                                                                                                                                                                                                   
  File "/usr/lib/python2.7/site-packages/acme/client.py", line 1041, in get                                                                                                                                                                      
    self._send_request('GET', url, **kwargs), content_type=content_type)                                                                                                                                                                         
  File "/usr/lib/python2.7/site-packages/acme/client.py", line 990, in _send_request                                                                                                                                                             
    response = self.session.request(method, url, *args, **kwargs)                                                                                                                                                                                
  File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 464, in request                                                                                                                                                             
    resp = self.send(prep, **send_kwargs)                                                                                                                                                                                                        
  File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 576, in send                                                                                                                                                                
    r = adapter.send(request, **kwargs)                                                                                                                                                                                                          
  File "/usr/lib/python2.7/site-packages/requests/adapters.py", line 431, in send                                                                                                                                                                
    raise SSLError(e, request=request)                                                                                                                                                                                                           
requests.exceptions.SSLError: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:579)

Anyone have any idea what’s going on?

Can you access https://acme-v01.api.letsencrypt.org/directory with curl or wget? Python? If the system supports IPv6, does it work?

Interesting.

Here is the output on my workstation (Fedora 28):

[pilcher@ian ~]$ curl -v https://acme-v01.api.letsencrypt.org/directory
*   Trying 104.72.45.24...
* TCP_NODELAY set
* Connected to acme-v01.api.letsencrypt.org (104.72.45.24) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
  CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: CN=acme-v02.api.letsencrypt.org
*  start date: Mar 16 00:14:19 2018 GMT
*  expire date: Jun 14 00:14:19 2018 GMT
*  subjectAltName: host "acme-v01.api.letsencrypt.org" matched cert's "acme-v01.api.letsencrypt.org"
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
> GET /directory HTTP/1.1
> Host: acme-v01.api.letsencrypt.org
> User-Agent: curl/7.59.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: nginx
< Content-Type: application/json
< Content-Length: 658
< Replay-Nonce: W0Oyj3rwB3kwx9eubojmleTVC6wnpb6Zhm_jg3y-Pmo
< X-Frame-Options: DENY
< Strict-Transport-Security: max-age=604800
< Expires: Fri, 18 May 2018 16:11:49 GMT
< Cache-Control: max-age=0, no-cache, no-store
< Pragma: no-cache
< Date: Fri, 18 May 2018 16:11:49 GMT
< Connection: keep-alive
< 
{
  "key-change": "https://acme-v01.api.letsencrypt.org/acme/key-change",
  "meta": {
    "caaIdentities": [
      "letsencrypt.org"
    ],
    "terms-of-service": "https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf",
    "website": "https://letsencrypt.org"
  },
  "new-authz": "https://acme-v01.api.letsencrypt.org/acme/new-authz",
  "new-cert": "https://acme-v01.api.letsencrypt.org/acme/new-cert",
  "new-reg": "https://acme-v01.api.letsencrypt.org/acme/new-reg",
  "osfh7DXN9Ic": "https://community.letsencrypt.org/t/adding-random-entries-to-the-directory/33417",
  "revoke-cert": "https://acme-v01.api.letsencrypt.org/acme/revoke-cert"
* Connection #0 to host acme-v01.api.letsencrypt.org left intact
}

And here is the output on my server (where the renewal runs):

[root@asterisk system]# curl -v https://acme-v01.api.letsencrypt.org/directory
* About to connect() to acme-v01.api.letsencrypt.org port 443 (#0)
*   Trying 23.207.56.130...
* Connected to acme-v01.api.letsencrypt.org (23.207.56.130) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* NSS error -12188 (SSL_ERROR_INTERNAL_ERROR_ALERT)
* Peer reports it experienced an internal error.
* Closing connection 0
curl: (35) Peer reports it experienced an internal error.

Note the different IP addresses.

It uses a CDN, so it has a lot of IP addresses, and it's normal for them to be different.

On the other hand, while 23.207.56.130 is one of the CDN company's IPs...

$ curl -v --compressed --resolve acme-v01.api.letsencrypt.org:443:23.207.56.130 https://acme-v01.api.letsencrypt.org/directory |& less
* Added acme-v01.api.letsencrypt.org:443:23.207.56.130 to DNS cache
* Hostname acme-v01.api.letsencrypt.org was found in DNS cache
*   Trying 23.207.56.130...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
^M  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to acme-v01.api.letsencrypt.org (23.207.56.130) port 443 (#0)
* found 148 certificates in /etc/ssl/certs/ca-certificates.crt
* found 592 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* gnutls_handshake() failed: Internal error
^M  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
* Closing connection 0
curl: (35) gnutls_handshake() failed: Internal error

Can you check if it's in /etc/hosts, and, if so, remove it?

2 Likes

Can you check if it’s in /etc/hosts, and, if so, remove it?

That was it! :exploding_head:

I have no idea why that was there. (I can only assume that I was having DNS problems at some point and added it as a workaround.)

Thanks & sorry for the noise!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.