Ylianst / MeshCentral

A complete web-based remote monitoring and management web site. Once setup you can install agents and perform remote desktop session to devices on the local network or over the Internet.
https://meshcentral.com
Apache License 2.0
4.09k stars 551 forks source link

Meshcentral Agent Proxy Activation Feature to reach agentless Clients on the Agents local LAN #3867

Closed prononext closed 2 years ago

prononext commented 2 years ago

There are always cases where MeshCentral Agent cannot be installed on machines for various reasons, but inside that machines local network you might already have a agent running somewhere.

In that case this agent could be used as a Proxy to reach other agentless machines inside its local network via SSH, SCP, VNC, RDP, HTTP etc. Many monitoring solutions use this functionality for monitoring the local network with just one agent installed (for example Zabbix Monitoring via Proxy).

My Idea is that inside a group (no matter if the Server is WANonly, LANonly or Hybrid) you click on "Add Agent" (better change that to Machine or Client) and have following functionality:

  1. Connection Type: Via MeshAgent // Via Proxy // Direct (When LAN or Hybrid mode is Activated) "Select Proxy" all other is already existent and clear
  2. Proxy Agent (Provide the Agent which is functioning as a proxy in that group)
  3. Connection method (SSH, SCP, VNC, RDP, HTTP)
  4. Hostname/IP of the machine (which is reachable from the selected Proxy)

When this agent is added you will have the same functionality as you would have on local managed agentless devices (when in LAN and Hybrid mode) with the difference that the connection will be made through the selected proxy, which is forwarding and managing the request through updated agent code.

Under this added machine in the General Tab there will be a info that the device is connected to a specific proxy agent, which can be selected to go to that agents proxy settings page.

On the agent which is serving as proxy there is a new "Proxy" tab which is listing the devices info and ports which it serves as a proxy for.

In the Device list the Proxy Agent will be marked as "Proxy" and the machine which is reached though that proxy is also marked that it connects "via Proxy"

Let me know what you think about that idea and the possibility to realize it?

Ylianst commented 2 years ago

I think I will work on this next. My plan would be to use the existing "local device group" code, but select a device you want to relay thru. So, you would need to create a new "Relayed Device Group", select a relay device and you can start adding devices to the relayed group. The SSH/SCP/RDP support would be exactly the same as what is supported now with the "local device group", but it would be relayed.

Let me know if that would work. I don't want to mix devices with agents and agent-less devices in the same device group, it would be difficult to deal with user permissions, etc.

prononext commented 2 years ago

Very nice Ylianst, that would be the way I guess. Thank you!

Ylianst commented 2 years ago

I checked in an initial version of this feature. More clean up tomorrow and should be ready to go.

MC2-RelayDeviceGroup1

MC2-RelayDeviceGroup2

johnnyq commented 2 years ago

This is fantastic, we sometimes need to access firewalls, printers, DVRs, Synology and other devices via their web interface via HTTP / HTTPS This will be a dream!! Thank you!

Ylianst commented 2 years ago

I have been playing around with it and it's powerful. "Local device groups" would work on LAN/Hybrid mode, but this works in Hybrid/WAN mode which is going to be a lot more common. I can just click "Connect" on the terminal and SSH into my home router instantly, no agent required on the router. Almost too powerful.

prononext commented 2 years ago

🥇 This is so nice, can't wait to play around with it 👍

Ylianst commented 2 years ago

Should be out later today.

prononext commented 2 years ago

I was testing the version 1.0.8 and the relay is working very nice over MeshCentral-Router with the local tools like RDP Client, Putty and WinSCP all tested positively, like a charm. 👍

Following tings were behaving strange:

  1. The relay device is showing a connection even it was already closed (including Remote Session logout) for 5+ Minutes
  2. The relay device has no field to show that it is used as a relay for another group
  3. There are no details of the devices inside the new Relay group, aside from the name. IP-Adress and or hostname should be the minium
  4. There is no ping to the device shown and it is online, no matter if it exists or not. Maybe there is a possibility to catch some more data like MAC Adress and Network Interface through network discovery.
  5. The Relay Group Summary Tab, does not list any devices and is empty no matter how many devices are added to the group.
  6. The Devices inside the Relay group do not show any events in the events ab.

