openbmc / bmcweb

A do everything Redfish, KVM, GUI, and DBus webserver for OpenBMC
Apache License 2.0
162 stars 134 forks source link

websocket not working #31

Closed frsauvage closed 5 years ago

frsauvage commented 5 years ago

Hi all,

I started my websocket tests from the scripts\websocket_test.py file.

Issue : The connection is always closed after a first ws.recv() (empty result).

I spent times to get a correct handshake, so in create_connectioncookie parameter, I suppose XSRF-TOKEN is the token received in the response when creating a session and SESSION is the received session id.

This part seems to work,

*1. Create a session with a secure POST
r = requests.post('https://mybmc/redfish/v1/SessionService/Sessions', auth=('root', 'fakerootpass'), json={"UserName": "root", "Password": "fakerootpass"} , verify=False)
cookie = requests.utils.dict_from_cookiejar(r.cookies) => cookie jar empty => so it is useless...
*2. Retrieve token and Id
response = json.loads(r.text)
session_id = response['Id']
auth_token = r.headers['x-auth-token']

websocket.enableTrace(True)
*3. Connect with token and Id inside a cookie, as in the example - not clear ...
ws = websocket.create_connection('wss://mybmc/subscribe'    
    , verify=False
    , sslopt={"cert_reqs": ssl.CERT_NONE,"check_hostname": False} #,"check_hostname": False,"ssl_version": ssl.PROTOCOL_TLSv1 
    , cookie="XSRF-TOKEN={token}; SESSION={session}".format(token=auth_token, session=session_id)
    )
body = json.dumps({
    'paths': ['/xyz/openbmc_project/logging', '/xyz/openbmc_project/sensors']
    ,"interfaces": ["xyz.openbmc_project.Logging.Entry", "xyz.openbmc_project.Sensor.Value"]
})

ws.send(body)

Debug trace --- request header --- GET /subscribe HTTP/1.1 Upgrade: websocket Connection: Upgrade Host: 172.31.92.34 Origin: http://172.31.92.34 Sec-WebSocket-Key: 96TyH/XoygwMUBPsUdykvg== Sec-WebSocket-Version: 13 Cookie: XSRF-TOKEN=PMizg2OffIz9xin5rbNr; SESSION=eELLEvaUxE

--- response header --- HTTP/1.1 101 Switching Protocols Server: nginx Date: Fri, 18 Jan 2019 22:38:07 GMT Connection: upgrade Upgrade: websocket Sec-WebSocket-Accept: iD0uaDw+g6epi5VbEngzBz2sCYk=

send: '\x81\xfe\x00\xa4\x07\x16[\xfc|4+\x9ds~(\xde=6\x00\xde(n"\x86(y+\x99it6\x9fXf)\x93ms8\x88(z4\x9b`\x7f5\x9b%:{\xde(n"\x86(y+\x99it6\x9fXf)\x93ms8\x88(e>\x92ty)\x8f%Kw\xdc%\x7f5\x88bd=\x9dds(\xde=6\x00\xde\x7fo!\xd2hf>\x92e{8\xa3wd4\x96bu/\xd2Ky<\x9bnx<\xd2Bx/\x8e~4w\xdc%n"\x86)y+\x99it6\x9fXf)\x93ms8\x88)E>\x92ty)\xd2Qw7\x89b4\x06\x81' client sent client receiving...


*4. This part does NOT work:

while True:
    try:
        result = ws.recv()
        print("client received '%s'" % result)
    except Exception as error:
        print "client error: {e}".format(e = error)
        break
ws.close()

Debug trace send: '\x88\x82Pk\x15\x18S\x83'


So I get wiered characters when ws.recv() is invoked. And I get an error : ws is already closed.

Any idea ? suggestion ? Please I spent hours... I may miss something evident, do not hesitate to tell me...

Best Regards, Francine

edtanous commented 5 years ago

Sorry for your troubles. We could certainly provide better, and more up to date examples of usage.

The example I use is attached below, and logs into the websocket using basic auth, thus logging in without requiring the double request approach. For production settings, session tokens are still recommended, but not required.

import json
import ssl
import websocket
import base64

BMC_ADDRESS = "10.243.49.82"
username = 'root'
password = '0penBmc'

b64Val = base64.b64encode((username + ":" + password).encode("ascii"))

websocket.enableTrace(True)

ws = websocket.create_connection('wss://' + BMC_ADDRESS + '/subscribe',
                                 sslopt={"cert_reqs": ssl.CERT_NONE},
                                 header=["Authorization: Basic " + b64Val.decode("ascii")])
request = json.dumps({
    "paths": ["/xyz/openbmc_project/logging", "/xyz/openbmc_project/sensors"],
    "interfaces": ["xyz.openbmc_project.Logging.Entry", "xyz.openbmc_project.Sensor.Value"]
})

ws.send(request)
print("Sent")
print("Receiving...")
while True:
    result = ws.recv()
    print("Received '%s'" % result)
ws.close()

When I run that, I get the following on my console

> --- request header ---
GET /subscribe HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: 10.243.49.82
Origin: http://10.243.49.82
Sec-WebSocket-Key: yk+4C8S++y+pIvgFl7AkdQ==
Sec-WebSocket-Version: 13
Authorization: Basic cm9vdDowcGVuQm1j

