Repository: certbot/certbot

Issue:
AttibuteError: 'module' object has no attribute 'rand' has occured at acme/acme/crypto_util.py with >=pyOpenSSL-17.2.0
## My operating system is (include version):
CentOS 6.9

## I installed Certbot with (certbot-auto, OS package manager, pip, etc):
pip

## I ran this command and it produced this output:
```
certbot certonly --standalone -d domain.com
```
```
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Cert is due for renewal, auto-renewing...
Renewing an existing certificate
Performing the following challenges:
tls-sni-01 challenge for domain.com
Cleaning up challenges
An unexpected error occurred:
AttributeError: 'module' object has no attribute 'rand'
Please see the logfiles in /var/log/letsencrypt for more details.
```
## Certbot's behavior differed from what I expected because:
There should not be any message related on error.

## Here is a Certbot log showing the issue (if available):
```
167 2017-09-14 07:14:31,235:DEBUG:certbot.error_handler:Calling registered functions
168 2017-09-14 07:14:31,235:INFO:certbot.auth_handler:Cleaning up challenges
169 2017-09-14 07:14:31,235:DEBUG:certbot.plugins.standalone:Stopping server at :::443...
170 2017-09-14 07:14:31,727:DEBUG:certbot.log:Exiting abnormally:
171 Traceback (most recent call last):
172   File "/usr/bin/certbot", line 11, in <module>
173     sys.exit(main())
174   File "/usr/lib/python2.7/site-packages/certbot/main.py", line 755, in main
175     return config.func(config, plugins)
176   File "/usr/lib/python2.7/site-packages/certbot/main.py", line 694, in certonly
177     lineage = _get_and_save_cert(le_client, config, domains, certname, lineage)
178   File "/usr/lib/python2.7/site-packages/certbot/main.py", line 77, in _get_and_save_cert
179     renewal.renew_cert(config, domains, le_client, lineage)
180   File "/usr/lib/python2.7/site-packages/certbot/renewal.py", line 297, in renew_cert
181     new_certr, new_chain, new_key, _ = le_client.obtain_certificate(domains)
182   File "/usr/lib/python2.7/site-packages/certbot/client.py", line 318, in obtain_certificate
183     self.config.allow_subset_of_names)
184   File "/usr/lib/python2.7/site-packages/certbot/auth_handler.py", line 74, in get_authorizations
185     resp = self._solve_challenges()
186   File "/usr/lib/python2.7/site-packages/certbot/auth_handler.py", line 115, in _solve_challenges
187     resp = self.auth.perform(self.achalls)
188   File "/usr/lib/python2.7/site-packages/certbot/plugins/standalone.py", line 221, in perform
189     return [self._try_perform_single(achall) for achall in achalls]
190   File "/usr/lib/python2.7/site-packages/certbot/plugins/standalone.py", line 226, in _try_perform_single
191     return self._perform_single(achall)
192   File "/usr/lib/python2.7/site-packages/certbot/plugins/standalone.py", line 234, in _perform_single
193     servers, response = self._perform_tls_sni_01(achall)
194   File "/usr/lib/python2.7/site-packages/certbot/plugins/standalone.py", line 252, in _perform_tls_sni_01
195     response, (cert, _) = achall.response_and_validation(cert_key=self.key)
196   File "/usr/lib/python2.7/site-packages/certbot/achallenges.py", line 54, in response_and_validation
197     self.account_key, *args, **kwargs)
198   File "/usr/lib/python2.7/site-packages/acme/challenges.py", line 205, in response_and_validation
199     self.validation(account_key, *args, **kwargs))
200   File "/usr/lib/python2.7/site-packages/acme/challenges.py", line 506, in validation
201     return self.response(account_key).gen_cert(key=kwargs.get('cert_key'))
202   File "/usr/lib/python2.7/site-packages/acme/challenges.py", line 417, in gen_cert
203     'dummy', self.z_domain.decode()], force_san=True), key
204   File "/usr/lib/python2.7/site-packages/acme/crypto_util.py", line 246, in gen_ss_cert
205     cert.set_serial_number(int(binascii.hexlify(OpenSSL.rand.bytes(16)), 16))
206 AttributeError: 'module' object has no attribute 'rand'
```

## Here is the relevant nginx server block or Apache virtualhost for the domain I am configuring:
* Note1: Every setting value which is edited by user is not cause of this issue.
* Note2: We need to refer this link https://pyopenssl.org/en/stable/changelog.html


Discussion:
I have the same issue, thank you for your report 👍 
likewise
@bmw wanna review the associated PR?

Resolving patch:
diff --git a/acme/acme/crypto_util.py b/acme/acme/crypto_util.py
--- a/acme/acme/crypto_util.py
+++ b/acme/acme/crypto_util.py
@@ -2,6 +2,7 @@
 import binascii
 import contextlib
 import logging
+import os
 import re
 import socket
 import sys
@@ -243,7 +244,7 @@ def gen_ss_cert(key, domains, not_before=None,
     """
     assert domains, "Must provide one or more hostnames for the cert."
     cert = OpenSSL.crypto.X509()
-    cert.set_serial_number(int(binascii.hexlify(OpenSSL.rand.bytes(16)), 16))
+    cert.set_serial_number(int(binascii.hexlify(os.urandom(16)), 16))
     cert.set_version(2)
 
     extensions = [


Test patch: