8000 client_server example rewrite to uasyncio v3. · Issue #43 · peterhinch/micropython-async · GitHub
[go: up one dir, main page]

Skip to content

client_server example rewrite to uasyncio v3. #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
beyonlo opened this issue Aug 10, 2020 · 9 comments
Closed

client_server example rewrite to uasyncio v3. #43

beyonlo opened this issue Aug 10, 2020 · 9 comments

Comments

@beyonlo
Copy link
beyonlo commented Aug 10, 2020

Hi Piter!

Two questions:

  1. Is the StreamWriter/StreamReader still the best idea/strategy to works with uasyncio v3, I mean, in async mode (no blocking) TCP/IP socket Client and Server, like as this https://github.com/peterhinch/micropython-async/tree/master/client_server used in uasyncio v2?
  2. If yes, could you please, to rewrite it to use the uasyncio v3, like as you did with UART example (ported to uasyncio v3) that are using as well the StreamWriter/StreamReader idea https://github.com/peterhinch/micropython-async/blob/master/v3/as_demos/auart.py ?

Thank you so much :)

@beyonlo beyonlo changed the title client_server examples rewrite to uasyncio v3. client_server example rewrite to uasyncio v3. Aug 10, 2020
@peterhinch
Copy link
Owner

It needs tidying up to conform with the new syntax, but uasyncio V3 does support the old event loop approach. A quick test on a Pyboard D, running the server under the Unix build on my PC, proves that the code does run under V3.

I will produce an updated version in due course.

In answer to your general query, StreamWriter and StreamReader are (in my view) still the way to do this. @damien plans improvements to the underlying select/poll mechanism to improve the performance of stream I/O, so applications using it should automatically benefit.

@peterhinch
Copy link
Owner

I have ported this to V3 in the directory v3/as_drivers/client_server. This is alpha code and is not yet documented: I've tested it with the client running on a Pyboard D and the server running on the Unix build. I believe it is still portable, but need to find time to test it.

The server now uses asyncio.start_server() which I believe has improved since V2. It simplifies the code.

The server code may change: asyncio.Server is evidently designed to be used in an asynchronous context manager. If I can figure this out I may make this change.

I'd be grateful for any observations, bugs, ideas or test reports.

@beyonlo beyonlo closed this as completed Aug 12, 2020
@beyonlo beyonlo reopened this Aug 12, 2020
@beyonlo
Copy link
Author
beyonlo commented Aug 12, 2020

@peterhinch

Sorry for "close" and "reopen" this issue, was just a wrong click.

Thank you for the port to v3, I will test soon as possible :)

Another question: is easy to add SSL support to this client_server example, to be a secure TCP/IP connection?
Ps: I'm using ESP32

Thank you.

@peterhinch
Copy link
Owner

I don't know. I've only tested this demo on a local network. There have been issues around running TLS on nonblocking sockets. My understanding is that this works on Pyboard D but may not on ESPx targets which use a different network stack. But I may be out of date and I'd suggest a forum search or query on that one.

I'm an electronics guy rather than a network programmer or security expert. However I have doubts over the wisdom of running TLS on bare metal targets for reasons discussed here.

@beyonlo
Copy link
Author
beyonlo commented Aug 12, 2020

@peterhinch

I'm an electronics guy rather than a network programmer or security expert. However I have doubts over the wisdom of running TLS on bare metal targets

But MicroPython are not running as baremetal, it runs as a task of FreeRTOS, right?
I always thinking IoT mostly over internet, so is basic concept to me the TCP/IP connection to be mandatory secure socket.

for reasons discussed here.

Sorry, could you to clarify to me, is this link correct? it go to micropython-iot, where has no "discussions", no threads.

Thank you so much.

@peterhinch
Copy link
Owner

But MicroPython are not running as baremetal, it runs as a task of FreeRTOS, right?

That depends on the platform. It is true for ESP32, but on Pyboards (1.x and D) it runs on baremetal, also on many other platforms. But bare metal isn't the issue here. Lazy writing on my part.

I evidently did a poor job of explaining my point. I have doubts about the wisdom of IOT devices accessing the internet for reasons I tried to present in the link. I prefer an architecture in which the IOT devices communicate with a server using a simple socket-like interface. An interface designed to be resilient in the face of WiFi outages. The server, which can be something cheap like a Raspberry Pi, communicates with the internet. It uses TLS. Because it runs Linux it can be kept updated and secure. The multiple IOT nodes do not need constant security upgrades because their communication protocol is simple and limited. What can an attacker do with a JSON string? Unless your application sends executable code (NO) it's easy to trap and reject malformed strings.

Aside from security, TLS is demanding of resources. Further, WiFi outages are common. WiFi connected PC's hide brief outages from the user but "bare metal" and ESP32's do not. Here brief outages occur about once an hour. Any communications operating over WiFi need to take account of this. For example the official MQTT library is utterly broken in this regard. I don't know the implications of this for long term connections to internet resources. If your application periodically sets up a link, uses it, and shuts it down it will probably be OK. If you need to keep it open 24/7 I have my doubts.

@beyonlo
Copy link
Author
beyonlo commented Aug 13, 2020

Hi @peterhinch

