Skip to content

Main config

config.mgc is the main global configuration file for Meshgate. It is usually stored next to the Meshgate binary or in a configuration directory such as /etc/meshgate/.

Meshgate reads config.mgc on startup. After changing configuration values, restart the service so the new settings are applied.

What usually lives here

Global settings such as certificates, licensing, logging, metrics, cluster, xdp, geoip, and from imports.

Recommended split

Keep shared settings in config.mgc, and move server-specific configs into config.d/ files imported via from.

One config.mgc should hold shared parameters (certificates, logging, metrics), while server configurations should be placed in separate files under config.d/ and imported through from.


The following section provides a brief reference for the basic config.mgc syntax elements used in the examples on this page.

Variables

  • Syntax: var name: value
  • Example: var certs: [cert: "path/to/cert.pem"]

Arrays

  • Syntax: []
  • Example: log: [level: "info" rotation: "daily"]

Keys

  • Syntax: key: value
  • Example: address: "127.0.0.1"

Comments

  • Syntax: #
  • Example: # test server

var certs: [
cert: "assets/certs/localhost.pem"
key: "assets/certs/localhost-key.pem"
]
var internal_certs: [
cert: "path/to/internal/internal.pem"
key: "path/to/internal/internal-key.pem"
]

Fields

  • cert — path to the certificate (.pem)
  • key — path to the private key (.pem)

File paths

If a relative path is used, it is resolved relative to the directory where config.mgc is located (or the current working directory, depending on how Meshgate is started).

If you are unsure, prefer absolute paths.

Recommendations

  • Local environment: self-signed certificates
  • Production: Let’s Encrypt or another trusted CA
  • Verify file permissions before starting Meshgate

license_key specifies the license key used to activate Meshgate.

license_key: "XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX"

The key is purchased from an official Meshgate vendor.

Meshgate FREE does not require a license key.


The log block defines how logs are written and stored.

log: [
rotation: "hourly"
runtime: [
layers: [
file: [
folder: "logs"
prefix: "meshgate_log"
]
opensearch: [
index_name: "runtime_logs"
address: "https://localhost:9200"
auth: [
login: "admin"
password: "adminpass"
]
]
clickhouse: [
address: "http://localhost:8123"
database: "test_db"
username: "default"
password: ""
]
stdout: [ ]
syslog: [ ]
]
]
access: [
layers: [
file: [
folder: "logs"
prefix: "meshgate_log"
]
opensearch: [
index_name: "access_logs"
address: "https://localhost:9200"
auth: [
login: "admin"
password: "adminpass"
]
]
clickhouse: [
address: "http://localhost:8123"
database: "test_db"
username: "default"
password: ""
]
stdout: [ ]
syslog: [ ]
]
]
]
  • level Controls log verbosity. Values: off, info (default), debug, warn, error, trace

  • rotation Controls file log rotation frequency. Values: minutely, hourly (default), daily, never

  • enable_stdout Enables writing logs to stdout. Value type: true / false

  • runtime — system/runtime logs.

  • access — HTTP access logs.

Local debugging

Use stdout with level: "debug" for fast feedback in terminal output.

Production

Use file + rotation, and optionally opensearch or clickhouse for centralized storage.


prometheus_config enables a Prometheus-compatible metrics endpoint.

prometheus_config: [
address: "127.0.0.1"
port: 3000
path: "/metrics"
]

After startup:

  1. Open http://{address}:{port}{path}.
  2. Confirm the endpoint responds with metrics data.
  3. Verify Prometheus can reach the endpoint from its network.

Metrics are grouped by purpose to simplify navigation and reading.

Core counters and gauges

  • total_requestsCounter (total request count)
  • total_connectionsGauge (active connections)
  • total_bansGauge (current number of bans)

Fingerprint-related metrics

  • ja3GaugeVec {ja3}
  • ja3_sortedGaugeVec {ja3_sorted}
  • http2GaugeVec {http2}

Cache metrics

  • cache_inserts_totalGaugeVec {cache_inserts_total}
  • cache_misses_totalGaugeVec {cache_misses_total}
  • cache_hits_totalGaugeVec {cache_hits_total}

Upstream health and status

  • health_check_failedGaugeVec {upstream}
  • health_check_successGaugeVec {upstream}
  • upstream_statusGaugeVec {upstream}

HTTP traffic and latency

  • http_requests_totalCounterVec {hostname, status_code}
  • http_request_duration_secondsHistogram
  • upstream_request_duration_secondsHistogramVec {upstream}
  • bytes_received_totalCounterVec {host, upstream}

Available in PRO.

cluster: [
api: "127.0.0.1:50051"
meshgate_uuid: "ru_moscow_01"
challenge_url: "http://127.0.0.1:8080"
captcha_url: "http://127.0.0.1:8080"
]

xdp: [
interfaces: ["lo", "enp2s0"]
rules: [
block_with_pps: [
expr: "src.ip == 10.0.0.1 && src.port == 8080 && pps > 9"
action: "drop"
]
]
]

Source

  • src.ip (Ip) — source IP
  • src.port (Int) — source port

Destination

  • dst.ip (Ip) — destination IP
  • dst.port (Int) — destination port

Rate

  • pps (Int) — packets per second

geo_db_path is the path to the MaxmindDB (geo2ip) database used by WAF.

geo_db_path: "/etc/meshgate/maxmindb_geo2ip.mmdb"

from imports configuration files (both relative and absolute paths are supported):

static: from "config.d/static.mgc"
https: from "config.d/https.mgc"
http: from "config.d/http.mgc"
tcp: from "config.d/tcp.mgc"
udp: from "config.d/udp.mgc"

Split recommendations

  • one file = one server type or one task (https.mgc, static.mgc, tcp.mgc)
  • keep naming short and consistent
  • start with a minimal set of modules, then add more gradually for easier debugging

  • certificate and key paths exist and are accessible
  • the required logging mode and rotation are configured
  • metrics are enabled only if they are actually needed
  • from modules are connected and files exist at the specified paths

var certs: [
cert: "assets/certs/localhost.pem"
key: "assets/certs/localhost-key.pem"
]
var internal_certs: [
cert: "path/to/internal/internal.pem"
key: "path/to/internal/internal-key.pem"
]
license_key: "XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX"
prometheus_config: [
address: "127.0.0.1"
port: 3000
path: "/metrics"
]
cluster: [
api: "127.0.0.1:50051"
meshgate_uuid: "ru_moscow_01"
challenge_url: "http://127.0.0.1:8080"
captcha_url: "http://127.0.0.1:8080"
]
xdp: [
interfaces: ["lo", "enp2s0"]
]
log: [
level: "debug"
rotation: "hourly"
enable_stdout: true
access: [
layers: [
file: [
folder: "logs"
prefix: "access"
]
opensearch: [
auth: [
basic: [
login: "admin"
password: $OPENSEARCH_INITIAL_ADMIN_PASSWORD
]
]
addr: "https://localhost:9200"
]
]
]
]
static: from "config.d/static.mgc"
#https: from "config.d/https.mgc"
#http: from "config.d/http.mgc"
#tcp: from "config.d/tcp.mgc"
#udp: from "config.d/udp.mgc"

Recommendations

Split servers by responsibility (local, proxy, internal, static handling) to keep configuration easier to reason about and maintain.