odelot / aws-mqtt-websockets

Implementation of a middleware to use AWS MQTT service through websockets, aiming the ESP8266 plataform
GNU Lesser General Public License v3.0
231 stars 67 forks source link

403 Forbidden #7

Closed GregorPonert closed 7 years ago

GregorPonert commented 8 years ago

Hi odelot,

Great Work. I tried to get the example script working. Unfortunately I keep getting 403 Forbidden Messages from the aws Server. I used aws-mqtt-websockets from the repository with the updated example from this post: https://github.com/odelot/aws-mqtt-websockets/issues/2#issuecomment-208978640 Here is the Debug-Output. Do you have any idea what I could have done wrong ?

please start sntp first ! [WS-Client] connected to A2BF8DY97CWJ2U.iot.us-west-2.amazonaws.com:443. [WS-Client][sendHeader] sending header...

-->GET /mqtt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AWSKEY%F 20160527%F us-west-2%F iotdevicegateway%F aws4_request&X-Amz-Date=20160527T075257Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=65544570a55cf2d17c676a04d4c3203c5096ad0232eef36eb773d1162c23e067 HTTP/1.1 Host: A2BF8DY97CWJ2U.iot.us-west-2.amazonaws.com:443 Connection: Upgrade Upgrade: websocket Origin: file:// User-Agent: arduino-WebSocket-Client Sec-WebSocket-Version: 13 Sec-WebSocket-Key: JR5yCYxsfpFwLFbxlhTUEA== Sec-WebSocket-Protocol: mqtt

[WS-Client][sendHeader] sending header... Done (284875us). [WS-Client][handleHeader] RX: HTTP/1.1 403 Forbidden [WS-Client][handleHeader] RX: content-type: application/json [WS-Client][handleHeader] RX: content-length: 241 [WS-Client][handleHeader] RX: date: Fri, 27 May 2016 07:53:00 GMT [WS-Client][handleHeader] RX: x-amzn-RequestId: 7b224257-875c-42e6-9c4c-46b471ea8570 [WS-Client][handleHeader] RX: connection: Keep-Alive [WS-Client][handleHeader] RX: x-amzn-ErrorType: ForbiddenException: [WS-Client][handleHeader] RX: access-control-allow-origin: * [WS-Client][handleHeader] RX: access-control-allow-headers: Authorization [WS-Client][handleHeader] RX: access-control-allow-headers: X-amz-security-token [WS-Client][handleHeader] RX: access-control-allow-headers: Accept [WS-Client][handleHeader] RX: access-control-allow-headers: X-amz-date [WS-Client][handleHeader] RX: access-control-allow-headers: X-amz-user-agent [WS-Client][handleHeader] RX: access-control-allow-headers: X-amz-content-sha256 [WS-Client][handleHeader] RX: access-control-allow-headers: Accept-Language [WS-Client][handleHeader] RX: access-control-allow-headers: X-requested-with [WS-Client][handleHeader] RX: access-control-allow-headers: Content-Language [WS-Client][handleHeader] RX: access-control-allow-headers: Content-Type [WS-Client][handleHeader] RX: access-control-expose-headers: x-amzn-ErrorMessage [WS-Client][handleHeader] RX: access-control-expose-headers: x-amzn-RequestId [WS-Client][handleHeader] RX: access-control-expose-headers: x-amzn-ErrorType [WS-Client][handleHeader] RX: access-control-expose-headers: Date [WS-Client][handleHeader] Header read fin. [WS-Client][handleHeader] Client settings: [WS-Client][handleHeader] - cURL: /mqtt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AWSKEY%2F20160527%2Fus-west-2%2Fiotdevicegateway%2Faws4_request&X-Amz-Date=20160527T075257Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=65544570a55cf2d17c676a04d4c3203c5096ad0232eef36eb773d1162c23e067 [WS-Client][handleHeader] - cKey: JR5yCYxsfpFwLFbxlhTUEA== [WS-Client][handleHeader] Server header: [WS-Client][handleHeader] - cCode: 403 [WS-Client][handleHeader] - cIsUpgrade: 0 [WS-Client][handleHeader] - cIsWebsocket: 1 [WS-Client][handleHeader] - cAccept: [WS-Client][handleHeader] - cProtocol: mqtt [WS-Client][handleHeader] - cExtensions: [WS-Client][handleHeader] - cVersion: 0 [WS-Client][handleHeader] no Websocket connection close. [WS-Client] client disconnected. [AWSc] Disconnected! [WS-Client] connect wss...

GregorPonert commented 8 years ago

