Profile Configuration

For script authoring, see the JavaScript API guide, including an importable demo, request/response fields, completion rules, and runtime limits.

Updated for MintFlow 2.0.0. Profile text is the source of truth: the app compiles it into a runtime database when starting VPN. Save changes, inspect compilation diagnostics, and restart VPN to apply a new configuration. Syntax/range errors and entitlement restrictions are distinct: a valid Pro configuration may be excluded from the compiled result when Pro is unavailable.

New sections include [simple-mode], [flowlog], [dns-hosts], and [http-body-rewrite]. Tailscale is an experimental [l3vpns] type. HTTP Engine now supports broader capture scope and jq/JavaScript body rules. Local scripts are separate resources; sharing profile text alone does not package them. Use an MFHRB bundle to share a rule and its source together.

The text-based profile is a cornerstone of MintFlow, designed to provide power users with a highly flexible and shareable way to control the app's advanced networking capabilities.

Why Use Profiles?

  • Complex Setups: Easily configure sophisticated routing rules, split DNS, and combinations of proxies and VPNs.
  • Manage Multiple Configurations: Create and switch between different profiles for various scenarios (e.g., a "Work" profile with a corporate VPN and a "Home" profile for personal use).
  • Share and Collaborate: Profiles are plain text, making them easy to share with other MintFlow users, version control with Git, or collaborate on.
  • Import and Export: Seamlessly import profiles from URLs or files, and export your configurations to back them up or share them.

MintFlow uses a powerful and flexible text-based profile format to configure all aspects of the VPN and proxy behavior. This document details the syntax and all available configuration options.

Syntax Overview

The profile uses an INI-style format with sections enclosed in [].

# Comments start with # or //
[section-name]
key=value

# Lists are comma-separated
key=value1,value2,value3

# Structured values use subkey:subvalue pairs
key=subkey1:value1,subkey2:value2

Sections

[misc]

This section contains miscellaneous system-level settings.

KeyTypeDescriptionDefault
tun-mtuIntegerThe MTU for the TUN interface.
exclude-lan-networksBooleanIf true, local area networks will be excluded from the VPN.false
log-levelStringRuntime logging level; use the app's supported choices.

Example:

[misc]
tun-mtu=1420
exclude-lan-networks=true

[dns]

This section configures the DNS settings.

KeyTypeDescription
system-dnsList of IPsDeprecated legacy override, used only when both custom App Routing and Simple Mode are disabled. Prefer direct-dns for new profiles.
app-routing-enabledBooleanEnables domain-based routing and split DNS. Set true for new profiles; the legacy false path is deprecated.
direct-dnsList of DNS upstreamsDNS servers for direct connections when app-routing-enabled is true. Supports plain IP DNS, DoT, and DoH.
vpn-dnsList of DNS upstreamsDNS servers for VPN/proxy connections when app-routing-enabled is true. Supports plain IP DNS, DoT, and DoH.
bootstrap-dnsList of IPs(New in 1.9.0) bootstrap resolvers used when encrypted VPN DNS upstreams are configured with domains. Defaults are provided by the app.
direct-dns-follow-vpnBoolean(New in 1.8.0) whether DNS servers for direct connections should follow the split routing rule.
optimistic-dns-cachingBoolean(New in 1.9.0) enables optimistic DNS cache refresh. Default is true.
l4proxy-synthetic-ipBooleanEnables synthetic-IP handling for L4 proxy domain routing. Default false.

DNS upstream formats:

  • Plain IP DNS: 1.1.1.1, 8.8.8.8
  • DNS over TLS: tls://cloudflare-dns.com or tls://1.1.1.1
  • DNS over HTTPS: https://dns.google/dns-query

When vpn-dns contains an encrypted DNS server with a domain name, such as tls://p2.freedns.controld.com, add a VPN-DNS-SERVER-DOMAINS routing rule so MintFlow can resolve that DNS server domain through a selected VPN/proxy path instead of leaking bootstrap traffic to the direct network.

Example:

[dns]
app-routing-enabled=true
direct-dns=223.5.5.5,114.114.114.114
vpn-dns=tls://p2.freedns.controld.com,https://dns.google/dns-query
bootstrap-dns=1.1.1.1,8.8.8.8
optimistic-dns-caching=true

