Table of Contents

Mesh Central in Docker behind NGINX Proxy Manager Reverse Proxy

Prerequisites

  1. Root Docker environment on Linux
  2. docker-compose installed
  3. Ports 80/443 port forwarded to your Docker host
  4. Reverse proxy being Nginx Proxy Manager, not Traefik as I don't use it
  5. Nginx Proxy Manager listening for ports 80/443
  6. Proper DNS records for a LetsEncrypt DNS Challenge (for a certificate)
  7. Folder on your linux filesystem named meshcentral (This folder will only contain a docker-compose.yml file)

Deploying container

sudo docker compose up -d
networks:
  reverse_proxy:
    external: true
    
volumes:
  files:
  database:

services:
    mongodb:
        container_name: meshcentral_db
        restart: always
        image: mongo:7.0-rc-jammy # DO NOT CHANGE VERSION AFTER DEPLOYMENT!!
        expose:
          - 27017
        volumes:
          - database:/data/db
        networks:
          - reverse_proxy
        environment:
          - TZ=Europe/Prague

    meshcentral:
        restart: always
        container_name: meshcentral
        image: ghcr.io/ylianst/meshcentral:1.1.37
        depends_on:
            - mongodb
        #ports:
        #    - 4433:4433 # This is used for Intel AMT, uncomment if you don't need it
        #    - 443:443 # You don't need to expose the port 443 directly if MeshCentral is behind a reverse proxy, this is just for debugging
        environment:
            - TZ=Europe/Prague
        volumes:
            - files:/opt/meshcentral/meshcentral-files # Docker Volume
            - /docker/containers/meshcentral/data:/opt/meshcentral/meshcentral-data # Docker Bind Mount
            - /docker/containers/meshcentral/backups:/opt/meshcentral/meshcentral-backups
            - /docker/containers/meshcentral/meshcentral-web:/opt/meshcentral/meshcentral-web
            - /docker/containers/meshcentral/config.json:/opt/meshcentral/meshcentral-data/config.json
        networks:
          - reverse_proxy

