Skip to content
Fixedmark
fm CLI

TCP

Updated

fm CLI reference

fm is the Fixedmark command line. fm tunnel forwards local ports through your static IPs to databases and TCP services, for drivers that have no proxy support. The other commands manage apps, IPs, routes, connectors, credentials, and keys over the REST API.

Docs preview: Fixedmark is not live yet. Endpoints are issued at launch, and these pages describe planned launch behavior. Anything marked planned may change. Join early access to get yours first.

fm tunnel

fm tunnel listens on a local port and sends each connection to a remote host and port from your static IPs. It carries outbound traffic only.

Terminal
fm tunnel 5432:db.example.com:5432

Your driver then connects to 127.0.0.1:5432. Give it the real server name for TLS checks, as the databases guide shows.

Terminal
# Several mappings in one process
fm tunnel 5432:db.example.com:5432 3306:mysql.example.com:3306

# Text logs instead of JSON lines
fm tunnel --log text 5432:db.example.com:5432

# A config file somewhere else
fm tunnel --config /run/secrets/fixedmark.toml 5432:db.example.com:5432
fm tunnel mapping parts
PartExampleMeaning
Local port5432The port fm listens on. It binds 127.0.0.1 only.
Hostdb.example.comThe destination. The proxy resolves the name in its region, never your machine.
Port5432The destination port. The connection leaves from your static IP.

Credentials

fm reads credentials from a config file first, then from FIXEDMARK_SOCKS_URL. It never calls a Fixedmark API when it starts, so an API outage cannot stop your app from booting.

The default file is $XDG_CONFIG_HOME/fixedmark/config.toml, or ~/.config/fixedmark/config.toml. Pass --config to name another one.

Terminal
# ~/.config/fixedmark/config.toml
app_id = "APP_ID"
token = "fmc_TOKEN"
endpoint = "mum.egress.fixedmark.com:1443"

Without a file, fm reads the SOCKS URL the dashboard shows. It accepts socks5s://, socks5h://, and socks5://, and always connects over TLS on port 1443.

Terminal
export FIXEDMARK_SOCKS_URL="socks5h://APP_ID:TOKEN@mum.egress.fixedmark.com:1080"
fm tunnel 5432:db.example.com:5432
The file holds your token. Keep it out of source control, mount it from your platform's secret store, and make it readable by your user only. fm never prints the token in logs or errors.

Running beside your app

The tunnel must run as long as your app does. On a platform with one start command, start it in the background first:

Terminal
web: fm tunnel 5432:db.example.com:5432 & node server.js
  • Your app may start before the tunnel listens. Retry the first connection, as most pools do.
  • Serverless functions cannot keep a background process. Use a SOCKS5 driver there.
  • If the endpoint is unreachable, fm retries with backoff, then exits with code 4.

Logs and exit codes

fm writes one JSON line per event to standard output, or text with --log text. It logs endpoint connected, each connection closed with bytes and duration, and endpoint unreachable, retrying.

fm exit codes
CodeMeaning
0Stopped by SIGINT or SIGTERM.
1Failed for another reason, printed on standard error.
2Bad usage, a bad config file, or no credentials found.
3The endpoint refused the credentials. Check the token.
4The endpoint stayed unreachable for the retry window.

A destination your allowlist refuses shows as not_allowed on that one connection. The tunnel keeps running.

Other commands

These commands call the REST API with an API key. Run fm auth login once to store the key, or set FM_API_KEY.

fm commands for the REST API
CommandWhat it does
fm auth loginStores an API key for the commands below.
fm whoamiShows the org and key in use.
fm apps list|create|get|deleteManages apps.
fm ips list|create|getLists and orders static IPs.
fm credentials list|create|rotate|revoke --app <app>Manages proxy credentials. The token is printed once, on create and rotate.
fm keys list|create|revokeManages API keys.
fm routes create|list|show|placement|partners|delete --app <app>Manages inbound routes, as Inbound routes shows.
fm connectors create|list|rotate|delete --app <app>Manages connectors, as fm connectors shows.
fm jobs get|watch <id>Follows a provisioning job.
fm usage --app <app>Shows bandwidth by day.
fm api <METHOD> <path>Calls any route in the API reference.
fm version, fm helpPrints the version or the usage.

Inbound routes

Inbound traffic uses fm routes, not fm tunnel. Routes belong to an app. create and list need --app with the app's id or name, and the other fm routes commands take it optionally. fm routes create gives a service on a connector's machine a hostname on the shared pool, or with --dedicated-ip a port on a dedicated IP of the app. See Tunnels and Dedicated inbound IP. Tunnels on Pro and up, with a dedicated inbound IP as an add-on at $9 per IP-month.

Terminal
# A hostname on the shared pool for a service on a connector's machine
fm routes create --app shop --kind http --name web --connector billing-db --to 127.0.0.1:8080 --partner 198.51.100.0/24

# A TCP port on a dedicated IP, to a host the node dials
fm routes create --app shop --kind tcp --name db --dedicated-ip IP_ID --origin db.example.com:5432 --partner 198.51.100.0/24

fm routes list --app shop
fm routes show web
fm routes placement web --dedicated-ip IP_ID
fm routes delete web

A route takes --origin or --connector with --to, never both. --origin needs --dedicated-ip, since a shared IP never dials out. --proxy-protocol goes with --connector only. show, placement, partners set, and delete name a route by id or name and search every app unless you pass --app. fm routes reference lists every flag.

fm connectors

fm connectors manages an app's connectors. Create and rotate write the new token to fm-connector-NAME.token in the current directory at mode 0600, print the install line, and never show the token again. --token-file PATH writes it somewhere else.

Terminal
fm connectors create --app APP_ID --name billing-db
fm connectors list --app APP_ID
fm connectors rotate --app APP_ID billing-db
fm connectors delete --app APP_ID billing-db

list shows each connector's token prefix, state, open sessions, and when it was last seen. delete is refused with connector.in_use while a route names the connector.

The connector itself is fixedmarkd, a separate program on the machine that holds your service, not an fm command. On that machine, from the directory with the token file, run the install line. Connectors covers fixedmarkd's commands, service, status, and exit codes.

Terminal
sudo fixedmarkd install --token-file fm-connector-billing-db.token

Frequently asked questions

Does fm tunnel call a Fixedmark API when it starts?

No. It reads the config file or FIXEDMARK_SOCKS_URL and connects straight to your region's proxy, so your app starts even when the Fixedmark API is down.

Is traffic through fm tunnel encrypted?

The hop from fm to the proxy is SOCKS5 inside TLS on port 1443, so your token never crosses the network in clear text. Your database's own TLS runs end to end inside the tunnel.

Can fm tunnel accept inbound connections from the internet?

No. It listens on 127.0.0.1 and carries outbound traffic only. For inbound traffic, fm routes create gives a service a hostname through a connector, or a port on a dedicated inbound IP.

Make it fixed.

Fixedmark is in early access. Join the list to get dedicated static IPs when your region opens.