Technical Briefing – Vpnnode (Mysterium Network Node) Clone: https://github.com/moses-y/Vpnnode (use verbatim)


The Problem

Running a node in the Mysterium dVPN requires assembling a cross‑platform Go service that must compile on Linux, macOS, Windows, and embedded devices (Raspberry Pi, Yocto). The repository is a portfolio of 36 semi‑independent projects (core, services, tequilapi, session, …) rather than a single monolith, which makes onboarding, building, and securing the whole stack non‑trivial. Moreover, the CI/CD configuration contains several hygiene gaps (mutable GitHub‑Action pins, root‑privileged Docker images, missing dependency‑scan gates) that raise the risk of unintended changes or credential leaks.


What This Does

The repo delivers a full‑stack VPN node:

  • Core VPN stack – WireGuard transport, NAT discovery, and session management live in core/ and services/wireguard/.
  • Tequila API – HTTP‑JSON client‑facing API defined in tequilapi/ (101 files, 99 code files).
  • CLI & bootstrap – Entry points cmd/mysterium_node/mysterium_node.go (main) and cmd/di.go (Bootstrap) wire dependency injection, configuration loading, and P2P hand‑shakes.
  • Docker images – Multi‑stage builds under bin/docker/ produce the mysteriumnetwork/myst image used by the one‑liner docker run … service --agreed‑terms-and‑conditions.
  • Installation scriptsinstall.sh (referenced from README) provisions a systemd service on Debian/Ubuntu/Raspbian and a Docker container on any host with Docker.

Key files that own the primary effects:

EffectOwner
Configuration loading & persistenceconfig/config.go (reads/writes files, env‑var resolution)
WireGuard endpoint creation & TUN routingservices/wireguard/endpoint/netstack/netstack.go (creates TUN, batches events)
P2P discovery & connection managercore/connection/manager.go (manages peer state, connects/disconnects)
Service startup & lifecyclecmd/node.go (Start reaches 409 downstream functions)
CLI command dispatchcmd/commands/cli/command.go (defines the public CLI surface)

Execution flows start at main (cmd/mysterium_node/mysterium_node.go:58) which calls Bootstrap (cmd/di.go:216). From there the call graph fans out: Bootstrap → Check → GloballyReachable → Close → Clean → cleanDNS (subprocess via command.Output), and Run → SaveUserConfig (filesystem write via os.WriteFile). The shortest path to an outbound network call is main → Bootstrap → Check [subprocess].


How It Is Wired

  • Entry points (from the internal call graph):
  • main – reaches 400 functions, no caller inside the repo.
  • Bootstrap – reaches 400 functions, called from 47 places.
  • handler (core/control/handler.go:27) – reaches 32 functions, called from 4 places.
  • run (cmd/natdisco/main.go:42) – reaches 402 functions, called from 1 place.
  • Run (cmd/commands/cli/command.go:171) – reaches 399 functions, called from 51 places.
  • Start (cmd/node.go:65) – reaches 409 functions, called from 41 places.
  • Hub modules (high Ca/Ce counts): Equal (180 callers), New (168), Info (149), Warn (108), Close (97). Changes to these ripple widely.
  • Outbound touches (per the “WHAT THIS CODE TOUCHES OUTSIDE ITSELF” block):
  • 9 functions make network calls (e.g., providerService via session.request.GetConfig).
  • 30 functions read/write files (config/config.go, core/storage/boltdb/storage.go).
  • 5 functions run external commands (command.Output, cmd.Run).
  • 3 functions read/write a database (BoltDB).
  • 1 function performs crypto operations.
  • Module graph – 891 of 891 code files analyzed; 1 internal module, no circular dependencies. The most connected modules are the equality‑checking and new‑type constructors that appear in many call stacks.

How To Use It

Setup

PlatformCommand (from README / repo)
Debian/Ubuntu/Raspbian (stable)sudo -E bash -c "$(curl -s https://raw.githubusercontent.com/mysteriumnetwork/node/master/install.sh)"
Docker (any OS with Docker)``bash\ndocker run \\\n --cap-add NET_ADMIN \\\n --net host \\\n --name myst -d \\\n mysteriumnetwork/myst service --agreed‑terms‑and‑conditions\n``
Build from sourcego build ./cmd/mysterium_node/ (requires Go 1.2+ and the go.mod in the repo root).

Configuration

  • Primary config file: config/config.go defines NewConfig, LoadUserConfig, SaveUserConfig.
  • Environment variables are read by config/config.go; key vars include MYSTERIUM_NODE_KEY, MYSTERIUM_NODE_SECRET (generated on first run).
  • Docker run uses the image mysteriumnetwork/myst; no extra env vars are required beyond the --agreed‑terms-and‑conditions flag.

Running it

  • Systemd service (post‑install): sudo systemctl status mysterium-node.service / sudo journalctl -u mysterium-node.service.
  • Docker: the one‑liner above starts the daemon; logs are fetched with docker logs -f myst.
  • CLI: mysterium node <subcommand> (see cmd/commands/cli/command.go for subcommands such as status, connect, disconnect).

Real‑World Use

A typical deployment: a startup runs the Docker image on a cloud VM with --cap-add NET_ADMIN to provision a WireGuard TUN device. The node registers with the Mysterium network, advertises its exit‑node capacity, and clients route traffic through it. The operator can monitor peer count via mysterium node status and rotate keys by deleting the persisted config (config/config.go) and re‑running the install script. Because the stack is modular, the same binary can be cross‑compiled for a Raspberry Pi (using the bin/build_xgo helper) to run a low‑power exit node in a home network.


Code Health & Issues

The static analysis (42 measured findings) reports:

SeverityIssueFiles
HIGHPin third‑party GitHub Actions to commit SHA (.github/workflows)docker/login-action@v3, docker/setup-buildx-action@v3, cpina/github-action-push-to-another-repository@main, indiesdev/curl@v1
HIGHPRs push directly to default branch (.github/workflows/mobile-release.yml)git push origin $BRANCH_NAME
MEDIUMDeclare least‑privilege GITHUB_TOKEN permissions (.github/workflows/build-packages.yml)4 workflows with no permissions declaration
MEDIUMEnable Dependabot/Renovate (no bot configured)1 manifest, no update bot
MEDIUMPin container base image by digest (bin/builder_docker/Dockerfile)golang:1.26 (mutable tag)
MEDIUMGate PRs on dependency vulnerability scan (no scan in CI)absent
MEDIUMAdd non‑root USER to Docker image (bin/builder_docker/Dockerfile)CMD/ENTRYPOINT with no USER directive
LOWSet timeout-minutes on workflow jobs (.github/workflows/build-packages.yml)4 jobs with no timeout

No committed secrets were found; licence and lockfile are present; CI (GitLab) and Dockerfiles exist.


The Bottom Line

The repository provides a mature, well‑tested implementation of a distributed VPN node, with clear separation between core VPN logic, API surface, and deployment tooling. The modular “portfolio” structure is useful for targeting diverse platforms but demands careful onboarding: newcomers must navigate ~36 independent projects and several CI hygiene gaps. Security‑focused operators should pin Action SHAs, add non‑root users to Docker images, and enable dependency scanning. Teams looking for a ready‑to‑run dVPN exit node will find the Docker one‑liner and Debian/Ubuntu install script the fastest path; those needing custom builds or embedded devices will benefit from the Go module layout and cross‑compilation helpers, while investing time in the noted code‑health remediations.