Python 3.7 and Dataflow - SSL Certificate Issue - python-3.x

I need to use the google cloud api to write my Dataflow jobs.
As I understand it, I can't use pip install google-cloud-dataflow since Apache Beam wont' work on Python 3, so I've been using googleapiclient.discovery. However, when I issue the build() command, it bombs out citing the error:
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1045)
Background notes:
I'm sitting behind a Corporate Proxy, with HTTP(S)_PROXY set at the environment level
I also have CA_BUNDLE and REQUESTS_CA_BUNDLE set to my custom certs
I've installed certifi, but no love
I've attempted to run /Applications/Python\ 3.6/Install\
Certificates.command but couldn't find the .command in my virtualenv. Also, would prefer not to go down this path as it will make my Prod deployment a nightmare
Here's my code:
from oauth2client.client import GoogleCredentials
from googleapiclient.discovery import build
credentials = GoogleCredentials.get_application_default()
dataflow = build('dataflow', 'v1b3', credentials=credentials)
Result:
Traceback (most recent call last):
File "test_dataflow_creds.py", line 6, in
dataflow = build('dataflow', 'v1b3', credentials=credentials)
File "/Users/user/.pyenv/versions/unit-test-3.7/lib/python3.7/site-packages/googleapiclient/_helpers.py", line 130, in positional_wrapper
return wrapped(*args, **kwargs)
File "/Users/user/.pyenv/versions/unit-test-3.7/lib/python3.7/site-packages/googleapiclient/discovery.py", line 222, in build
requested_url, discovery_http, cache_discovery, cache)
File "/Users/user/.pyenv/versions/unit-test-3.7/lib/python3.7/site-packages/googleapiclient/discovery.py", line 269, in _retrieve_discovery_doc
resp, content = http.request(actual_url)
File "/Users/user/.pyenv/versions/unit-test-3.7/lib/python3.7/site-packages/httplib2/init.py", line 1924, in request
cachekey,
File "/Users/user/.pyenv/versions/unit-test-3.7/lib/python3.7/site-packages/httplib2/init.py", line 1595, in _request
conn, request_uri, method, body, headers
File "/Users/user/.pyenv/versions/unit-test-3.7/lib/python3.7/site-packages/httplib2/init.py", line 1501, in _conn_request
conn.connect()
File "/Users/user/.pyenv/versions/unit-test-3.7/lib/python3.7/site-packages/httplib2/init.py", line 1291, in connect
self.sock = self._context.wrap_socket(sock, server_hostname=self.host)
File "/Users/user/.pyenv/versions/3.7.0/lib/python3.7/ssl.py", line 412, in wrap_socket
session=session
File "/Users/user/.pyenv/versions/3.7.0/lib/python3.7/ssl.py", line 850, in _create
self.do_handshake()
File "/Users/user/.pyenv/versions/3.7.0/lib/python3.7/ssl.py", line 1108, in do_handshake
self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1045)

tl;dr: got it working by exporting all Certs to a common file, then appending to the Cert file in the path as specified by Certifi
steps:
In Firefox > Preferences > View Certificates > Your Certificates, export all the required ones.
Concatenate all of the above .crt files into one big bundle.
In bash, run python -m requests.certs to get the certs file python is using.
Append the bundled certs from step 2 above to the file from step 3.
Done

Related

openssl unable to get local issuer certificate- but why do I need it?

