Open glimchb opened 9 months ago
``Traceback (most recent call last):
File "/usr/lib/python3.10/urllib/request.py", line 1348, in do_open
h.request(req.get_method(), req.selector, req.data, headers,
File "/usr/lib/python3.10/http/client.py", line 1283, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/usr/lib/python3.10/http/client.py", line 1329, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "/usr/lib/python3.10/http/client.py", line 1278, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/usr/lib/python3.10/http/client.py", line 1038, in _send_output
self.send(msg)
File "/usr/lib/python3.10/http/client.py", line 976, in send
self.connect()
File "/usr/lib/python3.10/http/client.py", line 1455, in connect
self.sock = self._context.wrap_socket(self.sock,
File "/usr/lib/python3.10/ssl.py", line 513, in wrap_socket
return self.sslsocket_class._create(
File "/usr/lib/python3.10/ssl.py", line 1100, in _create
self.do_handshake()
File "/usr/lib/python3.10/ssl.py", line 1371, in do_handshake
self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed \
certificate (_ssl.c:1007)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/sancho/opi/ansible-opi-dpu/./jgctests/get.py", line 177, in <module>
main()
File "/home/sancho/opi/ansible-opi-dpu/./jgctests/get.py", line 174, in main
utils.open_url("GET", "https://10.137.189.246/redfish/v1/UpdateService")
File "/home/sancho/opi/ansible-opi-dpu/./jgctests/get.py", line 167, in open_url
r = urllib_request.urlopen(request, None, timeout)
File "/usr/lib/python3.10/urllib/request.py", line 216, in urlopen
return opener.open(url, data, timeout)
File "/usr/lib/python3.10/urllib/request.py", line 519, in open
response = self._open(req, data)
File "/usr/lib/python3.10/urllib/request.py", line 536, in _open
result = self._call_chain(self.handle_open, protocol, protocol +
File "/usr/lib/python3.10/urllib/request.py", line 496, in _call_chain
result = func(*args)
File "/usr/lib/python3.10/urllib/request.py", line 1391, in https_open
return self.do_open(http.client.HTTPSConnection, req,
File "/usr/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: self\
-signed certificate (_ssl.c:1007)>
It can be fixed by making the following change in
/usr/lib/python3/dist-packages/ansible/module_utils/urls.py
def open(self, method, url, data=None, headers=None, use_proxy=None,
force=None, last_mod_time=None, timeout=None, validate_certs=None,
url_username=None, url_password=None, http_agent=None,
force_basic_auth=None, follow_redirects=None,
client_cert=None, client_key=None, cookies=None, use_gssapi=False,
unix_socket=None, ca_path=None, unredirected_headers=None, decompress=None,
ciphers=None, use_netrc=None):
...
context = ssl._create_unverified_context()
r = urllib_request.urlopen(request, None, timeout, context=context)
But likely this is not the right fix
I think I have reproduction with basic python (3.6.8) and also enabled debug prints now:
this works (from https://github.com/DMTF/python-redfish-library/blob/main/src/redfish/rest/v1.py) :
import http.client
http.client.HTTPConnection.debuglevel = 1
import redfish
r = redfish.redfish_client(base_url='https://10.246.87.133')
for x in range(3):
s = r.get('/redfish/v1/UpdateService', headers={'X-Auth-Token' : "iwKUR3no1WOHB5PFkd5H"})
print(s.status)
print(s.text)
and this works:
import http.client
http.client.HTTPConnection.debuglevel = 1
import requests
s = requests.Session()
for x in range(3):
resp = s.request("GET", "https://10.246.87.133/redfish/v1/UpdateService", headers={'X-Auth-Token' : "iwKUR3no1WOHB5PFkd5H"}, verify=False)
print(resp)
vs fails:
import ssl
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
import urllib.request
handler = urllib.request.HTTPSHandler(debuglevel=1, context=ctx)
opener = urllib.request.build_opener(handler)
opener.addheaders = [('X-Auth-Token', 'iwKUR3no1WOHB5PFkd5H')]
for x in range(3):
response = opener.open("https://10.246.87.133/redfish/v1/UpdateService")
print(response.read())
When it fails, first iteration is ok, second is failed (that's why range in the code) Also important, session object is deleted on the BMC side... Will debug more tomorrow...
working debug info:
send: b'GET /redfish/v1/UpdateService HTTP/1.1\r\nHost: 10.246.87.133\r\nUser-Agent: python-requests/2.27.1\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\nX-Auth-Token: iwKUR3no1WOHB5PFkd5H\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: OData-Version: 4.0
header: Allow: GET, PATCH, HEAD
header: ETag: "2BB654F0"
header: Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
header: X-Frame-Options: DENY
header: Pragma: no-cache
header: Cache-Control: no-Store,no-Cache
header: X-XSS-Protection: 1; mode=block
header: X-Content-Type-Options: nosniff
header: Content-Security-Policy: default-src 'none'; img-src 'self' data:; font-src 'self'; style-src 'self'; script-src 'self'; connect-src 'self' wss:; form-action 'none'; frame-ancestors 'none'; object-src 'none'; base-uri 'none'
header: Content-Type: application/json
header: Date: Tue, 05 Mar 2024 03:54:39 GMT
header: Content-Length: 1821
<Response [200]>
failed debug info:
send: b'GET /redfish/v1/UpdateService HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: 10.246.87.133\r\nX-Auth-Token: iwKUR3no1WOHB5PFkd5H\r\nAccept: */*\r\nConnection: close\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: OData-Version: 4.0
header: Allow: GET, PATCH, HEAD
header: ETag: "2BB654F0"
header: Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
header: X-Frame-Options: DENY
header: Pragma: no-cache
header: Cache-Control: no-Store,no-Cache
header: X-XSS-Protection: 1; mode=block
header: X-Content-Type-Options: nosniff
header: Content-Security-Policy: default-src 'none'; img-src 'self' data:; font-src 'self'; style-src 'self'; script-src 'self'; connect-src 'self' wss:; form-action 'none'; frame-ancestors 'none'; object-src 'none'; base-uri 'none'
header: Content-Type: application/json
header: Date: Tue, 05 Mar 2024 03:56:50 GMT
header: Connection: close
header: Content-Length: 1821
b'{\n "@odata.id": "/redfish/v1/UpdateService",\n "@odata.type": "#UpdateService.v1_8_0.UpdateService",\n "Actions": {\n "#UpdateService.SimpleUpdate": {\n "TransferProtocol@Redfish.AllowableValues": [\n [\n "SCP"\n ]\n ],\n "target": "/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate"\n },\n "Oem": {\n "Nvidia": {\n "#NvidiaUpdateService.CommitImage": {\n "@Redfish.ActionInfo": "/redfish/v1/UpdateService/Oem/Nvidia/CommitImageActionInfo",\n "target": "/redfish/v1/UpdateService/Actions/Oem/NvidiaUpdateService.CommitImage"\n },\n "#NvidiaUpdateService.PublicKeyExchange": {\n "target": "/redfish/v1/UpdateService/Actions/Oem/NvidiaUpdateService.PublicKeyExchange"\n },\n "#NvidiaUpdateService.RevokeAllRemoteServerPublicKeys": {\n "target": "/redfish/v1/UpdateService/Actions/Oem/NvidiaUpdateService.RevokeAllRemoteServerPublicKeys"\n }\n }\n }\n },\n "Description": "Service for Software Update",\n "FirmwareInventory": {\n "@odata.id": "/redfish/v1/UpdateService/FirmwareInventory"\n },\n "HttpPushUri": "/redfish/v1/UpdateService/update",\n "HttpPushUriOptions": {\n "HttpPushUriApplyTime": {\n "ApplyTime": "OnReset"\n }\n },\n "HttpPushUriTargets": [],\n "Id": "UpdateService",\n "MaxImageSizeBytes": 209715200,\n "MultipartHttpPushUri": "/redfish/v1/UpdateService/update-multipart",\n "MultipartHttpPushUri@Redfish.OperationApplyTimeSupport": {\n "@odata.type": "#Settings.v1_3_3.OperationApplyTimeSupport",\n "SupportedValues": [\n "Immediate"\n ]\n },\n "Name": "Update Service",\n "ServiceEnabled": true,\n "SoftwareInventory": {\n "@odata.id": "/redfish/v1/UpdateService/SoftwareInventory"\n },\n "Status": {\n "Conditions": [],\n "State": "Enabled"\n }\n}'
send: b'GET /redfish/v1/UpdateService HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: 10.246.87.133\r\nX-Auth-Token: iwKUR3no1WOHB5PFkd5H\r\nAccept: */*\r\nConnection: close\r\n\r\n'
reply: 'HTTP/1.1 401 Unauthorized\r\n'
header: WWW-Authenticate: Basic
header: Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
header: X-Frame-Options: DENY
header: Pragma: no-cache
header: Cache-Control: no-Store,no-Cache
header: X-XSS-Protection: 1; mode=block
header: X-Content-Type-Options: nosniff
header: Content-Security-Policy: default-src 'none'; img-src 'self' data:; font-src 'self'; style-src 'self'; script-src 'self'; connect-src 'self' wss:; form-action 'none'; frame-ancestors 'none'; object-src 'none'; base-uri 'none'
header: Content-Type: application/json
header: Date: Tue, 05 Mar 2024 03:56:50 GMT
header: Connection: close
header: Content-Length: 829
found it!!!
header: Connection: keep-alive
vs
header: Connection: close
reproduces with simple:
$ curl -k -H "X-Auth-Token: IDY0mdVOxAyNhS1XzBoL" -H "Connection: close" -X GET https://10.246.87.133/redfish/v1/UpdateService
also checked the code https://github.com/python/cpython/blob/3.9/Lib/urllib/request.py#L1331
OK, I think we have two issues: one is the unsecure_context I outlined before. Even when I run if with a valid token the first time, it fails with an exception. And, then, if I actually modify the community code to provide the unsecure_context in the urrlib_request.open, it works the first time and fails the second one (which is the close that Boris mentioned). I distilled the ansible redfish module to something simple (see the attached python script):
``sancho@doca-vr-ansible:~/opi/ansible-opi-dpu/jgctests$ echo $token
ltSvFgT3VYyIk93YbVvF
sancho@doca-vr-ansible:~/opi/ansible-opi-dpu/jgctests$ python3 ./get2.py ltSvFgT3VYyIk93YbVvF
{'msg': 'URL Error on GET request to '
"'https://10.137.189.246/redfish/v1/UpdateService': '[SSL: "
'CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed '
"certificate (_ssl.c:1007)'",
'ret': False}
sancho@doca-vr-ansible:~/opi/ansible-opi-dpu/jgctests$ python3 ./get2.py -U ltSvFgT3VYyIk93YbVvF
{'data': {'@odata.id': '/redfish/v1/UpdateService',
'@odata.type': '#UpdateService.v1_8_0.UpdateService',
'Actions': {'#UpdateService.SimpleUpdate': {'TransferProtocol@Redfish.AllowableValues': [['SCP']],
'target': '/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate'},
'Oem': {'Nvidia': {'#NvidiaUpdateService.CommitImage': {'@Redfish.ActionInfo': '/redfish/v1/UpdateService/Oem/Nvidia/CommitImageActionInfo',
'target': '/redfish/v1/UpdateService/Actions/Oem/NvidiaUpdateService.CommitImage'},
'#NvidiaUpdateService.PublicKeyExchange': {'target': '/redfish/v1/UpdateService/Actions/Oem/NvidiaUpdateService.PublicKeyExchange'},
'#NvidiaUpdateService.RevokeAllRemoteServerPublicKeys': {'target': '/redfish/v1/UpdateService/Actions/Oem/NvidiaUpdateService.RevokeAllRemoteServerPublicKeys'}}}},
'Description': 'Service for Software Update',
'FirmwareInventory': {'@odata.id': '/redfish/v1/UpdateService/FirmwareInventory'},
'HttpPushUri': '/redfish/v1/UpdateService/update',
'HttpPushUriOptions': {'HttpPushUriApplyTime': {'ApplyTime': 'OnReset'}},
'HttpPushUriTargets': [],
'Id': 'UpdateService',
'MaxImageSizeBytes': 209715200,
'MultipartHttpPushUri': '/redfish/v1/UpdateService/update-multipart',
'MultipartHttpPushUri@Redfish.OperationApplyTimeSupport': {'@odata.type': '#Settings.v1_3_3.OperationApplyTimeSupport',
'SupportedValues': ['Immediate']},
'Name': 'Update Service',
'ServiceEnabled': True,
'SoftwareInventory': {'@odata.id': '/redfish/v1/UpdateService/SoftwareInventory'},
'Status': {'Conditions': [], 'State': 'Enabled'}},
'headers': {'allow': 'GET, PATCH, HEAD',
'cache-control': 'no-Store,no-Cache',
'connection': 'close',
'content-length': '1821',
'content-security-policy': "default-src 'none'; img-src 'self' "
"data:; font-src 'self'; style-src "
"'self'; script-src 'self'; "
"connect-src 'self' wss:; form-action "
"'none'; frame-ancestors 'none'; "
"object-src 'none'; base-uri 'none'",
'content-type': 'application/json',
'date': 'Tue, 05 Mar 2024 19:42:20 GMT',
'etag': '"2BB654F0"',
'odata-version': '4.0',
'pragma': 'no-cache',
'strict-transport-security': 'max-age=31536000; '
'includeSubdomains; preload',
'x-content-type-options': 'nosniff',
'x-frame-options': 'DENY',
'x-xss-protection': '1; mode=block'},
'resp': <http.client.HTTPResponse object at 0x7fdbad5dcb20>,
'ret': True}
sancho@doca-vr-ansible:~/opi/ansible-opi-dpu/jgctests$ python3 ./get2.py -U ltSvFgT3VYyIk93YbVvF
{'msg': 'HTTP Error 401 on GET request to '
"'https://10.137.189.246/redfish/v1/UpdateService', extended message: "
"'While accessing the resource at '/redfish/v1/UpdateService', the "
"service received an authorization error 'Invalid username or "
"password'.'",
'ret': False,
'status': 401}
unsecure_context
I don't see an issue with unsecure_context
in my environment. I will double-check again.
for mee looks like validate_certs
is always false
, so context should already be unverified
see https://github.com/ansible/ansible/blob/stable-2.16/lib/ansible/module_utils/urls.py#L1440
see https://docs.ansible.com/ansible/latest/collections/community/general/redfish_command_module.html#examples
trying something like this:
I get
but fails on
curl seems working...