[l3vpns]

This section defines Layer 3 VPN interfaces. The key for each entry is a user-defined name for the interface.

Common Fields

KeyTypeDescriptionRequired
typeStringActive types include wireguard, amneziawg, and experimental tailscale. openvpn is accepted by the schema but should not be treated as an implemented OpenVPN client.Yes
nicknameStringA user-friendly name for the interface.No
enabledBooleanWhether the interface is enabled. Defaults to true.No

WireGuard Specific Fields (When type=wireguard)

KeyTypeDescriptionRequired
private-keyStringThe private key for the interface.Yes
addressCIDRThe internal IP address and subnet for the interface.Yes

Tailscale fields (type:tailscale, experimental, Pro)

KeyMeaning
login-serverHTTPS control server URL, normally https://controlplane.tailscale.com; no embedded credentials, query, or fragment.
auth-keyOptional bootstrap enrollment key. Prefer browser login or a one-time key submission to avoid saving secrets in the profile.
drive-dnsDefault false. Derive peer IPv4 DNS records through MintFlow DNS; this does not enable the Tailscale OS MagicDNS resolver. Requires Pro and the MintFlow DNS path.
enabledDefault true. Only one active Tailscale interface per profile.
[l3vpns]
tailnet=type:tailscale,login-server:https://controlplane.tailscale.com,enabled:true

[routing]
CIDR,100.64.0.0/10,L3VPN,tailnet
DEFAULT,DIRECT
DNS-FALLBACK,DIRECT

Use with [dns] app-routing-enabled=true and suitable direct-dns upstreams. See the complete login and routing guide. Machine identity, Accept Routes, and exit-node selection are device-local state, not portable profile settings. Losing Pro access excludes the interface during compilation and changes routes targeting it to REJECT.

AmneziaWG Specific Fields (When type=amneziawg)

MintFlow 1.9.0 supports AmneziaWG 1.5 and 2.0 interface parameters. Peer fields are configured separately in [amneziawg-peers].

KeyTypeDescriptionRequired
private-keyStringThe private key for the interface.Yes
addressCIDRThe internal IP address and subnet for the interface.Yes
jcIntegerJunk packet count parameter.No
jminIntegerMinimum junk packet size.No
jmaxIntegerMaximum junk packet size.No
s1IntegerAmneziaWG S1 parameter.No
s2IntegerAmneziaWG S2 parameter.No
s3IntegerAmneziaWG S3 parameter.No
s4IntegerAmneziaWG S4 parameter.No
h1Integer or rangeH1 packet header value, for example 1 or 843739526-1233562642.No
h2Integer or rangeH2 packet header value, for example 2 or 1383464517-1389039856.No
h3Integer or rangeH3 packet header value, for example 3 or 1558777559-1611162592.No
h4Integer or rangeH4 packet header value, for example 4 or 1797613837-1977519157.No
i1 ... i5StringAmneziaWG 2.0 CPS instruction strings. Each field is limited to 255 UTF-8 bytes. Supported tags are <b>, <r>, <rd>, <rc>, and <t>.No

Example:

[l3vpns]
my-wireguard=type:wireguard,nickname:My WG,private-key:...,address:10.0.0.1/32
my-awg=type:amneziawg,nickname:My AWG,private-key:...,address:10.8.9.2/32,jc:4,jmin:40,jmax:70,s1:0,s2:0,s3:0,s4:0,h1:1,h2:2,h3:3,h4:4,i1:<r 33>

[wireguard-peers]

This section defines peers for WireGuard interfaces. The key for each entry is a user-defined name for the peer.

KeyTypeDescriptionRequired
interfaceStringThe name of the l3vpns interface this peer belongs to.Yes
public-keyStringThe public key of the peer.Yes
preshared-keyStringAn optional pre-shared key.No
endpointStringThe public endpoint of the peer (e.g., 1.2.3.4:51820).Yes
allowed-ipsList of CIDRsA list of IP addresses/ranges to be routed through this peer.Yes

Example:

[wireguard-peers]
my-peer=interface:my-wireguard,public-key:...,endpoint:1.2.3.4:51820,allowed-ips:0.0.0.0/0

