Make the API listens to a TCP Socket

Hi. From what I understand, klippy’s api is only listening on a unix socket. We can change the socket path, but it’s only possible to bind to a local file. Is there a technical reason for that ?

I’ve bought a Flashforge Adventurer 5M pro and there is a klipper mod available for that printer. But klipper + moonraker + UI are consuming a lot of ram and ressources. The goal is to have the minimum processes running locally on the printer, and run the others somewhere else, on a faster CPU. We don’t have a direct access via uart or usb to the MCUs of the printer, only a LAN port.

If Klippy could listen to a TCP socket. We could at least run moonraker outside of the printer and have more ressources available on it. Do you think it’s a good idea ? If there is no technical issue about this, I can send a PR to make the configuration accept TCP sockets (and also another PR for Moonraker).

Thanks for your answers.

add-tcp.patch.txt (5.0 KB)

Here is my modification, you can use UNIX and TCP at the same time or choose one or the other.
A similar simple modification to moonraker can also be used to use TCP connections.
For reference only.

This is a good patch and it solves my problem.
I can’t find PR with this change on GitHub. Why?
IMHO, this is a basic feature everyone needs.

I don’t think this is a feature that can be merged into the mainline.
Only for players who prefer to toss around.

I’ve just created a PR. You can give it a try : Allow Klippy to listen to a TCP socket by Toniob · Pull Request #6826 · Klipper3d/klipper · GitHub . Just use the same argument (-a) but with a url tcp://ip:port .

I’ll try to make a PR to moonraker too.

I’m totally disagree with you. This is a very useful feature.
Previously, I thought this is only useful to containerization purpose, but now I see how useful this. First off all, you can split moonracker and klipper for a stability purpose.
I think, this should be merged and I’m happy to use your patch.

Moonraker isn’t intended to run on a different machine from the Klippy host. Some of its functionality with regard to administrating and updating Klipper requires that they run on the same machine. With that in mind I couldn’t accept a pull request that adds partially broken functionality to Moonraker. That said, its certainly possible to work around those limitations if you just want to run your own personal fork.

With regard to the current PR, when Klippy’s API server was in development TCP sockets were ruled out rather quickly. IIRC we didn’t want to allow unsecured remote connections to Klipper. This is one reason Moonraker was created. it provides authenticated (and optionally encrypted) remote access to Klipper.

2 Likes

What are your concerns here?
In my experience, Moonraker has never caused any stability issues and is very lightweight, thus running smoothly on very low-end SBCs.

The frontends along with the web server are more resource-demanding but can be relocated easily already today.

Don’t you think it’s up to the users to choose ? That’s why on my documentation PR I put a warning on the security if the IP is accessible from the internet. My vision is just to give another feature to the users, it’s up to them to use it or not. I also did not change the defaut behavior, which will remain to have a unix socket. For the security of the TCP socket, it’s something that can be managed with a firewall.

Beside Klipper’s update, which features require Moonraker to be on the same host as Klipper ? Something that would prevent to print ?

Security wise, we could run Moonraker on another host, or on the same host but with another user.

Did you check my PR ? It’s not a big deal, these are minors modifications and it’s not gonna cost any maintenance. Once it’s merged, it can stay like that. Currently, there isn’t any check on the unix socket and if you put an inaccessible path, there are no logs but a big stackstrace. My code enhances that behavior.

1 Like

I’m running a mod on my printer (Flashforge Adventurer 5M Pro). The official firmware uses a modified version of Klipper, without Moonraker and with a custom UI. And with the mod (Klipper, Moonraker, Fluidd, Mainsail and optionally a touchscreen UI), there are sometimes issues and a “MCU Shutdown” error.

I’ve just booted my printer, and here is what I have :

free with everything running :

              total        used        free      shared  buff/cache   available
Mem:         110404       68160        6768          16       35476       38624
Swap:        131068         768      130300

free without fluidd and mainsail :

              total        used        free      shared  buff/cache   available
Mem:         110404       67916        6924          24       35564       38860
Swap:        131068         768      130300

free without fluidd, mainsail and moonraker :

              total        used        free      shared  buff/cache   available
Mem:         110404       46968       27780          28       35656       59788
Swap:        131068         768      130300

Stopping Mainsail and Fluidd doesn’t free a lot of memory. Stopping Moonraker is really efficient. Running it on another host would really be nice.

Using the SDK provided by the manufacturer in some micro MPUs, compiling moonraker’s py library for its SDK is a huge project. Relatively speaking, klipper has fewer dependencies.
The control client in the LAN can use TCP to connect to klippy, skip moonraker, and perform some simple control.
Of course, I also think it is not necessary to merge this into the main line. It is only suitable for “playing”.

In my opinion, these statistics have very little to no value. The only true value is that under no circumstances is there any swapping.

Linux is very efficient at reserving and preallocating memory for processes in case it is needed. It is equally efficient at reallocating this memory to a different (newly started) process.
If you are experiencing swapping, it becomes critical because it has a significant performance impact.

In any case, neither should be the root cause of an “MCU shutdown,” which is not a Klipper error message by itself. Deeper analysis with a klippy.log would be required.

It isn’t possible to merge every feature that every user desires, ultimately the project maintainer needs to weigh the pros and cons of any change and make the decision. I wanted to share feedback based on what I recall at the time the API server was developed, but I don’t know what decision Kevin will make on the PR.

For the security of the TCP socket, it’s something that can be managed with a firewall.

It could be, but its an additional step required outside of Klipper. Most users will have routers that block in coming connections over the WAN. The worst exposure would be 3d printers in public settings such as labs. If the port was open to the LAN so local apps can connect anyone with access to the network can take over the printer.

Updates, service management and monitoring, system monitoring, and file management (logs, config, gcodes, config examples, etc) would be impacted. Planned features like Klipper extension management and MCU firmware updates would also be impacted. Printing should still be possible, as I previously stated you should be able to work around these issues for personal use.

Did you check my PR ? It’s not a big deal, these are minors modifications and it’s not gonna cost any maintenance.

Ultimately Kevin will make that decision. If he declines it doesn’t sound like it will be much work to maintain a personal fork.

Currently, there isn’t any check on the unix socket and if you put an inaccessible path, there are no logs but a big stackstrace. My code enhances that behavior.

A PR limited to socket path validation would have a good chance of being accepted IMO.

Frankly, if I had hardware concerns and only had access to a LAN port I would consider moving both Klippy and Moonraker to another host and use ser2net/socat to bridge the MCU over ethernet.

1 Like

I got no problems with Moonracker itself, but I have my own graveyard with at least 20 SBCs there. If it’s possible, I’m moving any compute load to my cluster of servers with Xeons and ECC memory.

Secondary, I’m SRE and I prefer to use declarative descriptions for any load I have. Ofc, I’m the crazy one with printing software in k8s in locker room, but look at mkuf/moonraker image on Docker Hub — it’s 50k pulls and it’s a number. Currently, I use socat to run moonracker, and this is ugly and creepy solution.

This is not just about moving out from the host, it’s also usable to easily dockerization without mounts and other unnecessary solutions to share the socket.

If you really scare about security, it’s fine to start with allow-list of ips/subnets. But in my opinion, this is not necessary in containerization and network should be secured by runtime.

Please, let us use native solutions without any forks and ugly helpers.