marsuplane

joined 1 year ago
MODERATOR OF
[–] [email protected] 1 points 8 months ago

Mles v2 is now published!

9
submitted 8 months ago* (last edited 8 months ago) by [email protected] to c/[email protected]
 

Hi! Mles (Modern Lightweight channEl Service) protocol with Rust-based reference implementation is on the path to upgrade to v2. The new version will be simpler and more secure. In case interested how to make the protocol v2 draft even better, please join discussion and comment on [email protected]. Thanks!

 

Mles protocol version 1.0 is deprecated and will be obsolete from the beginning of the year 2024 in favor of Mles v2.

If you have implemented Mles 1.0 protocol-based things on top of mles-websocket protocol, the upgrade is very simple: just send as a first message to the Mles-server a JSON structure based on the Mles v2 header (the JSON structure will be finalized soon). No other changes are needed!

If you have implemented Mles 1.0 based protocol, please consider upgrading to Mles v2. The benefits are:

  • up-to-date simplified server framework with even better performance
  • safety built-in with mandatory TLS messages via Let's encrypt-certificate over ALPN-TLS
  • only port 443 needs to be open, no need for the 80 or 8077 ports anymore

Comments are welcome! Cheers!

1
submitted 10 months ago* (last edited 10 months ago) by [email protected] to c/[email protected]
 

Previous prototype round leaned towards TLS-only solution and the direction has been fruitful. It offers a possibility to simplify Mles v2 further.

It has been possible to connect to Mles server via WebSocket proxy. This is handy as e.g. JavaScript web browsers support this out-of-the-box. There is also nice Rust tooling around that via e.g. websocat which supports secure WebSockets (WSS). As can be imagined, also JSON is supported by JavaScript and other tools well.

With a JSON structure as a connect initiator over WSS, we can simplify Mles v2 protocol to work over WSS-only. The SipHashing defined earlier for Mles v2 can be moved to be an internal operation which guarantees the same duplicate user identification and peering as before. Connections will be guaranteed to be secure as WSS to public 443 port guarantees proper certificate checks.

The above has been prototyped already and works splendidly well. The coming weeks are used to finalize the implementation to production quality. Earlier Mles v1 will be deprecated as of now. IANA port 8077 reservation can also be dropped in the future.

In practice, the Mles web-proxy and server will be merged to be a server binary. The client and library implementations are not needed anymore. A simplified client with websocat command line will be provided as an example. This all helps in maintenance of v2 for the next decade. Peering-feature will be postponed from first release.

As an attempt to break away from big company ecosystems, the MlesTalk application will be targeted to be published later as a new MlesTalk FOSS with strong E2EE support based on the Zpinc protocol implementation.

Further updates and guidance how to help will be provided in later updates here.

Thus, big changes are coming, any comments or questions so far?

1
submitted 10 months ago* (last edited 10 months ago) by [email protected] to c/[email protected]
 

After some weeks of prototyping, what are the results?

Libp2p as such was working as specified. Nevertheless, there are couple of issues regarding the Mles protocol:

1. frame check works only for the frames we receive on the channel

This means that to be able to check the validity of the first frame, the server would need to be on the same channel as the clients. This is problematic, as the channel should be selected by client to be anything...

OK, let's assume that we pick reserved "__mlesv2" channel for the first frames. It looks hacky already, but anyway, what would work or not? And we come to the second issue:

2. retransmit during reconnection does not work per channel

For new clients, we cannot really select any connection to send to as there no existing api to publish only to a peer. The server would need to flood the network to be able to send the message history to a new client. And if we have the "__mlesv2" way of communication, all clients of any channel would receive them. Not a way to go.

Well, that's what prototyping is for. We quickly spot possible issues with the design.

When I think about it, perhaps a simple TLSv1.3 connection would be fine even for direct server connection. There is some hassle with the certificates, but it may be possible to use the TLS-ALPN-01 way for public server and manual methods otherwise.

If no one comes up with a better idea, this is in the focus of next prototyping effort and very likely the first alpha implementation for Mles v2.

Comments are welcome! You can also comment if you think this is the way to go!

 

With Linux based devices, Mles 2.0 support is easy to achieve. There are a lot of existing libraries and programs that allow to create WebSockets over TLS connection with the Mles 2.0 simplified Json header structure. ChatGPT can write with little guidance a basic bash program that communicates over updated Mles.

How about embedded devices without Linux? Or Rust no-std programs? In the Rust ecosystem there exists already support for both, embedded websockets and embedded TLS. They have no-std ability. I already have an ESP32-Rust-C3-devkit based device where I can prototype this and share the implementation.

Summa summarum, it should be possible to use updated Mles 2.0 even with embedded devices without Linux. It is important as the new Mles 2.0 APIs have guaranteed security built-in, TLS for the websockets API and Noise for the distribution API. These APIs should provide a valid baseline to build on long into the future.

1
submitted 11 months ago* (last edited 11 months ago) by [email protected] to c/[email protected]
 

We have in previous posts dvelved into protocol and messaging framework improvements. The ideas presented earlier seem still solid after some time. Grand.

How about the server internal structure? It has two APIs, WebSocket interface via TLS port, and port 8077 for peer-to-peer server connection. Earlier, the websocket-proxy was a separate instance and the server itself had either centralized or peer configuration. With the new full peer-to-peering capabilities, the same logic can be applied or the instances can be merged. Running port 443 open is not everyone's cup of tea, so if the capabilities are merged for simplification, some configuration options are needed to define the proper roles for the instance. Comments are welcome!

Regarding the Mles 2.0 library support, the proper improvement would be to still offer libraries for clients with no-std support (now missing). The server part will leverage the libraries, of course.