[amneziawg-peers]

This section defines peers for AmneziaWG interfaces. The key for each entry is a user-defined peer name. The fields match WireGuard peers, but interface must reference an [l3vpns] entry whose type is amneziawg.

KeyTypeDescriptionRequired
interfaceStringThe name of the amneziawg interface this peer belongs to.Yes
public-keyStringThe public key of the peer.Yes
preshared-keyStringAn optional pre-shared key.No
endpointStringThe public endpoint of the peer, for example 1.2.3.4:51820.Yes
allowed-ipsList of CIDRsA list of IP addresses/ranges to be routed through this peer.Yes

Example:

[amneziawg-peers]
my-awg-peer=interface:my-awg,public-key:...,endpoint:1.2.3.4:51820,allowed-ips:0.0.0.0/0,::/0

[l4proxies]

This section defines Layer 4 proxies, like Shadowsocks and VMess. The key for each entry is a user-defined name for the proxy.

Common Fields

KeyTypeDescriptionRequired
typeStringThe proxy type. Supported: shadowsocks, vmess, anytls, http, socks5.Yes
nicknameStringA user-friendly name.No
serverStringThe server address.Yes
portIntegerThe server port.Yes
enabledBooleanWhether the proxy is enabled. Defaults to true.No
route-via-vpnBoolean(New in 1.8.0) Whether the proxy need to route over the VPN, thus you can chain it traffic to another VPN/Proxy server. Default to false, server IP must be in IPv4 address.No

Shadowsocks Fields

KeyTypeDescriptionRequired
passwordStringThe password.Yes
methodStringThe encryption method. Supported AEAD methods: aes-128-gcm, aes-256-gcm, chacha20-ietf-poly1305. Supported Shadowsocks 2022 methods: 2022-blake3-aes-128-gcm, 2022-blake3-aes-256-gcm, 2022-blake3-chacha20-poly1305.Yes
obfs-typeStringObfuscation type (tls or http).No
obfs-hostStringObfuscation host (required for obfs-type).No
obfs-pathStringObfuscation path (required for obfs-type=http).No
udp-forwardBooleanWhether to forward UDP traffic. Defaults to false.No

For Shadowsocks 2022 methods, password must be a base64-encoded pre-shared key. The decoded key must be 16 bytes for 2022-blake3-aes-128-gcm, and 32 bytes for 2022-blake3-aes-256-gcm or 2022-blake3-chacha20-poly1305.

VMess Fields

KeyTypeDescriptionRequired
user-idUUIDThe user ID.Yes
alter-idIntegerThe alter ID.Yes
securityStringSecurity type. E.g., auto.Yes
transport-typeStringTransport type (tcp or ws).Yes
ws-pathStringThe WebSocket path (required for transport-type=ws).No
sniStringServer Name Indication for TLS.No
skip-cert-checkBooleanIf true, skip certificate validation. Defaults to false.No
alpnStringApplication-Layer Protocol Negotiation. Defaults to h2,http/1.1.No

AnyTLS Fields

AnyTLS is configured as an L4 proxy with type=anytls. The fields below are based on the shared profile schema used by the mintflow-app branch currently used for vpprs integration; these AnyTLS profile fields are stable there and safe to use.

KeyTypeDescriptionRequired
passwordStringAnyTLS password.Yes
sniStringTLS Server Name Indication. Defaults to the server value when omitted.No
skip-cert-checkBooleanIf true, skip upstream certificate validation. Defaults to false.No
session-reuseBooleanEnables AnyTLS idle session reuse. Defaults to true.No
idle-session-check-intervalIntegerInterval in seconds for checking idle AnyTLS sessions. Valid range: 1 to 3600. Defaults to 30.No
idle-session-timeoutIntegerIdle session timeout in seconds. Valid range: 1 to 3600. Defaults to 60.No
min-idle-sessionsIntegerMinimum idle sessions to keep. Valid range: 0 to 64. Defaults to 1.No
max-idle-sessionsIntegerMaximum idle sessions to keep. Valid range: 0 to 64. Defaults to 4.No

Example:

