php-mqtt / client

An MQTT client written in and for PHP.
MIT License
372 stars 72 forks source link

Looking for ALPN TLS support to connect to AWS IoT #180

Closed jonofe closed 5 months ago

jonofe commented 5 months ago

Hi Guys, I'm looking for a MQTT PHP library, which supports APLN (Application Protocol Layer Negotiation) to connect to AWS IoT MQTT service on Port 443. Does this client support ALPN TLS? If not, could that be added? Thanks in advance for a short feedback. Regards André

Namoshek commented 5 months ago

If I'm correct, APLN is an HTTP feature which implies that WebSockets are the indended communication channel in your case. If that's the case, the answer is no and this is not something I'm planning to implement. At least not myself, I'm always open to contributions though. However, I'm not sure how feasible and easy it would be to implement a second, WebSocket based MQTT client in PHP to begin with. Last time I was looking for a proper implementation wasn't really fruitful.

jonofe commented 5 months ago

As far as I understand it does not imply WebSockets. It's MQTT over a TLS connection on port 443. So for example using the mosquitto_sub cli tool, I'm able to connect with the following command:

mosquitto_sub -k 45 -d -c -v -h $mqtt_host -p 443 --tls-alpn mqtt --cafile ./cacert.pem -i $mqtt_client -u $mqtt_user -q 1 -t

Only the option --tls-alpn mqtt makes the difference.

And I saw in the PHP 7.0 changelog:

_Added "alpn_protocols" SSL context option allowing encrypted client/server streams to negotiate alternative protocols using the ALPN TLS extension when built against OpenSSL 1.0.2 or newer. Negotiated protocol information is accessible through stream_get_metadata() output.

First I thought, may be it's only adding the alpn_protocols option to the tls context for the stream_context_create. But I can't really judge.

Namoshek commented 5 months ago

Maybe worth a look and yeah, that's where it should go in this case. I won't be able to work on this before the weekend though and I'm not sure I've the necessary setup to even test this. A PR would be appreciated.

But anyway, do you really need to use port 443? I've tested AWS IoT before with this library (see closed issues) and I don't think I had to work around this issue.

jonofe commented 5 months ago

I will have a look, but I'm not sure I have the necessary programming skills to solve it. :) Will let you know...

Background of my question is the usage of the unofficial Worx Landroid API in a PHP home automation project. Home automation systems like FHEM, ioBroker and Home Assistant have already implemented it, but all of them documented, that it only works with TLS ALPN support. So probably in that specific case, the only option.

But in general you are right, there are different connectivity options to AWS IoT Core service. I tried already port 8883 without TLS-ALPN and couldn't get it to work.

jonofe commented 5 months ago

Wasn't so complex as I initally thought. :) Just created a pull request (#181), which I was able to test against AWS IoT Core on TLS encrypted port 443.

Namoshek commented 5 months ago

PR is merged and released. Thanks for this addition!

christoph-kluge commented 1 month ago

Just adding a comment for those who might stumble around this issue when searching for AWS IoT.

AWS IoT via 443 + ALPN must use x-amzn-mqtt-ca as alpn as described here: https://docs.aws.amazon.com/iot/latest/developerguide/protocols.html

->setTlsAlpn('x-amzn-mqtt-ca')