Maybe the problem is related to the SSL Certificate ? As far as I understood, the Websocket connection is SSL encrypted. However, I did not configure any Certificate for this SSL encryption and I did not find any hint how to configure the Certificate (e.g. with espconn_secure_ca_enable).

boraozgen commented 8 years ago

It might be a problem with the arduinoWebSockets dependency. Check out https://github.com/odelot/aws-mqtt-websockets/issues/9

rahu2581 commented 8 years ago

Also the host name should be lowercase. A2BF8DY97CWJ2U.iot.us-west-2.amazonaws.com -> a2bf8dy97cwj2u.iot.us-west-2.amazonaws.com

Regarding the arduinoWebSockets: A port was added to the Host header. The same port needs to be added to the header before signing it.

sprintf(canonicalHeaders, "%shost:%s:443\n", canonicalHeaders,awsDomain);

Any difference in the header will render the signature invalid...

tejaswigowda commented 8 years ago

@rahu2581 can you elaborate on:

Regarding the arduinoWebSockets:
A port was added to the Host header.
The same port needs to be added to the header before signing it.

sprintf(canonicalHeaders, "%shost:%s:443\n", canonicalHeaders,awsDomain);
Any difference in the header will render the signature invalid...

My setup was working just fine. Am not sure why it stopped working once I used a different IAM user.

Appreciate all your help

rahu2581 commented 8 years ago

See https://github.com/odelot/aws-mqtt-websockets/pull/10. In my case I got the 403 because the dependency arduinoWebSockets added a port number to their host header which is not included in the signed host header.

If you only have problems with another IAM user my guess would be the permissions of that user though.

healthineer commented 7 years ago

I also encountered the 403 Permission Problem with my esp8266 (2.3.0). For me its only working with the 2.0.2 version of arduinoSockets [https://github.com/Links2004/arduinoWebSockets/releases/tag/2.0.2] without sending the port number in the header: sprintf(canonicalHeaders, "%shost:%s\n", canonicalHeaders,awsDomain); I tried also the versions 2.0.3, 2.0.4, 2.0.5 of arduinoWebsockets but didn't succeeded neither with nor without the port number in the header

TopGunPk commented 7 years ago

Hi. I am facing same issue.

connecting to wifi
state: 5 -> 0 (0)
rm 0
f r0, .....................scandone
.f r0, scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 1
cnt 

connected with Nayatel, channel 11
dhcp client start...
ip:192.168.100.60,mask:255.255.255.0,gw:192.168.100.1

connected
10295 - conn: 1 - (23520)
[WS-Client] connect wss...
please start sntp first !
[WS-Client] connected to ajqoxnudzweat.iot.us-east-1.amazonaws.com:443.
[WS-Client][sendHeader] sending header...
[WS-Client][sendHeader] sending header... Done (257277us).
[WS-Client][handleHeader] RX: HTTP/1.1 403 Forbidden
[WS-Client][handleHeader] RX: content-type: application/json
[WS-Client][handleHeader] RX: content-length: 241
[WS-Client][handleHeader] RX: date: Mon, 31 Oct 2016 12:37:09 GMT
[WS-Client][handleHeader] RX: x-amzn-RequestId: 2d1ca2d4-765a-7c06-8479-7cb8dd4f094e
[WS-Client][handleHeader] RX: connection: Keep-Alive
[WS-Client][handleHeader] RX: x-amzn-ErrorType: Forbi] client disconnected.
[AWSc] Disconnected!
[WS-Client] connect wss...
please start sntp first !

I tried to change the Canonical headers statement to not have the PORT number as well, still same issue.

Is this all due to AWS's change of headers OR is this a library issue ?

If so, could you please guide me how to get around this ?

Thank you.

vitoralvimb commented 7 years ago

Healthineer, you doin't need to back to WebSockets 2.0.2 version. You can do work with 2.0.5 doing few changes.

At the AWSWebSocketClient.cpp, keep this line of code without PORT, like this:

sprintf(canonicalHeaders, "%shost:%s\n", canonicalHeaders,awsDomain);