[l4proxies]
any=type:anytls,nickname:AnyTLS,server:any.example.com,port:443,password:secret,sni:cdn.example.com,skip-cert-check:false,session-reuse:true,idle-session-check-interval:30,idle-session-timeout:60,min-idle-sessions:1,max-idle-sessions:4,enabled:true

HTTP&Socks5 Fields

KeyTypeDescriptionRequired
usernameStringProxy username for upstream authentication.No
passwordStringProxy password for upstream authentication.No
udp-forwardBooleanSOCKS5 UDP forwarding flag. Currently kept for profile compatibility; UDP forwarding depends on runtime support.No

Example:

[l4proxies]
tshttp=type:http,nickname:tshttp,server:3.3.3.3,port:1055,enabled:true
tssocks=type:socks5,nickname:tssocks,server:10.1.1.1,port:1055,username:user,password:pass,enabled:true,udp-forward:false,route-via-vpn:true
ss2022=type:shadowsocks,nickname:SS2022,server:ss.example.com,port:8388,password:base64-psk,method:2022-blake3-aes-256-gcm,udp-forward:true,enabled:true
any=type:anytls,nickname:AnyTLS,server:any.example.com,port:443,password:secret,sni:cdn.example.com,skip-cert-check:false,session-reuse:true

[domain-sets]

Domain sets select an output through [routing]; they are separate from HTTP capture domains and exact DNS host records.

This section defines named sets of domains for use in routing rules. The key is the set name.

Example:

[domain-sets]
social-media=twitter.com,facebook.com,instagram.com

[cidr-sets]

This section defines named sets of IP ranges (CIDRs) for use in routing rules. The key is the set name.

Example:

[cidr-sets]
private-ips=10.0.0.0/8,192.168.0.0/16

[routing]

This section defines the routing rules, which are processed from top to bottom. It does not use key-value pairs.

Rule Format: TYPE,VALUE,ACTION,TARGET for match rules, or TYPE,ACTION,TARGET for reserved/default rules such as DNS-FALLBACK, VPN-DNS-SERVER-DOMAINS, and DEFAULT.

TypeValueActionTargetDescription
DOMAIN-SETName of a domain setL3VPN, L4PROXY, DIRECT, DROP, REJECTName of an l3vpn/l4proxyRoute based on a domain set.
CIDR-SETName of a CIDR setL3VPN, L4PROXY, DIRECT, DROP, REJECTName of an l3vpn/l4proxyRoute based on a CIDR set.
CIDRA single CIDRL3VPN, L4PROXY, DIRECT, DROP, REJECTName of an l3vpn/l4proxyRoute based on a single IP range.
DNS-FALLBACK(Not used)DIRECT, L3VPN, L4PROXY, etc.Name of an l3vpn/l4proxyDefault DNS behavior for domains not in any set.
VPN-DNS-SERVER-DOMAINS(Not used)L3VPN, L4PROXYName of an l3vpn/l4proxy(New in 1.9.0) route encrypted VPN DNS server domain bootstrap traffic through a selected VPN/proxy. Required when vpn-dns uses DoT/DoH upstreams with domain names.
DEFAULT(Not used)DIRECT, L3VPN, L4PROXY, etc.Name of an l3vpn/l4proxyThe final catch-all rule for all traffic.

Example:

[routing]
DOMAIN-SET,social-media,L4PROXY,my-shadowsocks
CIDR-SET,private-ips,DIRECT
VPN-DNS-SERVER-DOMAINS,L4PROXY,my-shadowsocks
DEFAULT,L3VPN,my-wireguard

[http-engine]

This section configures the internal HTTP engine.

KeyTypeDescription
enabledBooleanEnables the HTTP engine. Default false.
capture-allBooleanProcess every IPv4 destination on configured TCP ports; default false. Saved domain/CIDR lists remain intact.
cidr-listList of IPv4 CIDRsAdditional destination-IP capture scope.
port-listList of integersTCP ports from 1–65535; default 80,443.
http3-policyallow or blockDefault allow. Blocking HTTP/3 can encourage compatible clients to retry over TCP; it is not HTTP/3 decryption.
mitm-bypass-apple-servicesBooleanDefault true; avoid decrypting known Apple service domains.
mitm-bypass-domain-listList of domain suffixesAdditional domains that must not be decrypted.
upstream-tcp-receive-windowIntegerAdvanced upstream receive-window size in bytes: 4096–1048576, default 262144.
domain-listList of domain suffixesDomains to apply HTTP processing on; supports * for all domains.
ca-p12StringA base64 encoded PKCS#12 certificate authority. Note: Only RSA keys are currently supported.
ca-passphraseStringThe passphrase for the ca-p12 certificate.