I admit that I'm not a sysadmin by training, so I don't "get" some things that come up. This is one of those times.
I was setting up a server for a project. Stupidly, because the last time I'd been shoved into a sysadmin role I was working with Centos7, I opted for that OS out of familiarity. When installing Python 3.10+ (I specifically need 3.10+ for some packages I intend to use), openssl was an issue; after a certain version, 1.0.2 (the last shipped version with Centos7) is not an option, and I had to spot-setup 1.1.1k for this Python3 installation to work.
So I have this Python3.10 installation working:
python3 -c "import ssl; print(ssl.OPENSSL_VERSION)"
OpenSSL 1.1.1k 25 Mar 2021
Now, I need to run queries against a remote postgres database's API using their Python3 sdk. I get openssl problems when I do. Minimum to reproduce:
from algosdk.v2client import indexer
indexer_url="https://mainnet-idx.algonode.cloud"
indexer_client = indexer.IndexerClient(indexer_token='', indexer_address=indexer_url)
indexer_client.search_assets(asset_id=0)
This fails:
Traceback (most recent call last):
File "/usr/local/lib/python3.10/urllib/request.py", line 1348, in do_open
h.request(req.get_method(), req.selector, req.data, headers,
File "/usr/local/lib/python3.10/http/client.py", line 1282, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/usr/local/lib/python3.10/http/client.py", line 1328, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "/usr/local/lib/python3.10/http/client.py", line 1277, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/usr/local/lib/python3.10/http/client.py", line 1037, in _send_output
self.send(msg)
File "/usr/local/lib/python3.10/http/client.py", line 975, in send
self.connect()
File "/usr/local/lib/python3.10/http/client.py", line 1454, in connect
self.sock = self._context.wrap_socket(self.sock,
File "/usr/local/lib/python3.10/ssl.py", line 513, in wrap_socket
return self.sslsocket_class._create(
File "/usr/local/lib/python3.10/ssl.py", line 1071, in _create
self.do_handshake()
File "/usr/local/lib/python3.10/ssl.py", line 1342, in do_handshake
self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.10/site-packages/algosdk/v2client/indexer.py", line 801, in search_assets
return self.indexer_request("GET", req, query, **kwargs)
File "/usr/local/lib/python3.10/site-packages/algosdk/v2client/indexer.py", line 74, in indexer_request
resp = urlopen(req)
File "/usr/local/lib/python3.10/urllib/request.py", line 216, in urlopen
return opener.open(url, data, timeout)
File "/usr/local/lib/python3.10/urllib/request.py", line 519, in open
response = self._open(req, data)
File "/usr/local/lib/python3.10/urllib/request.py", line 536, in _open
result = self._call_chain(self.handle_open, protocol, protocol +
File "/usr/local/lib/python3.10/urllib/request.py", line 496, in _call_chain
result = func(*args)
File "/usr/local/lib/python3.10/urllib/request.py", line 1391, in https_open
return self.do_open(http.client.HTTPSConnection, req,
File "/usr/local/lib/python3.10/urllib/request.py", line 1351, in do_open
raise URLError(err)
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)>
Okay. My initial impression was that this could be a firewall issue, so I put my firewall down. No change. Put the firewall back up. (_ssl.c:997) seems to mean "Unable to get local issuer certificate", and trying to find a resolution brings me to sites like this one.
This is where I start to lose my patience, because I just don't understand the issue. I've only handled ssl certificates in the context of setting up a website; I put up a site, the site needs a signature specifying certain things about it (which earns it an s at the end of http), so I obtain a certificate it and tie it to the site. That's the extent of my understanding. I'm not talking about a website here. Yes, I'll be hosting a website on this server, but I'm literally just talking about a Python3 script. The error above seems to indicate that the issue is that I don't have an ssl certificate. Why does that matter? This code runs on my local machine, and I never had to obtain an ssl certificate.
tl;dr: help a noob out, please. I don't understand the problem, and that also means that I don't know what to look up to fix it.

Python3 SMTP SSL Cert Renewal - SSL: CERTIFICATE_VERIFY_FAILED unable to get local issuer certificate(_ssl.c:1108)

I'm posting this message since I fixed the problem with the same error codes. It may help others who encounter a similar issue.
I used to run the py script for sending emails. On another side, the mail server Cert got renewed and all of the sudden my script failing to connect to the server.
bash # python3 email_send.py
Traceback (most recent call last):
File "emailsend.py", line 143, in <module>
server.starttls(context=context)
File "/usr/lib/python3.8/smtplib.py", line 774, in starttls
self.sock = context.wrap_socket(self.sock,
File "/usr/lib/python3.8/ssl.py", line 500, in wrap_socket
return self.sslsocket_class._create(
File "/usr/lib/python3.8/ssl.py", line 1040, in _create
self.do_handshake()
File "/usr/lib/python3.8/ssl.py", line 1309, in do_handshake
self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1108)
I solved this issue by adding the last two lines.
context = ssl.create_default_context()
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE

Getting Error unable to get local issuer certificate (_ssl.c:1056) when trying to connect to AWS IoT

I'm getting the following error when trying to connecto t aws IoT
myAWSIoTMQTTShadowClient.connect()
File "/usr/local/lib/python3.7/dist-packages/AWSIoTPythonSDK/MQTTLib.py", line 1271, in connect
return self._AWSIoTMQTTClient.connect(keepAliveIntervalSecond)
File "/usr/local/lib/python3.7/dist-packages/AWSIoTPythonSDK/MQTTLib.py", line 513, in connect
return self._mqtt_core.connect(keepAliveIntervalSecond)
File "/usr/local/lib/python3.7/dist-packages/AWSIoTPythonSDK/core/protocol/mqtt_core.py", line 196, in connect
self.connect_async(keep_alive_sec, self._create_blocking_ack_callback(event))
File "/usr/local/lib/python3.7/dist-packages/AWSIoTPythonSDK/core/protocol/mqtt_core.py", line 223, in connect_async
raise e
File "/usr/local/lib/python3.7/dist-packages/AWSIoTPythonSDK/core/protocol/mqtt_core.py", line 211, in connect_async
rc = self._internal_async_client.connect(keep_alive_sec, ack_callback)
File "/usr/local/lib/python3.7/dist-packages/AWSIoTPythonSDK/core/protocol/internal/clients.py", line 122, in connect
rc = self._paho_client.connect(host, port, keep_alive_sec)
File "/usr/local/lib/python3.7/dist-packages/AWSIoTPythonSDK/core/protocol/paho/client.py", line 665, in connect
return self.reconnect()
File "/usr/local/lib/python3.7/dist-packages/AWSIoTPythonSDK/core/protocol/paho/client.py", line 826, in reconnect
ciphers=self._tls_ciphers)
File "/usr/lib/python3.7/ssl.py", line 1222, in wrap_socket
suppress_ragged_eofs=suppress_ragged_eofs
File "/usr/lib/python3.7/ssl.py", line 412, in wrap_socket
session=session
File "/usr/lib/python3.7/ssl.py", line 853, in _create
self.do_handshake()
File "/usr/lib/python3.7/ssl.py", line 1117, in do_handshake
self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)
I have tried several methods i've found on here, including https://timonweb.com/tutorials/fixing-certificate_verify_failed-error-when-trying-requests_html-out-on-mac/
but nothing seems to work. I'm running Raspbian Linux with Python 3
The command being run
python3 Script.py --endpoint "aws endpoint" --rootCA /etc/ssl/certs/AmazonRootCA1.pem --cert /greengrass/certs/RPI-certificate.pem.crt --key /greengrass/certs/RPI-private.pem.key --thingName RaspberryPi --clientId RaspberryPi
Does anyone have any other recommendations?
I also saw this exact error in my first venture into the Pi IoT SDK today.
In my case I was using the Amazon root CA (RSA 2048) certificate (as directed by Amazon). By switching to the VeriSign Class 3 Public Primary G5 root CA certificate (also advertised on their website) the connection worked.
So, try using the VeriSign Endpoints (legacy) root certificate linked to from the AWS IoT docs at https://docs.aws.amazon.com/iot/latest/developerguide/server-authentication.html

Accessing https pages with python3

I do not understand how to use urllib3 or requests to connect to an https web site. This is driving me nuts. I have installed certifi and I see the default .pem file it provides. I have tried to set the requests.verify option to requests to every .pem and .crt file on the machine my script runs on [I am not an admin on this device]. I get nothing but errors.
I switched to using urllib3 and am now getting:
H:\Projects\MyScraper\venv\Scripts\python.exe H:/Projects/MyScraper/MyScraper.py
Traceback (most recent call last):
File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\connectionpool.py", line 600, in urlopen
chunked=chunked)
File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\connectionpool.py", line 343, in _make_request
self._validate_conn(conn)
File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\connectionpool.py", line 839, in _validate_conn
conn.connect()
File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\connection.py", line 344, in connect
ssl_context=context)
File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\util\ssl_.py", line 342, in ssl_wrap_socket
return context.wrap_socket(sock, server_hostname=server_hostname)
File "C:\Program Files (x86)\Python36-32\lib\ssl.py", line 407, in wrap_socket
_context=self, _session=session)
File "C:\Program Files (x86)\Python36-32\lib\ssl.py", line 814, in __init__
self.do_handshake()
File "C:\Program Files (x86)\Python36-32\lib\ssl.py", line 1068, in do_handshake
self._sslobj.do_handshake()
File "C:\Program Files (x86)\Python36-32\lib\ssl.py", line 689, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "H:/Projects/MyScraper/MyScraper.py", line 15, in <module>
raw_html = HTTP.request('GET', 'https://portal.xsede.org/course-calendar/')
File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\request.py", line 68, in request
**urlopen_kw)
File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\request.py", line 89, in request_encode_url
return self.urlopen(method, url, **extra_kw)
File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\poolmanager.py", line 323, in urlopen
response = conn.urlopen(method, u.request_uri, **kw)
File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\connectionpool.py", line 667, in urlopen
**response_kw)
File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\connectionpool.py", line 667, in urlopen
**response_kw)
File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\connectionpool.py", line 667, in urlopen
**response_kw)
[Previous line repeated 6 more times]
File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\connectionpool.py", line 638, in urlopen
_stacktrace=sys.exc_info()[2])
File "H:\Projects\MyScraper\venv\lib\site-packages\urllib3\util\retry.py", line 398, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='portal.xsede.org', port=443): Max retries exceeded with url: /course-calendar/ (Caused by SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)'),))
Process finished with exit code 1
My code looks like:
#!/home/me/virtualenv/python3.6/3.6/bin/python
import certifi
import urllib3
from bs4 import BeautifulSoup
HTTP = urllib3.PoolManager(
cert_reqs='CERT_REQUIRED',
ca_certs=certifi.where(),
retries=10
)
raw_html = HTTP.request('GET', 'https://portal.xsede.org/course-calendar/')
html = BeautifulSoup(raw_html, 'html.parser')
It blows up on the raw_html = HTTP.request(... line. Ideas?
Edit
Huh, this has something to do with my target host. If I go to google.com then several of my pem/crt files work.
The problem is, you are using wrong certificate to make request.
you can run this command to verify which certificate is used when any request is made, and then use that certificate in your request,
openssl s_client -showcerts -connect google.com:443
Please also make sure that you are passing verify the path to CA_BUNDLE file or directory with certificates of trusted CAs.
This list of trusted CAs can also be specified through the REQUESTS_CA_BUNDLE environment variable.
If this doesn't work out for you can explicitly merge the environment settings into your session,
When you are using the prepared request flow, keep in mind that it
does not take into account the environment. This can cause problems if
you are using environment variables to change the behaviour of
requests. For example: Self-signed SSL certificates specified in
REQUESTS_CA_BUNDLE will not be taken into account. As a result an SSL:
CERTIFICATE_VERIFY_FAILED is thrown. You can get around this behaviour
by explicity merging the environment settings into your session:
from requests import Request, Session
s = Session()
req = Request('GET', url)
prepped = s.prepare_request(req)
# Merge environment settings into session
settings = s.merge_environment_settings(prepped.url, None, None, None, None)
resp = s.send(prepped, **settings)
print(resp.status_code)

WAS Slackbot Integration from WAS Landing Page errors when following the instructions

"https://watson-personal-assistant.github.io/developer/further-topics/slackbot-integration/"
I am not able to make it work by following the steps on WAS Slack Bot Integration (above link).
My slack setting should be ok as I tried use the same ID and API token to connect to another program successfully.
I installed Python 3.7 initially, but downgrading to 3.6.2 as document suggested
"python3 bot.py" results as following - with exception stack
Forests-MacBook-Pro:simple_WA_slackbot fmlin$ python3 bot.py
Not On Bluemix...
Environment Variables Loaded Successfully
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/slackclient/server.py", line 179, in connect_slack_websocket
http_proxy_auth=proxy_auth)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/websocket/_core.py", line 494, in create_connection
websock.connect(url, **options)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/websocket/_core.py", line 217, in connect
options.pop('socket', None))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/websocket/_http.py", line 126, in connect
sock = _ssl_socket(sock, options.sslopt, hostname)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/websocket/_http.py", line 253, in _ssl_socket
sock = _wrap_sni_socket(sock, sslopt, hostname, check_hostname)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/websocket/_http.py", line 232, in _wrap_sni_socket
server_hostname=hostname,
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 401, in wrap_socket
_context=self, _session=session)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 808, in __init__
self.do_handshake()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 1061, in do_handshake
self._sslobj.do_handshake()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 683, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:748)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/slackclient/client.py", line 52, in rtm_connect
self.server.rtm_connect(use_rtm_start=with_team_state, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/slackclient/server.py", line 147, in rtm_connect
self.connect_slack_websocket(self.ws_url)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/slackclient/server.py", line 186, in connect_slack_websocket
raise SlackConnectionError(message=str(e))
slackclient.server.SlackConnectionError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:748)
Connection failed. Invalid Slack token or bot ID?
Forests-MacBook-Pro:simple_WA_slackbot fmlin$
Try running the /Applications/Python 3.6.2/Install Certificates.command program to install the root certificates needed to validate SSL connections, as it looks like your Python installation's SSL certificate verification is failing.
See more information about this program here.
Make sure you used the right Bot ID?
Did you set the user environment variable BOT_ID in the .env file?
Did you properly create the bot in slack using the instructions in the instructions
https://github.com/Watson-Personal-Assistant/simple_WA_slackbot
Getting Your Slack Key
Go to https://YOUR_SLACK.slack.com/apps/manage
In the Search App Directory field at the top, type Bots
Click on Bots
Click on the Add Configuration button
Give your bot a unique username (Save this info)
Save the API Token
You will use these variables when creating your .env file as instructed in the below steps

Resources