Following would be nice to improve and add:

  1. The standard MeshCentral agentless group on LAN Mode gives the possibility to access all agents through the browser which is just perfect and needed for this relay group feature.
  2. Credentials should be possible to save, if point 1 is inside the browser, just like in LAN mode.
  3. HTTP and HTTPs relay to local Router or NAS GUIs sould be added (new device symbol needed for this.

As a conclusion keep as much as possible inside the browser, without external tools like MeshCentral Router, RDP, SSH, or SCP clients, so that credentials and access can be given to users without showing there contents.

Thank you very much for this feature Ylianst you are The Best! 💯

Ylianst commented 2 years ago

Wow, good list. Working thru it now.

For strange behaviors:

  1. I can't replicate this. Are you talking about this? image

  2. Will add that.

  3. No sure I understand the request. I display all the information I have here. You can to display relay device info on this screen?

image

  1. Ha yes. This a problem with both local and relay devices with no agents. Doing a "Ping" without have root access or calling the "ping" command on the shell (this is not efficient if your doing that for 100's of devices) is super difficult. I need to find a good way to ping devices every minute or so.

  2. Fixed that one. I don't have much info, but added what I have.

  3. Looking into that one.

Improvements.

  1. I am not sure what the request is. Really the relay device group and local device group is the same code and should offer the same services. If it's not, let me know.
  2. Yes, that should work now.
  3. I can add that.
Ylianst commented 2 years ago

Added events when you change a delay device...

image

A device will show if it's a relay for a device group...

image

prononext commented 2 years ago

Verson 1.0.10 looks good now, informationwise., only the "Relay for" is not showing at all like it is in your screenshot.

About the Improvements:

No. 1. I am not sure what the request is. Really the relay device group and local device group is the same code and should offer the same services. If it's not, let me know.

Connection Possibilities: image image

Credentials: image image

Sadly mine looks like this and only is working via MeshCentral Router: no webRDP, Files, Terminal and saving Credentials... image image

Maybe there is something missing at my end?

Ylianst commented 2 years ago

I am making improvements that will be in v1.0.11. My "Relay for" screenshots are not released yet.

Maybe your WAN and LAN servers are different? If so, check that your WAN server has the following lines in the domain section of the config.json:

      "mstsc": true,
      "ssh": true,

Also, you need NodeJS v11 or higher for the "SSH" feature to work. Also, add this to the domain section of the config.json:

      "deviceMeshRouterLinks": {
        "rdp": true,
        "ssh": true,
        "scp": true,
        "extralinks": [
          {
            "name": "HTTP",
            "protocol": "http",
            "port": 80
          },
          {
            "name": "HTTPS",
            "protocol": "https",
            "port": 443,
        ]
      },

That adds more links. You can add custom links this way.

prononext commented 2 years ago

With that settings and update to node16 LTS the Web-RDP and Web-SSH appear now, but when entereing credentials it gets black for a second, does not connect and brings me back to the Web-RDP, to enter the Credentials again. Normal RDP Client via MeshCentral Router has no problems. Following Server Error log is appearing:

{
  "name": "node-rdpjs",
  "hostname": "meshcentral.example.com",
  "pid": 10376,
  "level": 40,
  "msg": "NODE_RDP_PROTOCOL_X224_NEG_FAILURE(Failure code:5 (see https://msdn.microsoft.com/en-us/library/cc240507.aspx))\nError: Failure code:5 (see https://msdn.microsoft.com/en-us/library/cc240507.aspx)\n    at new ProtocolError (/home/user/node_modules/node-rdpjs-2/lib/core/error.js:40:8)\n    at Client.recvConnectionConfirm (/home/user/node_modules/node-rdpjs-2/lib/protocol/x224.js:221:9)\n    at TPKT.<anonymous> (/home/user/node_modules/node-rdpjs-2/lib/protocol/x224.js:202:8)\n    at Object.onceWrapper (node:events:646:26)\n    at TPKT.emit (node:events:526:28)\n    at TPKT.recvData (/home/user/node_modules/node-rdpjs-2/lib/protocol/tpkt.js:110:7)\n    at BufferLayer.<anonymous> (/home/user/node_modules/node-rdpjs-2/lib/protocol/tpkt.js:101:8)\n    at Object.onceWrapper (node:events:646:26)\n    at BufferLayer.emit (node:events:526:28)\n    at BufferLayer.recv (/home/user/node_modules/node-rdpjs-2/lib/core/layer.js:91:8)\n    at Socket.<anonymous> (/home/user/node_modules/node-rdpjs-2/lib/core/layer.js:41:9)\n    at Socket.emit (node:events:526:28)\n    at addChunk (node:internal/streams/readable:315:12)\n    at readableAddChunk (node:internal/streams/readable:289:9)\n    at Socket.Readable.push (node:internal/streams/readable:228:10)\n    at TCP.onStreamRead (node:internal/stream_base_commons:190:23)",
  "time": "2022-04-18T15:12:12.354Z",
  "v": 0
}
MatinatorX commented 2 years ago

Just read through the thread, this is extremely awesome to see. I think this is pretty related to an old feature request of mine, #2615. The only difference is, here you have the "relay device" assigned to a device group, with the relayed devices under that device group. This is awesome and especially great for getting access to a large number of relayed devices from one place.

For us, it would be really convenient if we could also put relayed devices in an existing device group (since we manage user permissions using groups assigned to regions). Would it be possible to add that functionality as well? Similar to choosing "Relayed Through Agent" as the group type when adding a new device group, it would be awesome to be able to choose "Relayed Through Agent" as the operating system type when adding a new agent. The you'd just feed it the relay device and local network IP and off you go! Seems like most of the work is already done to allow this. 😉

Do these relayed devices work with MeshRouter Links? This would be a huge and really powerful feature for us, since we have agent-less devices at all of our sites we need access to. This means we use a lot of relay maps, and that means I have to add custom router links to config.json to get MeshRouter links working. If we can assign MeshRouter Links directly to these relayed devices, I will no longer have to make custom links in config.json but instead can do tag-based linking like we do for normal devices, which lets me users create MeshRouter Links just by adding the right tags to a device.

EDIT: Probably should have tried it out before writing all that. Just gave it a go and MeshRouter links work great! I noticed you have to choose a protocol type when adding a device though, why is that? The devices I just tested don't have RDP or SSH, only HTTP, so it's a bit odd to have to have the RDP link there.

Anyways, this is amazing, it's going to save us so much time and training. You're a legend!

Ylianst commented 2 years ago

@prononext - For Web-RDP, I make use of node-rdpjs-2 which does not support "NLA Authentication security layer". It's on their roadmap but they never built it. So, you have to go on the remote Windows machine and enable legacy authentication for RDP. This is unfortunate, I may have to work on adding support for it myself.

Ylianst commented 2 years ago

@MatinatorX Arg. There are 3 devices types the server deals with (Device with Agent, AMT only and Agent-less). Because device groups set policies on these devices, a device group can only handle one device type. So, a device group is hard set to only contain one device type and you can't move a device to a device group of a different type. I am not likely to change this since I need to make it clear what policies are applied to each device. However I am open to create device security groups in the future when you would add a device to one or more device security group and set permissions for that. It would be a bunch of work.

For "I noticed you have to choose a protocol type when adding a device though" - Are you talking about selecting "Windows", "Linux" or "MacOS"? This will set what protocols the device supports, I am open to improving that.

MatinatorX commented 2 years ago

@Ylianst Ah, that makes sense. Well, the way it works now is still super useful for us, it will just be a bit more effort managing permissions across multiple device groups that most users will need access to.

I was thinking a way to skirt around that would be a feature request to allow a device or device group to inherit its permissions from another device or group, but with what you just explained I imagine this would only be possible with devices and device groups of the same type, so not a solution.

For "I noticed you have to choose a protocol type when adding a device though" - Are you talking about selecting "Windows", "Linux" or "MacOS"? This will set what protocols the device supports, I am open to improving that.

Yep, in my case most of the relay devices I want to add don't support any of the associated protocols that get added when you choose an OS. Things like BACnet devices and MSTP routers running on microcontrollers - you get an HTTP configuration interface (HTTPS if you're lucky) and that's it.

The way you have it now, choosing an OS is required to add the device, and then the associated protocols are mapped to router links automatically, whether I need them or not. It's not a huge issue, but it would be nice if there was an option to set the type to "Custom" or "None" which wouldn't create any router links automatically.

prononext commented 2 years ago

@prononext - For Web-RDP, I make use of node-rdpjs-2 which does not support "NLA Authentication security layer". It's on their roadmap but they never built it. So, you have to go on the remote Windows machine and enable legacy authentication for RDP. This is unfortunate, I may have to work on adding support for it myself.

Lets support to get NLA finally implemented: https://github.com/citronneur/node-rdpjs/issues/52

Going with legacy mode is really a security risk...

NiceGuyIT commented 2 years ago

The author or the original node-rdpjs went on to write a Rust implementation (rdp-rs) because:

On one side, Remote Desktop Protocol is a complex protocol, and it's hard to play easily with it. I've already implemented RDP in Python and Javascript with an event driven pattern. It appears that this kind of pattern raise the complexity of the library, and at the end there is a lot of bugs and no PR, and nobody can't play with RDP in deeper.

On other side, there is no secure implementation of the RDP protocol open sourced.

In the end, I would like to build a highly secure, cross-platform and highly customizable client.

I know you can't run Rust in a browser unless you cross compiles to WASM or maybe something else. Searching for WebAssembly RDP leads to myrtille. I didn't dig deep and there may be others. I bring this up because using WebAssembly in the browser may improve performance and provide other benefits like NLA.

I'm a MeshCentral user and have a vested interest in seeing it improve. Thank you for an awesome project!

Ylianst commented 2 years ago

@prononext I will give NLA implentation a try tomorrow. My understanding it that it's more-or-less RDP within TLS, but there is some data that to cause the switch into TLS. If this is correct, I should be able to do it. I do agree that legacy RDP is a security risk.

@MatinatorX I am totally willing to improve the protocol selection for local devices. At some point, I should put some time on it. Local devices are going to be getting more use now that you can relay them thru agents.

MatinatorX commented 2 years ago

@Ylianst Awesome, just an option to add a relayed local device without any protocols would be really helpful.

I was thinking a bit more about how to show relayed local devices together with their parent relay device without having them share a device group. Could be an option to move them from the My Devices page to a tab under the parent relay device instead, like a mini My Devices page just for the relayed local devices.

This would keep the main My Devices page from getting too bloated, which is becoming issue for servers with lots of devices. It would also make it easier to find all relayed local devices under a specific parent relay device.

Let me know what you think and if this should go in a separate feature request.

Ylianst commented 2 years ago

@MatinatorX Interesting request. Basically, I would hide the relayed local device group and just display them in a sub-area of the device acting as a relay. It would be some work because when a sub-device changes it's state, I have to also send the message to the relay device so the web page stays current. I currently support changing what device acts as a relay for a device group, that would also need to be adjusted.

UPDATE: I am currently deep into trying to port RDP NLA support from RDP-RS to NODE-RDP-JS2. It's complex with a lot of crypto and packet decoding/encoding work, it does not help that I have never read a line of Rust core before. I am going to have to send a HUGE thank you to @citronneur for writing that code. The Rust version has test cases in the code I used to check that my code was correct. It's going to take a while longer, I think I am 50% of the way there. If this works, I am thinking I may work on adding RDP support rights into the "Desktop" tab. Seems like that would be super nice.

MatinatorX commented 2 years ago

@Ylianst That's exactly what I had in mind. For us, it's not important at all the be able to change the relay device.

I'm going to stick this in a new feature request and close my old one.

Ylianst commented 2 years ago

Just published MeshCentral v1.0.13. The built-in RDP web client now has NLA support, so you can RDP to computers from the web site without needing to enable "Legacy Authentication" on the remote device. In addition to this, the RDP client is now enabled by default, so you don't need "mstsc": true inthe domain section of the config.json to enable it anymore. However, you can disable it with "mstsc": false. Let me know if it works.

MC2-RDP-NLA1

MC2-RDP-NLA2