Config File

 sudo nano /docker/containers/meshcentral/config.json:/opt/meshcentral/meshcentral-data/config.json
{
  {
  "$schema": "https://raw.githubusercontent.com/Ylianst/MeshCentral/master/meshcentral-config-schema.json",
  "settings": {
    "_maintenanceMode": true,
    "cert": "meshcentral.laptopwiki.eu",
    "_SQLite3": false,
    "mongodb": "mongodb://mongodb:27017/mesh",
    "mongodbcol": "mesh",
    "WANonly": true,
    "sessionKey": "null",
    "port": 443,
    "aliasPort": 443,
    "redirPort": 80,
    "redirAliasPort": 80,
    "AgentPong": 300,
    "TLSOffload": "127.0.0.1",
    "_ignoreAgentHashCheck": true,
    "SelfUpdate": false,
    "AllowFraming": true,
    "WebRTC": false,
    "Restore": true,
    "nice404": true,
    "allowHighQualityDesktop": true,
    "publicPushNotifications": false,
    "trustedProxy": "nginx-proxy-manager"
  },
  "domains": {
    "": {
      "_siteStyle": 2,
      "title": "MeshCentral",
      "title2": "LaptopWiki",
      "_titlePicture": "title-sample.png",
      "_loginPicture": "title-sample.png",
      "mobileSite": true,
      "maxDeviceView": 200,
      "_unknownUserRootRedirect": "https://www.youtube.com/watch?v=2Q_ZzBGPdqE",
      "nightMode": 0,
      "ipkvm": false,
      "minify": true,
      "newAccounts": false,
      "_welcomeText": "Sample Welcome Test.",
      "_welcomePicture": "mainwelcome.jpg",
      "_welcomePictureFullScreen": false,
      "meshMessengerTitle": "MeshMessenger",
      "_meshMessengerPicture": "messenger.png",
      "___hide__": "Sum of: 1 = Hide header, 2 = Hide tab, 4 = Hide footer, 8 = Hide title, 16 = Hide left bar, 32 = Hide back buttons",
      "hide": 4,
      "footer": "<a href='https://laptopwiki.eu'>Homepage</a>",
      "loginfooter": "This is not a public service.",
      "allowSavingDeviceCredentials": true,
      "guestDeviceSharing": true,
      "_AutoRemoveInactiveDevices": 37,
      "_DeviceSearchBarServerAndClientName": false,
      "_agentSelfGuestSharing": {
        "expire": 120
      },
      "certUrl": "https://meshcentral.laptopwiki.eu:443",
      "deviceMeshRouterLinks": {
        "rdp": true,
        "ssh": true,
        "scp": true
      },
      "myServer": {
        "Backup": true,
        "Restore": true,
        "Upgrade": true,
        "ErrorLog": true,
        "Console": true,
        "Trace": true,
        "Config": true,
        "Restore": true
      },
      "passwordRequirements": {
        "min": 8,
        "max": 128,
        "upper": 1,
        "lower": 1,
        "numeric": 1,
        "nonalpha": 1,
        "reset": 3650,
        "force2factor": false,
        "skip2factor": "127.0.0.1",
        "oldPasswordBan": 5,
        "banCommonPasswords": false,
        "twoFactorTimeout": 120
      },
      "twoFactorCookieDurationDays": 180,
      "agentInviteCodes": false,
      "_agentNoProxy": true,
      "geoLocation": false,
      "novnc": true,
      "mstsc": true,
      "ssh": true,
      "_WebEmailsPath": "/myserver/email-templates",
      "consentMessages": {
        "title": "MeshCentral Remote Access",
        "desktop": "{0} requesting remote desktop access. Grant access?",
        "terminal": "{0} requesting remote terminal access. Grant access?",
        "files": "{0} requesting remote files access. Grant access?",
        "consentTimeout": 60,
        "autoAcceptOnTimeout": false
      },
      "notificationMessages": {
        "title": "MeshCentral Remote Access",
        "desktop": "{0} started a remote desktop session.",
        "terminal": "{0} started a remote terminal session.",
        "files": "{0} started a remote files session."
      },
      "agentCustomization": {
        "displayName": "Laptopwiki MeshCentral Agent",
        "description": "MeshCentral agent for remote monitoring, management and assistance.",
        "_companyName": "LaptopWiki.eu",
        "serviceName": "laptopwikiMeshAgent",
        "_image": "agent-logo.png",
        "_fileName": "_laptopwikiMeshAgent",
        "filename": "MeshAgent"
      },
      "_agentFileInfo": {
        "_icon": "agent.ico",
        "_filedescription": "sample_filedescription",
        "fileversion": "1.0",
        "_internalname": "sample_internalname",
        "_legalcopyright": "sample_legalcopyright",
        "_originalfilename": "sample_originalfilename",
        "productname": "sample_productname",
        "productversion": "v0.1.2.3"
      },
      "assistantCustomization": {
        "title": "Laptopwiki Mesh Assistant",
        "_image": "assistant-logo.png",
        "fileName": "laptopwikiAssist"
      },
      "androidCustomization": {
        "title": "Laptopwiki Mesh Android™",
        "_subtitle": "Product Subtitle™",
        "_image": "assistant-logo.png"
      },
      "_userAllowedIP": "127.0.0.1,192.168.1.0/24",
      "_userBlockedIP": "127.0.0.1,::1,192.168.0.100",
      "_agentAllowedIP": "192.168.0.100/24",
      "_agentBlockedIP": "127.0.0.1,::1",
      "___userSessionIdleTimeout__": "Number of user idle minutes before auto-disconnect",
      "_userSessionIdleTimeout": 60,
      "_userConsentFlags": {
        "desktopnotify": true,
        "terminalnotify": true,
        "filenotify": true,
        "desktopprompt": true,
        "terminalprompt": true,
        "fileprompt": true,
        "desktopprivacybar": true
      },
      "urlSwitching": true,
      "_desktopPrivacyBarText": "Privacy bar: {0}, {1}",
      "_limits": {
        "maxDevices": 3000,
        "maxUserAccounts": 100,
        "maxUserSessions": 100,
        "maxAgentSessions": 100,
        "maxSingleUserSessions": 10
      },
      "terminal": {
        "linuxshell": "login",
        "launchCommand": {
          "linux": "clear\necho \"Hello Linux\"\n",
          "darwin": "clear\necho \"Hello MacOS\"\n",
          "freebsd": "clear\necho \"Hello FreeBSD\"\n"
        }
      },
      "redirects": {
        "homepage": "https://laptopwiki.eu"
      }
    }
  }
}

So what are we changing and why?

  1. “cert”: “meshcentral.laptopwiki.eu” - to tell Mesh Central what certificate to use - works even if you use a wildcard certificate (*.laptopwiki.eu)here
  2. “TLSOffload”: “nginx-proxy-manager” - set Docker hostname or IP address of your NPM installation, don't put port here
  3. “port”: 443, - change if you don't use 443. If your NPM isn't on the same docker host this should be the exposed port (for example 8786) but I haven't tested it so I don't really know.
  4. “certUrl”: “https://meshcentral.laptopwiki.eu:443” - Public FQDN of your Mesh Central server, including the port * Save the file (Press Ctrl+O and Enter to save changes and Ctrl+X to exit Nano) \ * Start the Docker Compose project sudo docker compose up -d

NGINX Proxy Manager

  1. Add a new Proxy host as you would with any other Docker container
  2. Check Cache Assets, Block Common Exploits and Websockets Support
  3. In SSL, select your certificate, force SSL and enable HTTP/2
  4. In the Advanced tab paste the following
    proxy_set_header CF-Connecting-IP $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Host $host:$server_port;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_read_timeout 200s;
    proxy_connect_timeout 200s;
    proxy_send_timeout 200s;


If Cloudflare Proxy

  1. As of August 2023, MeshCentral no longer works through Cloudflare Proxy, see https://github.com/Ylianst/MeshCentral/issues/5302 - This setup works fine through Cloudflare Proxy, assuming
  2. Cloudflare Dashboard → yourdomain.tld → SSL/TLS → Overview → FULL
  3. This is necessary so that the Cloudflare Proxy and your local certificate match and Cloudflare doesn't try to redirect

Issues

Unable to connect web socket


dustojnikhummer 20/09/2024 17:28