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
3.68k stars 511 forks source link

meshctrl.js throws missing netif error on deviceInfo read #6097

Closed timaw7 closed 1 month ago

timaw7 commented 1 month ago

Describe the bug

I'm attempting to use meshctrls.js script to trigger API commands to the server. I've started with the deviceInfo command, but this is throwing errors on specific devices but not on others. Just to note, I've been able to modify it to work, but it is having unexpected results and requires someone more familiar with the software to take a look.

This is the thrown error on an attempted run for one device. Another functioning device is noted below.

/home/meshctrl.js:2837
    if (network.netif != null) {
                ^

TypeError: Cannot read properties of null (reading 'netif')
    at displayDeviceInfo (/home/meshctrl.js:2837:17)
    at WebSocket.incoming (/home/meshctrl.js:2055:60)
    at WebSocket.emit (node:events:513:28)
    at Receiver.receiverOnMessage (/home/node_modules/ws/lib/websocket.js:1209:20)
    at Receiver.emit (node:events:513:28)
    at /home/node_modules/ws/lib/receiver.js:608:16
    at node:internal/process/task_queues:140:7
    at AsyncResource.runInAsyncScope (node:async_hooks:203:9)
    at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

To Reproduce Steps to reproduce the behavior:

  1. Pull the latest meshctrl.js from the server (v1.1.22) and a node ID.
  2. Run this command node meshctrl.js --url wss://SERVER:443?key=KEY --loginuser "USER" --loginpass "PASSWORD" --token TOKEN deviceInfo --id "NODEID"
  3. See resulting error

Expected behavior

I would expect the following result. I was able with slight modification to the script above, run the above command and produce device Info. The modifications are down below. This should eliminate any concern of authentication or errors in the parameters.

--- General ---
  Server Name: SERVER
  Computer Name: COMPUTER-1
  IP Address: XXX.XXX.XXX.XXX
  Icon: 2
--- Operating System ---
  Name: COMPUTER-1
  Version: Rocky Linux 9.3 
--- Mesh Agent ---
  Mesh Agent: Linux 64bit
  Last agent connection: Connected now

Modifications were to comment out the entire networking blocks for .netif and .netif2 lines 2836 to 2907.

     // Networking
    // if (network.netif != null) {
    //     var output = {}, outputCount = 0, minfo = {};
    //     for (var i in network.netif) {
    //         var m = network.netif[i], moutput = {}, moutputCount = 0;
    //         if (m.desc) { moutput["Description"] = m.desc; moutputCount++; }
    //         if (m.mac) {
    //             if (m.gatewaymac) {
    //                 moutput["MAC Layer"] = format("MAC: {0}, Gateway: {1}", m.mac, m.gatewaymac); moutputCount++;
    //             } else {
    //                 moutput["MAC Layer"] = format("MAC: {0}", m.mac); moutputCount++;
    //             }
    //         }
    //         if (m.v4addr && (m.v4addr != '0.0.0.0')) {
    //             if (m.v4gateway && m.v4mask) {
    //                 moutput["IPv4 Layer"] = format("IP: {0}, Mask: {1}, Gateway: {2}", m.v4addr, m.v4mask, m.v4gateway); moutputCount++;
    //             } else {
    //                 moutput["IPv4 Layer"] = format("IP: {0}", m.v4addr); moutputCount++;
    //             }
    //         }
    //         if (moutputCount > 0) { minfo[m.name + (m.dnssuffix ? (', ' + m.dnssuffix) : '')] = moutput; info["Networking"] = minfo; }
    //     }
    // }

    // if (network.netif2 != null) {
    //     var minfo = {};
    //     for (var i in network.netif2) {
    //         var m = network.netif2[i], moutput = {}, moutputCount = 0;

    //         if (Array.isArray(m) == false ||
    //             m.length < 1 ||
    //             m[0] == null ||
    //             ((typeof m[0].mac == 'string') && (m[0].mac.startsWith('00:00:00:00')))
    //         )
    //             continue;

    //         var ifTitle = '' + i;
    //         if (m[0].fqdn != null && m[0].fqdn != '') ifTitle += ', ' + m[0].fqdn;

    //         if (typeof m[0].mac == 'string') {
    //             if (m[0].gatewaymac) {
    //                 moutput['MAC Layer'] = format("MAC: {0}, Gateway: {1}", m[0].mac, m[0].gatewaymac);
    //             } else {
    //                 moutput['MAC Layer'] = format("MAC: {0}", m[0].mac);
    //             }
    //             moutputCount++;
    //         }

    //         moutput['IPv4 Layer'] = '';
    //         moutput['IPv6 Layer'] = '';
    //         for (var j = 0; j < m.length; j++) {
    //             var iplayer = m[j];
    //             if (iplayer.family == 'IPv4' || iplayer.family == 'IPv6') {
    //                 if (iplayer.gateway && iplayer.netmask) {
    //                     moutput[iplayer.family + ' Layer'] += format("IP: {0}, Mask: {1}, Gateway: {2}  ", iplayer.address, iplayer.netmask, iplayer.gateway);
    //                     moutputCount++;
    //                 } else {
    //                     if (iplayer.address) {
    //                         moutput[iplayer.family + ' Layer'] += format("IP: {0}  ", iplayer.address);
    //                         moutputCount++;
    //                     }
    //                 }
    //             }
    //         }
    //         if (moutput['IPv4 Layer'] == '') delete moutput['IPv4 Layer'];
    //         if (moutput['IPv6 Layer'] == '') delete moutput['IPv6 Layer'];
    //         if (moutputCount > 0) {
    //             minfo[ifTitle] = moutput;
    //             info["Networking"] = minfo;
    //         }
    //     }
    // }

Screenshots

No screenshots.

Server Software (please complete the following information):

Client Device (please complete the following information):

Remote Device (please complete the following information):

Additional context

To note, we recently upgraded a few months ago from 1.1.0 to 1.1.22 as we saw that the LTS hadn't been updated in quite awhile and decided to modernize. We had not been using meshctrl on the prior version.

Additionally, some devices appear to fail to return differing results. Another remote devices results that seem to be more detailed with no change to the command... I've also had some devices fail to return results in past testing, but haven't located a device yet as an example.

Run on modified script

--- General ---
  Server Name: SERVER
  Computer Name: COMPUTER-2
  IP Address: XXX.XXX.XXX.XXX
  Icon: 2
--- Operating System ---
  Name: COMPUTER-2
  Version: Rocky Linux 9.3 (Blue Onyx)
--- Mesh Agent ---
  Mesh Agent: Linux 64bit
  Last agent connection: 5/16/2024, 8:51:59 AM
  Last agent address: XXX.XXX.XXX.XXX
--- Intel Active Management Technology (Intel AMT) ---
  Version: v11.8.90
  Provisioning State: <i>Unknown</i>
  Security: TLS is not setup
  Admin Credentials: Not Known
--- BIOS ---
  Vendor: Dell Inc.
  Version: 1.32.4
--- Motherboard ---
  Vendor: Dell Inc.
  Name: 111111
  Serial: /AAAAAA/BBBBBBBBBBBB
  Version: A00
  Identifier: 11111111-1111-1111-1111-11111111111
  CPU: Intel(R) Core(TM) i5-6300U CPU @ 2.40GHz
  GPU1: Intel Corporation Skylake GT2 [HD Graphics 520] (rev 07)

Same device run on stock meshctrl.js

Provides networking and storage info.

--- General ---
  Server Name: SERVER
  Computer Name: COMPUTER-2
  IP Address: XXX.XXX.XXX.XXX
  Icon: 2
--- Operating System ---
  Name: COMPUTER-2
  Version: Rocky Linux 9.3 (Blue Onyx)
--- Mesh Agent ---
  Mesh Agent: Linux 64bit
  Last agent connection: 5/16/2024, 8:51:59 AM
  Last agent address: XXX.XXX.XXX.XXX
--- Networking ---
  enp0s31f6:
    MAC Layer: MAC: 11:11:11:11:11:11
  wlp1s0:
    MAC Layer: MAC: 11:11:11:11:11:11
    IPv4 Layer: IP: XXX.XXX.XXX.XXX, Mask: 255.255.255.0, Gateway: XXX.XXX.XXX.XXX
    IPv6 Layer: IP: 1111:1111:1111:1111:1111:1111:1111:1111  IP: 1111::1111:1111:1111:1111%3  
  docker0:
    MAC Layer: MAC: 11:11:11:11:11:11
    IPv4 Layer: IP: XXX.XXX.XXX.XXX
  wg0:
    IPv4 Layer: IP: XXX.XXX.XXX.XXX
--- Intel Active Management Technology (Intel AMT) ---
  Version: v11.8.90
  Provisioning State: <i>Unknown</i>
  Security: TLS is not setup
  Admin Credentials: Not Known
--- BIOS ---
  Vendor: Dell Inc.
  Version: 1.32.4
--- Motherboard ---
  Vendor: Dell Inc.
  Name: 111111
  Serial: /AAAAAA/BBBBBBBBBBBB
  Version: A00
  Identifier: 11111111-1111-1111-1111-11111111111
  CPU: Intel(R) Core(TM) i5-6300U CPU @ 2.40GHz
  GPU1: Intel Corporation Skylake GT2 [HD Graphics 520] (rev 07)
--- Storage ---
  ATA Disk:
    Model: SK hynix SC300 M
    Capacity: 238GiB (256GB)
  SD Card:
    Model: SL16G
    Capacity: 14GiB (15GB)

Additionally, here is info about the meshctrl.js file. We pulled this file on Apr 26 from NPM for the install.

Top lines of file

#!/usr/bin/env node

/**
* @description MeshCentral command line tool
* @author Ylian Saint-Hilaire
* @copyright Intel Corporation 2018-2022
* @license Apache-2.0
* @version v0.0.1
*/

Your config.json file

{
  "$schema": "http://info.meshcentral.com/downloads/meshcentral-config-schema.json",
  "__comment1__": "This is a simple configuration file, all values and sections that start with underscore (_) are ignored. Edit a section and remove the _ in front of the name. Refer to the user's guide for details.",
  "__comment2__": "See node_modules/meshcentral/sample-config-advanced.json for a more advanced example.",
  "settings": {
    "MongoDb": "mongodb://127.0.0.1:27017/SERVER",
    "cert": "SERVER",
    "WANonly": true,
    "_LANonly": true,
    "_sessionKey": "SECRET",
    "_port": 443,
    "_aliasPort": 443,
    "_redirPort": 80,
    "_redirAliasPort": 80,
    "agentPort": 444,
    "agentAliasPort": 443,
    "agentAliasDNS": "DOMAIN",
    "maxInvalidLogin": {
      "time":10,
      "count": 10,
      "coolofftime": 10
    },
    "authLog": "/opt/meshcentral/LoginAttemptsLog"
  },
  "domains": {
    "": {
      "loginKey": [KEY1, KEY2],
      "title": "",
      "_title2": "Servername",
      "welcomePicture": "A_black_background.jpg",
      "welcomePictureFullScreen": true,
      "_minify": true,
      "_newAccounts": true,
      "_userNameIsEmail": true,
      "passwordRequirements": {
        "min": 1,
        "max": 100,
        "upper": 1,
        "lower": 1,
        "numeric": 1,
        "nonalpha": 1,
        "reset": 300,
        "force2factor": true,
        "email2factor": false,
        "sms2factor": false,
        "oldPasswordBan": 10,
        "loginTokens": false
      },
      "twoFactorCookieDurationDays": 0
    }
  },
  "letsencrypt": {
    "__comment__": "Requires NodeJS 8.x or better, Go to https://letsdebug.net/ first before trying Let's Encrypt.",
    "email": ":EMAIL",
    "names": "DOMAIN",
    "production": true
  }
}
timaw7 commented 1 month ago

Just a followup. I'm making some assumptions here, but it is erroring on returning netinfo. I was able on the first device to pull that info through the web console tab.

> netinfo
{
  lo: {
    0: {
      mac: "00:00:00:00:00:00"
      type: "ethernet"
      status: "up"
      address: "127.0.0.1"
      family: "IPv4"
      netmask: "255.0.0.0"
    }
    1: {
      mac: "00:00:00:00:00:00"
      type: "ethernet"
      status: "up"
      address: "::1"
      family: "IPv6"
      netmask: "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
    }
  }
  enp0s31f6: {
    0: {
      mac: "11:11:11:11:11:11"
      type: "ethernet"
      status: "up"
    }
  }
  wlp1s0: {
    0: {
      mac: "22:22:22:22:22:22"
      type: "ethernet"
      status: "up"
      address: "XXX.XXX.XXX.XXX"
      family: "IPv4"
      gateway: "XXX.XXX.XXX.XXX"
      netmask: "255.255.255.0"
    }
    1: {
      mac: "22:22:22:22:22:22"
      type: "ethernet"
      status: "up"
      address: "fe11::"fe11:"fe11:"fe11:"fe11%3"
      family: "IPv6"
      netmask: "ffff:ffff:ffff:ffff::"
    }
  }
  bridge0: {
    0: {
      mac: "22:22:22:22:22:22"
      type: "ethernet"
      status: "up"
      address: ""fe11::"fe11:"fe11:"fe11:"fe11%4"
      family: "IPv6"
      netmask: "ffff:ffff:ffff:ffff::"
    }
  }
  vnet0: {
    0: {
      mac: "22:22:22:22:22:22"
      type: "ethernet"
      status: "up"
      address: "fe11::"fe11:"fe11:"fe11:"fe11%4"
      family: "IPv6"
      netmask: "ffff:ffff:ffff:ffff::"
    }
  }
  wg0: {
    0: {
      status: "up"
      address: "XXX.XXX.XXX.XXX"
      family: "IPv4"
      netmask: "255.255.255.255"
    }
  }
timaw7 commented 1 month ago

A side question here. Is it possible to pull the Node ID through the Web GUI? I'm currently using the listDevices command which is not convenient for testing.

si458 commented 1 month ago

i can replicate the issue, looking into it now for you 👍

si458 commented 1 month ago

the issue is because your nodeid will have a $ in it which isnt phased correctly at the command line try putting nodeid with ' around instead --id 'LONGNODE$ID'

timaw7 commented 1 month ago

@si458 You are correct. The executed command works with ' but not " for the nodeid. I can also confirm the not working nodeid has a $ in it whereas the devices that worked did not have the $.

I think you've nailed this one. Any idea how to get the nodeid out of the webgui? Would just be convenient for testing.

si458 commented 1 month ago

@timaw7 the nodeid is actually part of the URl itself https://meshcentral.myserver.com/?viewmode=10&gotonode=lupekvnEmP$6OBe0yhtXEzBl9FUAcuyF@T7fs1gIQxCDGgK4l1YBk0Ziua01TLZA so in this example its the gotonode= value and to be honest after a quick check, the is actually nowhere listing the node id haha, not even in the console tab! will add a nodeid option into the console tab, so you can type nodeid and it will return its id for you! 👍

timaw7 commented 1 month ago

@si458 I see it in the URI now. Right in front of my face. Yeah at least on the console tab would be ideal.

I've confirmed that this works in a script for all my devices (over 80+). Also a side note, this fixes another issue I was having. Some device calls were not returning at all as opposed to erroring like above. This apparently fixes it all. Thanks for the help! Closing out the issue.

si458 commented 1 month ago

from what ive learn use ' on linux and " with windows, and IF no special characters like $ @ in the nodeid then use without both

si458 commented 1 month ago

side note: just added Node ID: into the info output in the console tab hehe https://github.com/Ylianst/MeshCentral/commit/e8da6a607c4a238fd49399c5f6346bb325cb7643

si458 commented 1 month ago

side note: https://github.com/Ylianst/MeshCentral/commit/7cf14a2b69f9f970959838a68628f415adae0384 ive pushed a fix to show invalid device id if no data at all was returned