I evidently did a poor job of explaining my point. I have doubts about the wisdom of IOT devices accessing the internet for reasons I tried to present in the link. I prefer an architecture in which the IOT devices communicate with a server using a simple socket-like interface. An interface designed to be resilient in the face of WiFi outages. The server, which can be something cheap like a Raspberry Pi, communicates with the internet. It uses TLS. Because it runs Linux it can be kept updated and secure. The multiple IOT nodes do not need constant security upgrades because their communication protocol is simple and limited. What can an attacker do with a JSON string? Unless your application sends executable code (NO) it's easy to trap and reject malformed strings.

Just to explain your scenario:

======== no secure ======== secure ========
ESP32-01---------------|
ESP32-02---------------| RPI *********************** Cloud/Server
ESP32-03---------------|

I understand you, but with this scenario we have many problems:

  1. Trusting just on security WiFi (WPA/etc) for the local network (between IoT devices and Gateway - RPI) is not a good idea. As connection is WiFi, someone can to hack near on the IoT solution to get data from all devices, and many cases that information is very relevant. I can't to see the possibility where has no secure (SSL) even in local network.
  2. RPI is not so cheap for that. Trust me, RPI in many countries after imported, price go to 100% to 200% more (high taxes from theses countries).
  3. RPI use so much energy compared with ESP32.
  4. Some cases, many cases make no sense to be a gateway for ONE device, like as the case that I will wrote bellow (about electric motor)

I agree your scenario if we can use ESP32 instead RPI (may be can be another microcontroller) as Gateway, but even in this scenario is essential SSL between iot devices and gateway (ESP32):

======== JSON-RPC ================ JSON-RPC ==============
======== secure ===================== secure =========
ESP32-01*************|
ESP32-02*************| ESP32 (8MB RAM) *********************** Server Linux
ESP32-03*************|

This scenario above I already using (except secure - SSL) as tests, and is my goal. I'm using a clean and light JSON-RPC over a TCP/IP socket between ESP32 devices and ESP32 Gateway.

Aside from security, TLS is demanding of resources.

Resources actually is not a problem for all microcontrollers, like ESP32 where is the default (and cheap) come with 4MB RAM on ESP32-WROVER modules.

Further, WiFi outages are common. WiFi connected PC's hide brief outages from the user but "bare metal" and ESP32's do not. Here brief outages occur about once an hour. Any communications operating over WiFi need to take account of this. For example the official MQTT library is utterly broken in this regard. I don't know the implications of this for long term connections to internet resources. If your application periodically sets up a link, uses it, and shuts it down it will probably be OK. If you need to keep it open 24/7 I have my doubts.

I understand you, but is a developer responsibility to put a "ping" to test frequently if connection is OK. Actually I have a ESP32 connected to an electric motor and ESP32 sending information (voltage/current/etc) to the server/cloud over a WiFi AcessPoint (Dlink) 24x7. The connection between ESP32 and Server is a persistent connection, NO sets up a link, uses it, and shuts it down, because Server can send data to change motor configuration or acting on motor (sending a command) to ESP32 shutdown the motor, for example, so connection between ESP32 and Server need to be always open, all the time. This already working 8 months (24x7) without problem. When a "ping" or a send JSON-RPC message (with ACK) do not receive answer, I do in ESP32 a reconnect to WiFi. Follow the scenario:
AP DLINK
ESP32 -----------JSON-RPC --------------- Server Linux
======== persistent connection ==============

About MQTT 24x7, I have no experience, but I think is possible to do a "ping" using MQTT too, right?

I could tell you infinite applications/solutions where is no possible to use a gateway for IOT devices, I mean, where IoT devices need to be connected directly to the server/cloud with secure mode, like as a tracker (connected via WiFi/4G(using PPPoS - I'm using it)). So that is clear that we need to add a SSL on TCP/IP socket and use Writer/StreamReader socket over that secure socket. That is the perfect, perfect.

Please, think about that :)

Thank you so much!

@peterhinch
Copy link
Owner

When it comes to security we need to be clear about the threat. I agree that my IOT solution does not protect against interception of the information flowing between the server and the ESP's. In many cases the data is just sensor values and it simply doesn't matter. But I agree that there is a case for TLS on the WiFi link if data is confidential. The IOT solution just uses a socket, so TLS could be used if the problem of TLS on nonblocking sockets were fixed.

A reason for the IOT design is to protect against the risk where unpatched, Internet-connected devices are taken over by an attacker. Since the IOT solution exchanges only JSON strings it is hard to see how this could occur. I believe that internet-connected devices should regularly be patched with the latest security updates. This is more practical with a Linux based SBC than with a host of remote devic 8606 es.

As for the pricing of such devices worldwide, I take your point. The power consumption of one of the simpler Pi's is about 5W.

MQTT is another option which I have addressed. I have tested this with TLS on a Pyboard D. The last time I tried TLS on ESPx it didn't work owing to the nonblocking socket issue. This is a major issue which (as far as I know) has not been fixed. Search for TLS in this discussion.

Until the maintainers fix this issue, the use of TLS on ESPx with uasyncio seems impractical.

@peterhinch
Copy link
Owner

Closing as TLS issues have now been fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants
0