-----------------------
--- response header ---
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Accept: oP4ltAAjDHw/nnclUSjwRf3kOQQ=
Server: Boost.Beast/181
-----------------------
send: b'\x81\xfe\x00\xa4u6\xe4C\x0e\x14\x94"\x01^\x97aO\x16\xbfaZN\x9d9ZY\x94&\x1bT\x89 *F\x96,\x1fS\x877ZZ\x8b$\x12_\x8a$W\x1a\xc4aZN\x9d9ZY\x94&\x1bT\x89 *F\x96,\x1fS\x877ZE\x81-\x06Y\x960Wk\xc8cW_\x8a7\x10D\x82"\x16S\x97aO\x16\xbfa\rO\x9em\x1aF\x81-\x17[\x87\x1c\x05D\x8b)\x10U\x90m9Y\x83$\x1cX\x83m0X\x901\x0c\x14\xc8cWN\x9d9[Y\x94&\x1bT\x89 *F\x96,\x1fS\x877[e\x81-\x06Y\x96m#W\x886\x10\x14\xb9>'
Sent
Receiving...
Received '{"event":"PropertiesChanged","interface":"xyz.openbmc_project.Sensor.Value","path":"/xyz/openbmc_project/sensors/fan_tach/Fan_3","properties":{"Value":4438.0}}'
Received '{"event":"PropertiesChanged","interface":"xyz.openbmc_project.Sensor.Value","path":"/xyz/openbmc_project/sensors/voltage/P1V8_PCH","properties":{"Value":1.8175}}'
Received '{"event":"PropertiesChanged","interface":"xyz.openbmc_project.Sensor.Value","path":"/xyz/openbmc_project/sensors/fan_tach/Fan_2","properties":{"Value":4500.0}}'
frsauvage commented 5 years ago

Thank you edtanous , I am so gratefull ! It still does not work but I have a different server from you, so that should be the source of my issue:

image

I try to figure it out by my side and I keep contact. Best Regards, Francine

edtanous commented 5 years ago

..... FYI, it sounds like the project is moving toward a "pure" bmcweb solution, without nginx at all. You might consider testing with that, as it has a number of advantages.

edtanous commented 5 years ago

@frsauvage any updates here? This looks like it's some incompatibility between nginx and the scripts you're using. The WebUI seems to successfully launch, which utilities the /subscribe api, and we're not seeing any issues on non-nginx systems. I suspect this bug needs to be opened against meta-ibm.

frsauvage commented 5 years ago

@edtanous , I am still waiting for the web server on my side, I cannot do it by myself. I will tell you , I promise ;-)

Le jeu. 31 janv. 2019 à 16:53, edtanous notifications@github.com a écrit :

@frsauvage https://github.com/frsauvage any updates here? This looks like it's some incompatibility between nginx and the scripts you're using. The WebUI seems to successfully launch, which utilities the /subscribe api, and we're not seeing any issues on non-nginx systems. I suspect this bug needs to be opened against meta-ibm.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/openbmc/bmcweb/issues/31#issuecomment-459396036, or mute the thread https://github.com/notifications/unsubscribe-auth/AWE1LDJVP-8uryp18_JfpEBmb1qrm2-Qks5vIxGKgaJpZM4aPMEJ .

edtanous commented 5 years ago

I'm not really following.... You filed this bug against bmcweb, which I assumed means you're using that component as your webserver (be aware, this is not the default for the OpenBMC project). If you're not, you need to file the bug against the webserver you're using, so the maintainers are made aware and can get it resolved. Based on the responses, you are running on an nginx based IBM BMC? The configurations for that are housed in the meta-ibm layer. Maybe some more details about what platform you're on, what version of OpenBMC you're running, and how you're building it would help to clear this up a bit.

frsauvage commented 5 years ago

Hi edtanou, Based on the responses, you are running on an nginx based IBM BMC? Yes, but I did NOT know it before posting. I did not even imagine it could be possible, because every body here is talking about OpenBMC, never IBM !

So your post was very helpful because I discover that some components - like nginx - from IBM are present, and it should no more be the case. I was upset too !

We are fixing the problem - I mean I told the guy - who is compiling - to change everything that could be "IBM" to "pure" OpenBCM/bmcweb, and that it could have told me that before...

I agree with you, I will be vigilant in the future - I screwed like a beginner in a forum !! I swear it is not the case.

Sorry for this inconvenient, I fully understand what you told me, sorry if you spent your time, my post should not be in the bmcweb forum, you are right, and thank you again for your help.

Francine

Le jeu. 31 janv. 2019 à 17:14, edtanous notifications@github.com a écrit :

I'm not really following.... You filed this bug against bmcweb, which I assumed means you're using that component as your webserver (be aware, this is not the default for the OpenBMC project). If you're not, you need to file the bug against the webserver you're using, so the maintainers are made aware and can get it resolved. Based on the responses, you are running on an nginx based IBM BMC? The configurations for that are housed in the meta-ibm layer. Maybe some more details about what platform you're on, what version of OpenBMC you're running, and how you're building it would help to clear this up a bit.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/openbmc/bmcweb/issues/31#issuecomment-459404111, or mute the thread https://github.com/notifications/unsubscribe-auth/AWE1LJDBnIJIi7RFyfulVza1S6AajZr4ks5vIxZwgaJpZM4aPMEJ .

frsauvage commented 5 years ago

Hi edtanou, your code works perfectly, thank you !

edtanous commented 5 years ago

FYI, making bmcweb the standard got merged to mainline in this patch this morning.

https://gerrit.openbmc-project.xyz/c/openbmc/meta-phosphor/+/12933/

If you still see websocket issues when running the mainline code, let me know. I will get the websocket example updated with the easier to use version I posted above.