The next steps are to prototype the implementation into port 8078 and see how it works. Initial development already exists. Please comment, or let me know otherwise, if you'd like to join either in development or testing.

Cheers!

1
submitted 1 year ago* (last edited 1 year ago) by [email protected] to c/[email protected]
 

Mles v1.0 has a hierarchical structure with a centralized-looking main server. It is in theory possible to have a ring of servers but that is not available anywhere at the moment and the such environment might become hard to maintain.

More optimal would be just being allowed to use peer-to-peering. The relevant features would be similar to 1.0 still, guaranteed message delivery for the message history and scalable publish and subscribe for the selected shared channel (i.e. topic) in a secure way. With the rise of crypto-blockchains, such peer-to-peer libraries are nowadays available, widely used, tested, and maintained, such as libp2p. As a protocol e.g. gossipsub with noise + yamux would be fairly good from the requirements perspective. Veilid is also a newer option, but is less documented at the moment.

In the end, the library implementations and their APIs matter the most. Libp2p in Rust allows to check messages received in their API and this would allow to check the SipHash checksum/authentication in the connection init.

The Mles v2.0 server itself would then listen to client connections and connect to bootstrap server (list) during startup. A good question is how would the clients connect then? They could indeed connect via a selected libp2p connection to port 8077 or via wss to port 443. A non-secure connection would not be allowed anymore.

Would this be then simple for clients to implement? I think so. Clients could be easily written with libp2p API or a netcat-like simple implementation could be created with websocat. A prototyping is needed to finish the details, of course. That's enough for today. In case you end up prototyping the above things, let me know how it worked!

 

Mles originates from October 2016 and the Mles message structure has been the following since the v1.0 release

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | ASCII 'M'(77) |            Encapsulated data length           |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |            CID (lowest 4 bytes of initial SipHash)            |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +                          SipHash                              +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         CBOR encapsulated data (uid, channel, message)        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

It had pretty modern aspects included such as

  • Large data length support, up to 16 MB framing
  • SipHash authentication
  • CID handling with peer servers
  • CBOR

Even though it has served well for almost a decade now, there exist certain issues with it as an open Internet protocol header, such as a) Framing does not have a checksum b) The default SipHash authentication does not work really for connections behind NAT c) CBOR d) Header overhead

Let's check the above cases in detail.

a) Why would we need a checksum over TCP you may ask? Well, you do not need it for data for sure, TCP has one already. Nevertheless, the server side has use for it to identify and drop false random-data bot-connections. And there are often a lot of them, which just happen to start with ASCII 77.

b) Yes, the SipHash did a good job authenticating the TCP endpoints. Unfortunately, behind a NAT the client cannot really know its IP, so shared key was in the end the only working solution for IPv4 servers.

c) CBOR as an (IETF) format sounds nice, but in practice is awkward to both implement and use. It does not really save that much space compared to e.g. JSON, it cannot be easily read on the captures and the most popular crate is now deprecated.

d) Header overhead is pretty extensive for very short messages. The specification says that the use of SipHash can be ignored, but still needs the header fields and CBOR structures for every frame. Do we really need them, every time?

You may have encountered or noticed other issues too regarding the message structure. If so, please let me know, let's fix it.

Regarding the above issues, what would be the concept for the next-generation message structure then? Perhaps not that different, to be honest, see below draft:

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | ASCII 'N'(78) |                  Data length                  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +                          SipHash                              +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |           JSON encapsulated id data (uid, channel)            |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Even though the fields are quite the same, the way we use them will be different and hopefully will solve all of the above issues:

a) The SipHash field will include the header as well and therefore be the checksum for it. The weak dependency on CID will be removed, obviously, as there is no CID anymore, the SipHash is the CID.

b) The SipHash authentication for IP endpoints will be dropped. A shared key can still be part of SipHash authentication, by default the header + the channel are the authentication.

c) Let's drop CBOR and use JSON. And especially, let's not encapsulate the data into JSON. JSON is supported everywhere and is easy for client implementation.

d) After the first initial frame, the connection is authenticated and identified, we do not need the SipHash or JSON anymore. The next frames will use the following format:

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                       Data (raw bytes) ...                    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The first frame cannot hold more data than the JSON identifiers, but after that we avoid all the overhead allowing the application to decide the framing.

That's it for this time! This is all draft and you are free to comment, thanks in advance! The presented changes will certainly cause changes to other areas of the protocol. What they are, we check in detail next time. See you then!

 

Awesome new networking framework, reminds me of Mles design principles.

1
submitted 1 year ago* (last edited 1 year ago) by [email protected] to c/[email protected]
 

Mles is aging and references to "modern" and "lightweight" need constant evolving. The earlier state-of-the-art features need an upgrade.

So, what would be the preferable new state-of-the-art technology for next generation?

Based on earlier feedback for Mles during its existence, a more distributed approach would be preferable (even though it is not quite centralized, at least in a common sense). Another suggested feature is strong end-to-end encryption with hidden group member interactions.

Not bad suggestions. And they are nowadays achievable with surprisingly low effort.

Personally I think also CBOR encoding has proven to be awkward, why not ditch it for JSON headers to ease client implementation development? It would be awesome to be able to write a client with a few lines of bash + Netcat. I would call that "lightweight" :)

As a list, I'd summarize the next gen as follows:

  • Fully peer-to-peer communication
  • State-of-the-art encryption with established distribution protocol (e.g. Noise)
  • Hidden protocol headers to avoid group level user interaction monitoring
  • JSON format for optional extended headers
  • Anything as payload

I already have a prototype implementation in my mind. I'll publish a 2.0 beta at some point. Let me know if something is missing.

 

Welcome to the federated Mles channel!

view more: next ›