SSLError: [X509] PEM lib (_ssl.c:2831)

Hi, I am getting SSLError: [X509] PEM lib (_ssl.c:2831) error.

I am trying to renew certificate.

This is from error log:

2017-01-17 15:05:14,605:DEBUG:letsencrypt.cli:Root logging level set at 30
2017-01-17 15:05:14,606:INFO:letsencrypt.cli:Saving debug log to /var/log/letsencrypt/letsencrypt.log
2017-01-17 15:05:14,606:DEBUG:letsencrypt.cli:letsencrypt version: 0.4.1
2017-01-17 15:05:14,606:DEBUG:letsencrypt.cli:Arguments: ['-a', 'webroot', '--webroot-path', '/srv/www/vhosts/my-domain.com/AsyncWebFrontend/htdocs', '-d', 'my-domain.com', '-d', 'www.my-domain.com', '-d', 'sk.my-domain.com', '-d', 'de.my-domain.com']
2017-01-17 15:05:14,607:DEBUG:letsencrypt.cli:Discovered plugins: PluginsRegistry(PluginEntryPoint#webroot,PluginEntryPoint#null,PluginEntryPoint#manual,PluginEntryPoint#standalone)
2017-01-17 15:05:14,609:DEBUG:letsencrypt.cli:Requested authenticator webroot and installer None
2017-01-17 15:05:14,609:DEBUG:letsencrypt.plugins.webroot:Creating root challenges validation dir at /srv/www/vhosts/my-domain.com/AsyncWebFrontend/htdocs/.well-known/acme-challenge
2017-01-17 15:05:14,610:DEBUG:letsencrypt.plugins.webroot:Creating root challenges validation dir at /srv/www/vhosts/my-domain.com/AsyncWebFrontend/htdocs/.well-known/acme-challenge
2017-01-17 15:05:14,610:DEBUG:letsencrypt.plugins.webroot:Creating root challenges validation dir at /srv/www/vhosts/my-domain.com/AsyncWebFrontend/htdocs/.well-known/acme-challenge
2017-01-17 15:05:14,610:DEBUG:letsencrypt.plugins.webroot:Creating root challenges validation dir at /srv/www/vhosts/my-domain.com/AsyncWebFrontend/htdocs/.well-known/acme-challenge
2017-01-17 15:05:14,610:DEBUG:letsencrypt.display.ops:Single candidate plugin: * webroot
Description: Webroot Authenticator
Interfaces: IAuthenticator, IPlugin
Entry point: webroot = letsencrypt.plugins.webroot:Authenticator
Initialized: <letsencrypt.plugins.webroot.Authenticator object at 0x7f39f196a5d0>
Prep: True
2017-01-17 15:05:14,610:DEBUG:letsencrypt.cli:Selected authenticator <letsencrypt.plugins.webroot.Authenticator object at 0x7f39f196a5d0> and installer None
2017-01-17 15:05:14,622:DEBUG:letsencrypt.cli:Picked account: <Account(2bff132b1c5929c9ac105fdb5abbfbf1)>
2017-01-17 15:05:14,625:DEBUG:root:Sending GET request to https://acme-v01.api.letsencrypt.org/directory. args: (), kwargs: {}
2017-01-17 15:05:14,628:INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
2017-01-17 15:05:14,672:DEBUG:letsencrypt.cli:Exiting abnormally:
Traceback (most recent call last):
  File "/usr/bin/letsencrypt", line 9, in <module>
    load_entry_point('letsencrypt==0.4.1', 'console_scripts', 'letsencrypt')()
  File "/usr/lib/python2.7/dist-packages/letsencrypt/cli.py", line 1986, in main
    return config.func(config, plugins)
  File "/usr/lib/python2.7/dist-packages/letsencrypt/cli.py", line 689, in obtain_cert
    le_client = _init_le_client(config, authenticator, installer)
  File "/usr/lib/python2.7/dist-packages/letsencrypt/cli.py", line 213, in _init_le_client
    return client.Client(config, acc, authenticator, installer, acme=acme)
  File "/usr/lib/python2.7/dist-packages/letsencrypt/client.py", line 183, in __init__
    acme = acme_from_config_key(config, self.account.key)
  File "/usr/lib/python2.7/dist-packages/letsencrypt/client.py", line 41, in acme_from_config_key
    return acme_client.Client(config.server, key=key, net=net)
  File "/usr/lib/python2.7/dist-packages/acme/client.py", line 63, in __init__
    self.net.get(directory).json())
  File "/usr/lib/python2.7/dist-packages/acme/client.py", line 627, in get
    self._send_request('GET', url, **kwargs), content_type=content_type)
  File "/usr/lib/python2.7/dist-packages/acme/client.py", line 609, in _send_request
    response = requests.request(method, url, *args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/api.py", line 53, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 468, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 576, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/adapters.py", line 447, in send
    raise SSLError(e, request=request)
SSLError: [X509] PEM lib (_ssl.c:2831)

I believe it has something to do with CA certs.

I use ubuntu 16.04

root@server07:~/# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.1 LTS
Release:        16.04
Codename:       xenial

I can update ca-certs, but there is no change

root@server07:~/# sudo dpkg-reconfigure ca-certificates
Processing triggers for ca-certificates (20160104ubuntu1) ...
Updating certificates in /etc/ssl/certs...
0 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...

updates of cacerts keystore disabled.
done.

(there is 521 files in /etc/ssl/certs)

root@server07:~# curl -v https://acme-v01.api.letsencrypt.org/directory
*   Trying 104.103.97.15...
* Connected to acme-v01.api.letsencrypt.org (104.103.97.15) port 443 (#0)
* found 181 certificates in /etc/ssl/certs/ca-certificates.crt
* found 722 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_256_GCM_SHA384
*        server certificate verification OK
*        server certificate status verification SKIPPED
*        common name: *.api.letsencrypt.org (matched)
*        server certificate expiration date OK
*        server certificate activation date OK
*        certificate public key: RSA
*        certificate version: #3
*        subject: CN=*.api.letsencrypt.org,O=INTERNET SECURITY RESEARCH GROUP,L=Mountain View,ST=California,C=US
*        start date: Fri, 26 Jun 2015 17:05:45 GMT
*        expire date: Mon, 25 Jun 2018 17:05:45 GMT
*        issuer: C=US,O=IdenTrust,OU=TrustID Server,CN=TrustID Server CA A52
*        compression: NULL
* ALPN, server accepted to use http/1.1
> GET /directory HTTP/1.1
> Host: acme-v01.api.letsencrypt.org
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx
< Content-Type: application/json
< Content-Length: 352
< Boulder-Request-Id: gaPpVeSaLLguIdJH1W5v2wKMva6z7QZTFXdPtjeOE64
< Replay-Nonce: E3AvnJ1DKq-NBpLBqo_AWOm1aiiVCTUsUU1rnEoz0w8
< X-Frame-Options: DENY
< Strict-Transport-Security: max-age=604800
< Expires: Tue, 17 Jan 2017 15:14:46 GMT
< Cache-Control: max-age=0, no-cache, no-store
< Pragma: no-cache
< Date: Tue, 17 Jan 2017 15:14:46 GMT
< Connection: keep-alive
<
{
  "key-change": "https://acme-v01.api.letsencrypt.org/acme/key-change",
  "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",
  "revoke-cert": "https://acme-v01.api.letsencrypt.org/acme/revoke-cert"
* Connection #0 to host acme-v01.api.letsencrypt.org left intact
}

Curl seems to work ok.

I am not perl programmer, but perhaps this may help:

root@server07:~/ssl# cat test.pl
    use strict;
    use IO::Socket::SSL;



my $client = new IO::Socket::SSL("acme-v01.api.letsencrypt.org/directory:443");
print $client;
if (defined $client) {
        print $client "GET / HTTP/1.0\r\n\r\n";
        print <$client>;
        close $client;
} else {
        print "I encountered a problem: ",
        IO::Socket::SSL::errstr();
        print "\n",
}

root@server07:~/ssl# perl test.pl
I encountered a problem: IO::Socket::IP configuration failed

Any help?

How is it possible to mess up the ca certificates for perl? How can I resolve it? :frowning:

I'm no perl developer and don't know what's wrong with the client but don't you want
my $client = new IO::Socket::SSL("acme-v01.api.letsencrypt.org:443");

That seems like a good catch; /directory is a concept in HTTP (not TCP or TLS), while the port number :443 is a concept in TCP which can also optionally be used as part of an HTTP or HTTPS URL.

(If you want to download the directory information, the “GET” should presumably be getting /directory instead of /.)

Hi, thx for reply.

I have fixed the perl app to this

use strict;
use IO::Socket::SSL;
my $client = new IO::Socket::SSL("acme-v01.api.letsencrypt.org:443");
print $client;
if (defined $client) {
	print $client "GET /directory HTTP/1.0\r\nHost: acme-v01.api.letsencrypt.org\r\n\r\n";
	print <$client>;
	close $client;
} else {
	print "I encountered a problem: ",
	IO::Socket::SSL::errstr();
	print "\n",
}

And the connection seems to work:

# perl test.pl
IO::Socket::SSL=GLOB(0xb7fd50)HTTP/1.0 200 OK
Server: nginx
Content-Type: application/json
Content-Length: 352
Boulder-Request-Id: TyeGkqURi0tvV-ETfG5M0zU8wUKRe_OxMXfmvyxY9nE
Replay-Nonce: ssuoUcySJImHqS1ddOTw7Mcqx4t1DBLgy76qxjxuR4c
X-Frame-Options: DENY
Strict-Transport-Security: max-age=604800
Expires: Thu, 26 Jan 2017 10:19:26 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Thu, 26 Jan 2017 10:19:26 GMT
Connection: close

{
  "key-change": "https://acme-v01.api.letsencrypt.org/acme/key-change",
  "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",
  "revoke-cert": "https://acme-v01.api.letsencrypt.org/acme/revoke-cert"
}

The problem however still resides…

l# cat /var/log/letsencrypt/letsencrypt.log
2017-01-26 10:11:33,929:DEBUG:letsencrypt.cli:Root logging level set at 30
2017-01-26 10:11:33,930:INFO:letsencrypt.cli:Saving debug log to /var/log/letsencrypt/letsencrypt.log
2017-01-26 10:11:33,930:DEBUG:letsencrypt.cli:letsencrypt version: 0.4.1
2017-01-26 10:11:33,930:DEBUG:letsencrypt.cli:Arguments: ['-a', 'webroot', '--webroot-path', '/srv/www/vhosts/mydomain.com/AsyncWebFrontend/htdocs', '-d', 'mydomain.com', '-d', 'www.mydomain.com', '-d', 'sk.mydomain.com', '-d', 'de.mydomain.com']
2017-01-26 10:11:33,931:DEBUG:letsencrypt.cli:Discovered plugins: PluginsRegistry(PluginEntryPoint#webroot,PluginEntryPoint#null,PluginEntryPoint#manual,PluginEntryPoint#standalone)
2017-01-26 10:11:33,934:DEBUG:letsencrypt.cli:Requested authenticator webroot and installer None
2017-01-26 10:11:33,935:DEBUG:letsencrypt.plugins.webroot:Creating root challenges validation dir at /srv/www/vhosts/mydomain.com/AsyncWebFrontend/htdocs/.well-known/acme-challenge
2017-01-26 10:11:33,938:DEBUG:letsencrypt.plugins.webroot:Creating root challenges validation dir at /srv/www/vhosts/mydomain.com/AsyncWebFrontend/htdocs/.well-known/acme-challenge
2017-01-26 10:11:33,938:DEBUG:letsencrypt.plugins.webroot:Creating root challenges validation dir at /srv/www/vhosts/mydomain.com/AsyncWebFrontend/htdocs/.well-known/acme-challenge
2017-01-26 10:11:33,938:DEBUG:letsencrypt.plugins.webroot:Creating root challenges validation dir at /srv/www/vhosts/mydomain.com/AsyncWebFrontend/htdocs/.well-known/acme-challenge
2017-01-26 10:11:33,938:DEBUG:letsencrypt.display.ops:Single candidate plugin: * webroot
Description: Webroot Authenticator
Interfaces: IAuthenticator, IPlugin
Entry point: webroot = letsencrypt.plugins.webroot:Authenticator
Initialized: <letsencrypt.plugins.webroot.Authenticator object at 0x7f1d93d18590>
Prep: True
2017-01-26 10:11:33,939:DEBUG:letsencrypt.cli:Selected authenticator <letsencrypt.plugins.webroot.Authenticator object at 0x7f1d93d18590> and installer None
2017-01-26 10:11:34,022:DEBUG:letsencrypt.cli:Picked account: <Account(2bff132b1c5929c9ac105fdb5abbfbf1)>
2017-01-26 10:11:34,025:DEBUG:root:Sending GET request to https://acme-v01.api.letsencrypt.org/directory. args: (), kwargs: {}
2017-01-26 10:11:34,039:INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
2017-01-26 10:11:34,109:DEBUG:letsencrypt.cli:Exiting abnormally:
Traceback (most recent call last):
  File "/usr/bin/letsencrypt", line 9, in <module>
    load_entry_point('letsencrypt==0.4.1', 'console_scripts', 'letsencrypt')()
  File "/usr/lib/python2.7/dist-packages/letsencrypt/cli.py", line 1986, in main
    return config.func(config, plugins)
  File "/usr/lib/python2.7/dist-packages/letsencrypt/cli.py", line 689, in obtain_cert
    le_client = _init_le_client(config, authenticator, installer)
  File "/usr/lib/python2.7/dist-packages/letsencrypt/cli.py", line 213, in _init_le_client
    return client.Client(config, acc, authenticator, installer, acme=acme)
  File "/usr/lib/python2.7/dist-packages/letsencrypt/client.py", line 183, in __init__
    acme = acme_from_config_key(config, self.account.key)
  File "/usr/lib/python2.7/dist-packages/letsencrypt/client.py", line 41, in acme_from_config_key
    return acme_client.Client(config.server, key=key, net=net)
  File "/usr/lib/python2.7/dist-packages/acme/client.py", line 63, in __init__
    self.net.get(directory).json())
  File "/usr/lib/python2.7/dist-packages/acme/client.py", line 627, in get
    self._send_request('GET', url, **kwargs), content_type=content_type)
  File "/usr/lib/python2.7/dist-packages/acme/client.py", line 609, in _send_request
    response = requests.request(method, url, *args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/api.py", line 53, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 468, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 576, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/adapters.py", line 447, in send
    raise SSLError(e, request=request)
SSLError: [X509] PEM lib (_ssl.c:2831)

this also seems to work:

Code:

# cat test.py
import urllib2
from OpenSSL import SSL
try:
    response = urllib2.urlopen('https://acme-v01.api.letsencrypt.org/directory')
    print 'response headers: "%s"' % response.info()

    print response.read()

except IOError, e:
    if hasattr(e, 'code'): # HTTPError
        print 'http error code: ', e.code
    elif hasattr(e, 'reason'): # URLError
        print "can't connect, reason: ", e.reason
    else:
        raise

Result:

# python2.7 test.py
response headers: "Server: nginx
Content-Type: application/json
Content-Length: 352
Boulder-Request-Id: 5J2lrMAks8q1zipipJOS2Qwi176zWkzjeARq9vwp9Ys
Replay-Nonce: kcq3r2Bok6gt6TwrK8oidXt3mkPwF5vZJGtBqPDib5g
X-Frame-Options: DENY
Strict-Transport-Security: max-age=604800
Expires: Thu, 26 Jan 2017 10:30:24 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Thu, 26 Jan 2017 10:30:24 GMT
Connection: close
"
{
  "key-change": "https://acme-v01.api.letsencrypt.org/acme/key-change",
  "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",
  "revoke-cert": "https://acme-v01.api.letsencrypt.org/acme/revoke-cert"
}

By analyzing letsencrypt source code i had to disable the verification of letsencrypt ceritifcate…

i had created file /etc/letsencrypt/cli.ini and placed there line

no-verify-ssl = True

this has solved the issue, but i would prefere if someone could help me resolve how is it possible that python is verifying the acme server one time correctly, and if used by letsencrypt not correctly ?!?

i dont want to skip security checks in long run…

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