At the WebSocketsClient.cpp, change this part of code with the lines below:

    String transport;
    String handshake;
    if(!client->isSocketIO || (client->isSocketIO && client->cSessionId.length() > 0)) {
        if(client->isSocketIO) {
            transport = "&transport=websocket&sid=" + client->cSessionId;
        }
        handshake = "GET " + client->cUrl + transport + " HTTP/1.1\r\n"
                    //CHANGED
                    "Host: " + _host + "\r\n"
                    ///////////////////////////////
                    "Connection: Upgrade\r\n"
                    "Upgrade: websocket\r\n"
                    "Origin: file://\r\n"
                    "User-Agent: arduino-WebSocket-Client\r\n"
                    "Sec-WebSocket-Version: 13\r\n"
                    "Sec-WebSocket-Key: " + client->cKey + "\r\n";

        if(client->cProtocol.length() > 0) {
           handshake += "Sec-WebSocket-Protocol: " + client->cProtocol + "\r\n";

        }

        if(client->cExtensions.length() > 0) {
            handshake += "Sec-WebSocket-Extensions: " + client->cExtensions + "\r\n";
        }

    } else {
        handshake = "GET " + client->cUrl + "&transport=polling HTTP/1.1\r\n"
                    "Connection: keep-alive\r\n";
                  //MOVED from outside ELSE to here
                  handshake +=    "Host: " + _host + "\r\n"
                        "Origin: file://\r\n"
                        "User-Agent: arduino-WebSocket-Client\r\n";
                  /////////////////////////////////////////////////////
    }
    if(client->base64Authorization.length() > 0) {
        handshake += "Authorization: Basic " + client->base64Authorization + "\r\n";
    }

    if(client->plainAuthorization.length() > 0) {
        handshake += "Authorization: " + client->plainAuthorization + "\r\n";
    }

    handshake += "\r\n";

    client->tcp->write(handshake.c_str(), handshake.length());

    //ADDED a debug line just to see the Header we are sending                    
    DEBUG_WEBSOCKETS("[WS-Client][sendHeader] Header: \n%s\n", handshake.c_str());

#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
...
...
odelot commented 7 years ago

@vitoralvimb @healthineer I've fixed the lib. Now you can use it with the WebSockets library (version 2.0.5) without modifying it

theElementZero commented 6 years ago

hey i am also having same problem, i couldnt understand the problem i have removed PORT from websocketclient file, also AWS ID and key are correct but it doesnt work,

help please

[WS-Client] connected to apigateway.ap-northeast-1.amazonaws.com:443.
[WS-Client][sendHeader] sending header...
[WS-Client][sendHeader] handshake GET /mqtt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJVBP557SD6JXUL5Q%2F20171206%2Fap-northeast-1%2Fiotdevicegateway%2Faws4_request&X-Amz-Date=20171206T103355Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=e44e9da2511de46d4be39c5ebbde9420a4a475c23c29d8ba8b10652ef42b7f47 HTTP/1.1
Host: apigateway.ap-northeast-1.amazonaws.com
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: OEsEtSQzeE2v6C3qnYAuuA==
Sec-WebSocket-Protocol: mqtt
Origin: file://
User-Agent: arduino-WebSocket-Client

[write] n: 554 t: 1197781
[WS-Client][sendHeader] sending header... Done (355247us).
[WS-Client][handleHeader] RX: HTTP/1.1 403 Forbidden
[WS-Client][handleHeader] RX: Date: Wed, 06 Dec 2017 10:34:05 GMT
[WS-Client][handleHeader] RX: Content-Length: 141
[WS-Client][handleHeader] RX: Connection: keep-alive
[WS-Client][handleHeader] RX: x-amzn-RequestId: fc269ab1-da70-11e7-a95b-a316f2cf1c51
[WS-Client][handleHeader] RX: Access-Control-Allow-Origin: *
[WS-Client][handleHeader] RX: Access-Control-Expose-Headers: x-amzn-RequestId,x-amzn-ErrorType,x-amzn-ErrorMessage,Date
[WS-Client][handleHeader] Header read fin.
[WS-Client][handleHeader] Client settings:
[WS-Client][handleHeader]  - cURL: /mqtt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJVBP557SD6JXUL5Q%2F20171206%2Fap-northeast-1%2Fiotdevicegateway%2Faws4_request&X-Amz-Date=20171206T103355Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=e44e9da2511de46d4be39c5ebbde9420a4a475c23c29d8ba8b10652ef42b7f47
[WS-Client][handleHeader]  - cKey: OEsEtSQzeE2v6C3qnYAuuA==
[WS-Client][handleHeader] Server header:
[WS-Client][handleHeader]  - cCode: 403
[WS-Client][handleHeader]  - cIsUpgrade: 0
[WS-Client][handleHeader]  - cIsWebsocket: 0
[WS-Client][handleHeader]  - cAccept: 
[WS-Client][handleHeader]  - cProtocol: mqtt
[WS-Client][handleHeader]  - cExtensions: 
[WS-Client][handleHeader]  - cVersion: 0
[WS-Client][handleHeader]  - cSessionId: 
[WS-Client][handleHeader] no Websocket connection close.
[write] n: 27 t: 1198243
[WS-Client] client disconnected.
[WS-Client] connect wss...

@vitoralvimb @odelot