Example:

[http-engine]
enabled=true
domain-list=example.com
ca-p12=...
ca-passphrase=...

[http-url-rewrite]

This section defines URL rewrite rules for the HTTP engine. The key is a user-defined name for the rule.

KeyTypeDescriptionRequired
matchRegexpA regular expression to match the URL.Yes
actionStringThe action to take. Supported: reject, redirect-302.Yes
targetStringThe target URL for redirection.No
enabledBooleanDefault true.No

Example:

[http-url-rewrite]
block-ads=match:^https?://ads\..*,action:reject
redirect-google=match:^https?://google\.com,action:redirect-302,target:https://duckduckgo.com

[simple-mode]

Select one typed output for ordinary client traffic. Saved advanced routing rules remain available when returning to Rules Mode; Simple Mode does not erase them.

[simple-mode]
enabled=true
output=type:DIRECT

For a configured VPN use output=type:L3VPN,target:my-wireguard; for a proxy use output=type:L4PROXY,target:my-proxy. The target must exist and be usable under the current entitlement. Do not use an unauthenticated Tailscale output as the browser's Internet path during initial login.

[dns-hosts] (Pro)

Exact hostnames mapped to IPv4 addresses, served by MintFlow DNS. These are DNS answers, not routing rules or wildcard domain suffixes. Configure routing separately and enable App Routing for this example:

[dns]
app-routing-enabled=true
direct-dns=1.1.1.1,8.8.8.8

[dns-hosts]
nas.example.com=192.168.40.10

At most 256 hostnames and 1–16 IPv4 addresses per hostname are supported. Static host records and derived Tailscale records are subject to entitlement and effective DNS configuration checks; inspect the compilation report.

[flowlog]

Local Flow Capture is available free. It records flow diagnostics; it is not an IPFIX remote exporter or an HTTP body recording.

KeyDefaultRange
enabledfalseBoolean
sampling-interval11–1000000
active-timeout-seconds51–3600
tcp-idle-timeout-seconds1202–86400
udp-idle-timeout-seconds302–3600
fin-grace-seconds51–300
max-flows-per-worker40961–16384
capture-duration-seconds00–86400; 0 means no duration limit
retention-hours241–720
max-database-rows1000001000–1000000
[flowlog]
enabled=true
sampling-interval=1
retention-hours=24

[http-body-rewrite]

Named request or response body rules reference managed local scripts. The app's editor and MFHRB importer manage the script resource and its profile reference. Do not paste a remote script URL here and expect automatic fetching or updates.

FieldMeaning
matchRequired regex over the normalized full URL; at most 4096 UTF-8 bytes.
directionrequest or response; default response.
typeRequired: jq or javascript.
body-modejson or text; jq requires JSON (default json for jq, text for JavaScript).
scriptRequired managed local resource reference, produced by the editor/importer.
priority0–1000000; default 100. Lower values run first; ties sort by rule name.
enabledDefault true in profile syntax. MFHRB imports always save it disabled.
api-version1.
timeout-msJavaScript only: 50–2000 ms, default 500.

The portable JSON bundle uses camel-case keys such as bodyMode and timeoutMS; profile text uses body-mode and timeout-ms. They are different formats. Use the MFHRB guide for a complete shareable example, API contract, and review workflow.

For example, if the managed resource ./feed-cleanup/remove-banner.jq already exists in this profile's script storage:

[http-body-rewrite]
remove-banner=match:^https://api\.example\.com/feed$,direction:response,type:jq,body-mode:json,priority:100,enabled:false,api-version:1,script:./feed-cleanup/remove-banner.jq

The referenced jq source could be .items |= map(select(.kind != "banner")) for a JSON object with an items array. The profile line does not create that file. Import an MFHRB bundle or use the app's script editor to manage the resource, and review it before enabling the rule.

Read this page as Markdown