9. Outbound Protocol Configuration#


Outbound protocols determine how Link1 ultimately connects to a target or upstream service. All static outbound nodes are defined in proxies; dynamic nodes from subscriptions, files, inline definitions, or WARP are defined in proxy-providers.

This chapter explains each protocol as “an egress type the user needs to configure,” instead of only listing fields. When reading about each protocol, consider four things:

  1. What problem it solves: a regular proxy, encrypted proxy, L3 VPN, enterprise VPN, or special egress.
  1. How a connection flows: whether Link1 uses TCP, UDP, QUIC, TLS, WireGuard, OpenVPN, or an enterprise proprietary protocol to reach the upstream.
  1. What behavior each field changes: how authentication, certificates, transport layer, DNS, UDP, routing, and performance parameters affect each part of the connection.
  1. Common pitfalls: which fields do not belong to this protocol, and which fields look similar but mean different things.

If you are configuring a protocol for the first time, we recommend copying the example in this chapter first and changing only the account, address, port, password/key provided by your service provider. After it works, adjust advanced fields as needed.

Common Outbound Node Structure#

proxies:
  - name: node-name
    type: socks5
    server: 127.0.0.1
    port: 1080

Common fields:

FieldMeaningActual effect
nameNode nameMust be unique; can be referenced by policy groups and rules
typeProtocol typeDetermines which outbound protocol implementation to use
server / addressRemote addressMost protocols use server; a few protocols are compatible with address
portRemote port0 is usually treated as not configured
dialer-proxyFront proxyDial through another node first, then connect to this node’s remote endpoint
interface-nameBind network interfaceControls the egress interface in multi-NIC/router scenarios
routing-markLinux markUsed with policy routing
ip-versionIP selection policyControls whether resolution/dialing prefers IPv4 or IPv6
tfoTCP Fast OpenCan reduce handshake latency for supported TCP protocols
mptcpMultipath TCPEnables Multipath TCP on supported platforms/protocols
udpUDP supportAffects UDP forwarding, games, QUIC, DNS, and more

Not every protocol supports all common fields. Link1 rejects unsupported fields during configuration compilation.

How Common Fields Affect Data Flow#

These fields do not belong to a single protocol. They affect how the “Link1 to upstream” segment is dialed:

Field groupFieldsHow users should understand it
Naming and referencesname, typename is the name referenced by rules and policy groups; type determines which protocol all following fields are interpreted as.
Remote locationserver, address, port, port-range, portsDetermines where the upstream is; ports/port-range usually indicate port hopping or protocol-specific capabilities, not ordinary backup ports.
Front chaindialer-proxyThe current node does not connect to the upstream directly. It goes through another node first. Commonly used for “connect to a local proxy first, then connect to an enterprise VPN/remote node.”
Egress selectioninterface-name, routing-mark, ip-versionControls which network interface, policy route, and IP family the underlying TCP/UDP traffic uses.
TCP capabilitiestfo, mptcpOnly affects protocols that use TCP. It may have no effect if the system or upstream does not support it.
UDP capabilityudpAffects whether UDP traffic such as DNS, QUIC, games, voice, WireGuard/MASQUE can use this node.

dialer-proxy is the easiest field to misunderstand. It is not a “backup node for this node.” It means “when connecting to this node’s server, go through another outbound first.” For example, if a trojan node uses dialer-proxy: PROXY, Trojan first establishes the underlying connection to its own server:port through the PROXY group. After the protocol handshake completes, this Trojan node still handles final application traffic using its own protocol.

Protocol Overview#

typeCategoryHow it worksWhen to choose itMain risks/notes
directSpecial egressLink1 connects directly to the target IP/domainLAN, domestic sites, targets that do not need a proxyStill goes through Link1; only the final connection is direct
rejectSpecial egressLink1 rejects the connection directlyAds, malicious domains, blocked accessMay cause applications to retry repeatedly
dnsSpecial egressHands the connection to the built-in DNS resolverDNS rules or internal DNS forwardingRarely written manually by regular users
httpExplicit proxyLink1 connects to an HTTP proxy, and the upstream then CONNECTs/forwards to the targetCorporate proxy, upstream HTTP proxyHTTP upstreams usually do not carry UDP
socks / socks5Explicit proxyLink1 connects to a SOCKS5 upstream, and the SOCKS5 server connects to the targetLocal proxy chains, simple upstreamsUDP depends on SOCKS5 UDP associate
sshTunnelLogs in to SSH first, then forwards TCP through an SSH channel; UDP requires udpgwYou have an SSH server or bastion hostHost key verification is important
vmessEncrypted proxyVMess user identity + optional TLS/WS/H2/gRPC/KCP and other transportsCompatible with legacy VMess nodesalterId, transport layer, and TLS must match the server
vlessEncrypted proxyVLESS user identity + TLS/REALITY/Vision/transport layerREALITY, Vision, XUDP nodesA wrong flow, REALITY, or SNI value will cause handshake failure
trojanEncrypted proxyTrojan password authentication, usually disguised as a TLS serviceSimple TLS proxyCertificate/SNI and password must all match
ss / shadowsocksEncrypted proxyAEAD/2022 encrypted proxy, with optional pluginLightweight proxy, routerscipher/password/plugin must match the server
ssr / shadowsocksrEncrypted proxySS + obfs/protocol compatibility extensionsLegacy SSR nodesMany parameter combinations; subscription fields may be inconsistent
shadowtlsWrapper/disguiseWraps traffic in a ShadowTLS TLS disguise, then carries subsequent trafficRequires a ShadowTLS upstreamVersion, password, and SNI must match
tuicQUIC proxyQUIC-based authentication and UDP/TCP forwardingMobile networks, UDP scenariosExperience will be poor if UDP is blocked
hysteriaQUIC proxyHysteria v1 with bandwidth and port hopping parametersLegacy HY1 nodesv1/v2 fields cannot be mixed
hysteria2 / hy2QUIC proxyHysteria2 password authentication + QUIC + optional Salamander obfuscationHigh-performance proxy, mobile networksobfs and certificate parameters must match
juicityQUIC proxyQUIC proxy with UUID/password authenticationJuicity serverCongestion control and certificate parameters affect connectivity
naiveHTTP/2/3 proxyNaiveProxy-style HTTP/2/3 upstreamCaddy/NaiveProxy ecosystemEssentially an authenticated HTTP/2/3 upstream
snellEncrypted proxySnell PSK authentication; v4/v5 support TCP, v3/v4/v5 support UDPSnell serverVersion and obfs must match
gost-relayProxy protocolLink1 connects to a GOST relay server and sends a relay CONNECT requestGOST relay TCP upstreams and chained hopsThe first version is TCP-only; no UDP/TLS/mTLS/mux
anytlsEncrypted proxyAnyTLS password authentication + TLS tunnelAnyTLS serverSNI/certificate/fingerprint still need to be handled
brookProxy protocolMultiple Brook server transports, with optional WS/WSS/QUIC/maskBrook servernetwork determines whether many fields are available
mieruProxy protocolMieru user authentication + TCP/UDP transportMieru servertransport, multiplexing, and handshake must match
trusttunnelTunnelLightweight tunnel with HTTP/2 ALPN, supports UDP over streamTrustTunnel serverALPN must include h2
sudokuExtended protocolPassword/key + AEAD + padding/table/http-maskSudoku serverpadding/table/mask parameters must match the server
wireguard / wgL3 tunnelEstablishes a WireGuard virtual Layer 3 linkWARP, self-hosted WG, enterprise tunnelsallowed-ips has tunnel routing semantics; it is not a rule
masqueHTTP/3 tunnelBuilds a tunnel through HTTP/3 MASQUE CONNECT-UDP/IPWARP MASQUE, services that support MASQUEQUIC, URI, certificate, and MTU all affect connectivity
tailscaleMesh/VPNLogs in to Tailnet/Headscale and uses an exit node or routesDevice mesh networking, LAN accessAffected by control-plane policies and node authorization
openvpnVPNOpenVPN control-plane handshake + userspace netstack forwardingEnterprise OpenVPN, traditional VPNDNS/routes come from push or configuration; it cannot be treated as a regular proxy
atrustEnterprise VPNLogs in to ATrust, obtains enterprise routes/DNS, then acts as an egressSangfor/enterprise accessAuthentication policy, CAPTCHA, and device binding have major impact
feilianEnterprise VPNLogs in to Feilian and selects a VPN gatewayFeilian enterprise networkGateway selection and session persistence are critical
easyconnectEnterprise VPNLogs in to EasyConnect, then acts as an enterprise VPN egressEasyConnect enterprise networkServer versions/policies vary significantly
warpWARP providerNot used directly as a leaf; materializes WireGuard/MASQUE nodes through a providerCloudflare WARP egressMust be written in proxy-providers, not in proxies

Protocol configuration can often be inferred from upstream materials:

Which Outbound Should I Choose?#

If you are not “designing your own server protocol” but entering an account someone gave you into Link1, choose the protocol based on the provider’s materials first. Do not change the type based on guesswork. The table below gives selection suggestions from user scenarios:

ScenarioProtocols to check firstWhyWhat not to do at first
Your company provides an HTTP/SOCKS proxyhttp, socks5Few fields, usually only address, port, username, and password.Do not mistakenly write it as HTTP Engine. HTTP Engine is a content rewriting module, not an upstream HTTP proxy.
Airport/subscription nodesvmess, vless, trojan, ss, hysteria2, tuicThese are common proxy node types, and subscriptions usually already include protocol fields.Do not casually change network, tls, sni, flow, or obfs; they must match the server.
You have your own SSH serversshNo dedicated proxy service needs to be deployed; TCP can be forwarded through SSH channels.Do not treat SSH as a high-performance UDP proxy; UDP requires udpgw support.
High performance, mobile networks, UDP requiredhysteria2, tuic, wireguard, masqueQUIC/WireGuard-like protocols are better suited for UDP and network switching.If the local network blocks UDP, check UDP reachability first. Do not only change the password or certificate.
Cloudflare WARP egressproxy-providers.type=warpWARP generates WireGuard/MASQUE candidate nodes and is naturally a provider.Do not write proxies[].type=warp.
Enterprise VPN/LAN accessopenvpn, atrust, feilian, easyconnect, tailscaleThese protocols bring LAN routes, enterprise DNS, or device login state.Do not treat it only as a “proxy port”; DNS, routes, and account state must all be considered.
Direct connection for LAN/domestic sitesDIRECT or directThe target does not need a proxy, and direct connection has the lowest latency.Do not put all traffic into a remote node. LAN addresses should be direct first.
Ad/malicious domain blockingREJECT or rejectRejects connections directly and reduces meaningless outbound traffic.Do not make the blocking scope too broad, or applications may keep retrying or malfunction.

A simple decision tree:

Did you receive a ready-made node/subscription?
  Yes -> Fill fields according to the node type; do not change the protocol
  No -> Is it an enterprise VPN/intranet account?
         Yes -> openvpn / atrust / feilian / easyconnect / tailscale
         No -> Is it WARP?
                Yes -> proxy-providers.type=warp
                No -> Is it only an upstream proxy port?
                       Yes -> http / socks5 / naive
                       No -> choose based on the self-hosted server protocol

TLS, Transport, and Extension Fields#

Many protocols share TLS fields:

tls: true
skip-cert-verify: false
servername: example.com
sni: example.com
alpn: [h2]
client-fingerprint: chrome

Practical effects:

Common transports for VMess/VLESS/Trojan:

network: ws
ws-opts:
  path: /ws
  headers:
    Host: example.com
networkRelated fieldsEffect
tcp or emptyNone or protocol default fieldsPlain TCP transport
httphttp-optsHTTP camouflage
wsws-optsWebSocket transport
h2h2-optsHTTP/2 transport
grpcgrpc-optsgRPC transport
kcpkcp-optsKCP transport
xhttpxhttp-optsXHTTP-compatible transport, for VMess/VLESS/Trojan-like nodes that support xHTTP

REALITY:

reality-opts:
  public-key: xxxxx
  short-id: abcd
  fingerprint: chrome

ECH:

ech-opts:
  enable: true
  mode: grease
  query-server-name: example.com

SMUX:

smux:
  enabled: true
  protocol: smux
  max-connections: 4
  min-streams: 4
  max-streams: 32

How to read transport sub-configuration fields#

Sub-configurationCommon fieldsPractical effect
http-optsmethod, path, headersUsed for HTTP camouflage transport; path/header must match the server.
ws-optspath, headers, max-early-data, early-data-header-name, v2ray-http-upgradeWebSocket path, Host, and early data behavior; most commonly used with CDN/reverse proxy setups.
h2-optshost, pathauthority/path for HTTP/2 transport.
grpc-optsgrpc-service-name, grpc-user-agentgRPC service name and UA; a service name mismatch looks like "the port is reachable, but the protocol is not."
kcp-optsseed, header-type, mtu, tti, uplink-capacity, downlink-capacity, congestion, write-buffer, read-bufferKCP transport parameters; server support is required, and wrong parameters can cause handshake or performance issues.
ss-optsenabled, method, passwordTrojan's Shadowsocks extension, not a regular ss node.
plugin / plugin-optsPlugin name and plugin parametersShadowsocks plugin obfuscation; must match the server-side plugin.
obfs-optsmode, host, etc.Snell/plugin obfuscation parameters.
smuxenabled, protocol, max-connections, min-streams, max-streams, padding, statistic, only-tcpMultiplexing settings; can reduce the number of connections, but is not suitable for every network. Disable it first when troubleshooting.

How to read TLS/REALITY/ECH fields#

FieldUsed by which protocolsHow users should understand it
tlsVMess/VLESS/Trojan/HTTP/Brook/Naive, etc.Whether to wrap the protocol with TLS; not all protocols allow it to be set manually.
servername / sniTLS-like protocolsThe service name in the TLS handshake; usually must equal the certificate domain or the camouflage domain required by the server.
skip-cert-verifyTLS-like protocolsSkips certificate verification. Recommended only for self-signed certificates or testing; reduces security.
alpnTLS/H2/H3/TrustTunnel, etc.Negotiates the application-layer protocol, such as h2, h3, or http/1.1.
client-fingerprintProtocols that support uTLSAdjusts the ClientHello fingerprint, such as chrome.
pinned-certchain-sha256Certificate pinning scenariosAccepts only the specified certificate chain. Suitable for strict verification, but configuration is more costly.
reality-opts.public-keyVLESS/REALITYServer REALITY public key.
reality-opts.short-idVLESS/REALITYShort ID assigned by the server.
reality-opts.fingerprintVLESS/REALITYFingerprint parameter used by REALITY.
reality-opts.support-x25519mlkem768VLESS/REALITYPost-quantum/extended handshake capability, which must be compatible with the server.
ech-opts.enableTLS outbounds that support ECHEnables Encrypted ClientHello.
ech-opts.modeECHECH mode, such as grease/real configuration.
ech-opts.configECHManually provided ECHConfig.
ech-opts.query-server-nameECHWhich domain name to use when querying the ECH configuration.

If you do not know whether these fields are needed, do not set them at first. Set them only when provided by your service provider, and match the field values exactly.

Special Outbounds#

direct#

Connect directly to the target server.

proxies:
  - name: local-direct
    type: direct
    interface-name: eth0

Field effects:

reject#

Reject connections.

proxies:
  - name: block
    type: reject

Used for rules that block ads, malicious traffic, or disallowed access. The built-in REJECT already exists.

dns#

A special outbound that hands traffic to Link1's built-in DNS resolver.

proxies:
  - name: dns-out
    type: dns

Regular users usually do not need to configure it explicitly.

Explicit Proxy Protocols#

http#

An HTTP upstream proxy works as follows: Link1 first connects to the upstream HTTP proxy. If the client accesses HTTPS, Link1 sends CONNECT target:443 to the upstream, and the upstream establishes a TCP tunnel to the target. If the client accesses plaintext HTTP, the upstream can forward the full HTTP request.

Suitable for: corporate proxies, HTTP proxies on cloud servers, and upstreams that require Basic authentication. It is not HTTP Engine and does not automatically decrypt HTTPS content.

proxies:
  - name: http-upstream
    type: http
    server: proxy.example.com
    port: 8080
    username: alice
    password: secret
    tls: false

Key fields:

FieldEffect
server / portHTTP proxy server address
username / passwordBasic authentication
tlsWhether to use TLS when connecting to the upstream proxy
headersAdditional request headers
skip-cert-verify / servernameAffect the certificate and SNI in TLS mode

socks / socks5#

A SOCKS5 upstream proxy works as follows: Link1 passes the target address to the SOCKS5 server, and the SOCKS5 server connects to the target. The target can be a domain name or an IP address.

DNS impact: If Link1 passes the domain name to SOCKS5, the upstream is responsible for resolution. If Link1 resolves it to an IP first and then passes it to SOCKS5, domain information may be lost. In transparent proxy/TUN scenarios, it is still recommended to let Link1 DNS/Fake-IP provide domain context first.

UDP impact: udp: true means Link1 will try to use SOCKS5 UDP associate. If the upstream does not support it, UDP traffic will fail, but TCP may still work normally.

proxies:
  - name: socks-upstream
    type: socks5
    server: 127.0.0.1
    port: 1080
    username: alice
    password: secret
    udp: true

Key fields:

FieldEffect
server / portSOCKS5 server
username / passwordSOCKS5 username and password
udpWhether to use SOCKS5 UDP associate
tfoTCP Fast Open, which requires protocol and system support

ssh#

An SSH outbound works as follows: Link1 first logs in to the SSH server, then forwards TCP traffic through an SSH channel. It is more like "using the SSH server as a jump host" than a traditional encrypted proxy protocol.

Authentication can use either a password or a private key. In production, it is strongly recommended to configure host-key to verify the server host key. skip-host-key-verify is only suitable for temporary testing. UDP is not a native SSH capability; Link1 bridges it through udpgw mode, so a corresponding gateway is required.

proxies:
  - name: ssh-node
    type: ssh
    server: ssh.example.com
    port: 22
    username: root
    private-key: ./id_ed25519
    private-key-passphrase: secret
    host-key:
      - SHA256:xxxxxxxx
    udp: true
    udp-relay-mode: udpgw
    udp-gateway: 127.0.0.1:7300

Key fields:

FieldEffect
usernameSSH login user, required
password / private-keyChoose one authentication method
private-key-passphrasePassphrase for the encrypted private key
host-keyAllowed server host keys; recommended for production
skip-host-key-verifySkips host key verification; insecure
host-key-algorithmsRestricts host key algorithms
udpEnables UDP forwarding capability
udp-relay-modeUses udpgw
udp-gatewayudpgw address; requires udp=true

Limitations: SSH does not support TLS, VMess/VLESS transport fields, Reality, ECH, SMUX, or other proxy protocol extensions.

VMess / VLESS / Trojan#

These three protocol types are common in "node subscriptions". Their configuration consists of three layers: identity fields (uuid/password), security layer (TLS/REALITY/certificates/SNI), and transport layer (TCP/WS/H2/gRPC/KCP). When troubleshooting, do not only check whether the port is reachable. Many failures happen because TLS, REALITY, or the transport-layer path does not match.

vmess#

proxies:
  - name: vmess-ws
    type: vmess
    server: example.com
    port: 443
    uuid: 00000000-0000-0000-0000-000000000000
    alterId: 0
    cipher: auto
    tls: true
    network: ws
    ws-opts:
      path: /ws
      headers:
        Host: example.com

Key fields:

FieldImpact
uuidVMess user ID, required
alterIdVMess compatibility field
cipherVMess encryption method
tls / skip-cert-verify / servernameTLS behavior
network + *-optsTransport layer
udpUDP forwarding capability
smuxMultiplexing

vless#

proxies:
  - name: vless-reality
    type: vless
    server: example.com
    port: 443
    uuid: 00000000-0000-0000-0000-000000000000
    flow: xtls-rprx-vision
    encryption: none
    tls: true
    network: tcp
    reality-opts:
      public-key: xxxxx
      short-id: abcd
      fingerprint: chrome

Key fields:

FieldImpact
uuidVLESS user ID, required
flowVLESS flow, such as Vision
encryptionUsually none
tlsVLESS is commonly used with TLS/REALITY
reality-optsREALITY parameters
packet-addr / xudp / packet-encodingUDP extension semantics
udp-over-tcp / udp-over-tcp-versionUDP over TCP compatibility extension

trojan#

proxies:
  - name: trojan-grpc
    type: trojan
    server: example.com
    port: 443
    password: secret
    tls: true
    network: grpc
    grpc-opts:
      grpc-service-name: trojan

Key fields:

FieldImpact
passwordTrojan password, required
tlsTrojan usually uses TLS
networkCan use transports such as WS/H2/gRPC
ss-optsTrojan Shadowsocks extension configuration
udpUDP forwarding capability

Shadowsocks Ecosystem#

The core of the Shadowsocks ecosystem is "encryption method + password". SS itself is lightweight. Fields such as plugins, UDP-over-TCP, XUDP, and packet-addr exist to support different servers and transport scenarios. SSR and ShadowTLS are different compatibility/wrapping protocols, and their fields cannot be mixed.

ss / shadowsocks#

proxies:
  - name: ss-node
    type: ss
    server: example.com
    port: 8388
    cipher: 2022-blake3-aes-128-gcm
    password: secret
    udp: true
    plugin: obfs
    plugin-opts:
      mode: tls
      host: www.example.com

Key fields:

FieldImpact
cipherEncryption method, required
passwordPassword, required
udpUDP forwarding
plugin / plugin-optsPlugin obfuscation
smuxMultiplexing
udp-over-tcpUDP over TCP
packet-addr / xudpUDP address extensions

Shadowsocks cipher and plugin combinations#

Shadowsocks is the most typical "cipher suite + plugin" protocol in this chapter. You can think of it as two layers:

  1. cipher and password encrypt the SS data stream.
  1. plugin and plugin-opts disguise or wrap the TCP connection to the SS server into another form.

Link1 processes them in this order: first connect to server:port; if a plugin is configured, let the plugin wrap this upstream connection first; then run the Shadowsocks encryption protocol over the plugin connection. Therefore, the server-side cipher, password, and plugin parameters must match field by field.

Supported ciphers:

CategoryAllowed cipher valuesDescription
Standard AEADaes-128-gcm, aes-192-gcm, aes-256-gcm, aes-128-ccm, aes-192-ccm, aes-256-ccm, aes-128-gcm-siv, aes-256-gcm-siv, chacha20-ietf-poly1305, chacha8-ietf-poly1305, xchacha20-ietf-poly1305, xchacha8-ietf-poly1305AEAD is recommended first. The chacha* series is usually suitable for devices without AES acceleration.
Extended AEADlea-128-gcm, lea-192-gcm, lea-256-gcm, rabbit128-poly1305, aegis-128l, aegis-256, deoxys-ii-256-128, aez-384, ascon128, ascon128aUse only when explicitly provided by the server. If the server does not support it, the handshake will fail directly or there will be no response.
Shadowsocks 20222022-blake3-aes-128-gcm, 2022-blake3-aes-256-gcm, 2022-blake3-chacha20-poly1305, 2022-blake3-chacha8-poly1305, 2022-blake3-aes-128-ccm, 2022-blake3-aes-256-ccmSS 2022 uses an independent key format. Do not casually reuse an old SS password with a 2022 cipher.
Legacy stream cipheraes-128-cfb, aes-192-cfb, aes-256-cfb, aes-128-ctr, aes-192-ctr, aes-256-ctr, chacha20, chacha20-ietf, xchacha20, xchacha20-ietf, rc4-md5Kept for compatibility with old servers. Not recommended as the first choice for new configurations.
Plaintext/testingnone, dummyOnly suitable for special testing or compatibility scenarios. It does not provide normal encryption protection.

The configuration is also compatible with some aliases that use different letter cases, underscores, or ss-2022-*; the user documentation only lists the recommended forms.

Supported plugins:

pluginCore plugin-opts combinationTCP behaviorUDP behaviorSuitable scenarios
Not configuredNoneRuns the SS encrypted stream directlyUses native SS UDP when udp: trueSimplest and most stable.
obfsmode: http or mode: tls; optional hostsimple-obfs-style HTTP/TLS disguiseThe plugin itself does not support UDP packets. If UDP is required, the server must support it and you need to use a stream-based solution such as udp-over-tcpOld servers, lightweight disguise.
v2ray-pluginmode: websocket/ws; optional host, path, headers, tls, mux, v2ray-http-upgrade, skip-cert-verify, fingerprint, certificate/private-key, ech-optsWraps SS TCP in WebSocket, with optional TLS, HTTP Upgrade, and mux layered on topThe plugin itself does not support UDP packets. When UDP is required, first confirm whether the server supports udp-over-tcpCDN/reverse proxy/WebSocket servers.
gost-pluginmode: websocket/ws; optional host, path, headers, tls, mux, fingerprint, certificate/private-key, ech-optsGOST-style WebSocket wrapping; mux is enabled by defaultThe plugin itself does not support UDP packets. When UDP is required, it depends on a stream-based UDP solutionIntegrating with the GOST plugin ecosystem.
cloaktransport: direct/cdn; required uid, publicKey, serverName; optional proxyMethod, encryptionMethod: plain/aes-gcm/aes-256-gcm/aes-128-gcm/chacha20-poly1305, browserSig: chrome/firefox/safari, cdnOriginHost, cdnWsUrlPath, numConn, streamTimeout, keepAlive, udpCloak handshake and session disguise; can connect directly or use CDN modeThe plugin provides UDP over stream packet capability only when plugin-opts.udp: trueCloak servers and strong disguise scenarios.
shadow-tlsOptional password, host, version: 1/2/3, alpn, strict-mode, skip-cert-verify, fingerprint, client-fingerprint, certificate/private-keyLayers ShadowTLS disguise outside SS; host defaults to the upstream hostDoes not support plugin UDP packetsConnecting to ShadowTLS plugin servers.
restlsRequired password; optional host, version-hint: tls12/tls13, restls-script, fingerprint: chrome/firefox/safari/ios, skip-cert-verifyLayers the Restls handshake outside SSDoes not support plugin UDP packetsRestls servers.

When using combinations, troubleshoot in this order:

ssr / shadowsocksr#

proxies:
  - name: ssr-node
    type: ssr
    server: example.com
    port: 8388
    cipher: aes-256-cfb
    password: secret
    obfs: tls1.2_ticket_auth
    obfs-param: example.com
    protocol: auth_sha1_v4
    protocol-param: ''

Key fields:

FieldImpact
cipherSSR encryption method
passwordPassword
obfs / obfs-paramObfuscation method and parameters
protocol / protocol-paramSSR protocol plugin
udpUDP forwarding

ShadowsocksR cipher / obfs / protocol combinations#

SSR configuration is determined by three things at the same time: cipher handles encryption, obfs controls traffic appearance, and protocol handles SSR authentication/fragmentation format. Link1 supports the following combinations:

Combination dimensionAllowed valuesHow users should choose
ciphernone, rc4-md5, aes-128-cfb, aes-192-cfb, aes-256-cfb, aes-128-ctr, aes-192-ctr, aes-256-ctr, chacha20, chacha20-ietf, xchacha20Use the value provided by the service provider. SSR nodes are mostly legacy nodes, so upgrading the cipher yourself is not recommended.
obfsplain, http_simple, http_post, random_head, tls1.2_ticket_auth, tls1.2_ticket_fastauthFollow the server. obfs-param is usually a disguise domain or HTTP header parameter.
protocolorigin, auth_sha1_v4, auth_aes128_md5, auth_aes128_sha1, auth_chain_a, auth_chain_bFollow the server. protocol-param is commonly a user ID/password-style parameter. Fill in whatever the subscription provides.

These dimensions can be combined at the configuration layer, but whether they actually work depends on whether the SSR server uses the same combination. When troubleshooting SSR, do not look only at cipher. Any mismatch in obfs or protocol can result in no data after the connection is established, quick disconnections, or UDP issues.

shadowtls#

proxies:
  - name: shadowtls-node
    type: shadowtls
    server: example.com
    port: 443
    password: secret
    version: 3
    sni: www.example.com

Key fields:

FieldImpact
passwordShadowTLS password, required
versionShadowTLS version
sni / servernameDisguised TLS domain
certificate / private-keyUsed as certificate material when both are configured
dialer-proxyCan be combined with a front proxy; some socket fields become unavailable after it is set

QUIC / High-Performance Proxy Protocols#

This group of protocols mainly runs over QUIC/UDP. They are usually friendlier to mobile networks, packet loss, and UDP traffic, but only if the local network, ISP, router, and upstream all allow UDP. If “TCP websites open, but video/games/QUIC do not work,” check udp, firewall rules, and upstream UDP support first.

The bandwidth fields up/down are important inputs for protocol scheduling and congestion control, not just display text. Setting them too high may cause packet loss; setting them too low may limit throughput.

tuic#

proxies:
  - name: tuic-node
    type: tuic
    server: example.com
    port: 443
    uuid: 00000000-0000-0000-0000-000000000000
    password: secret
    udp: true
    udp-relay-mode: native
    congestion-controller: bbr
    reduce-rtt: true

Key fields:

FieldEffect
uuid / passwordTUIC authentication
udp-relay-modeUDP relay mode, such as native / quic
congestion-controllerCongestion control: cubic, new_reno, bbr, brutal
reduce-rttReduces handshake RTT
request-timeoutRequest timeout
heartbeat-intervalHeartbeat interval
disable-sniDisables SNI
max-udp-relay-packet-sizeMaximum UDP relay packet size
bbr-profileSelects a BBR parameter profile when congestion-controller: bbr. Supports standard, conservative, and aggressive. If the controller is not set but bbr-profile is set, BBR is enabled by default.

hysteria#

proxies:
  - name: hy1-node
    type: hysteria
    server: example.com
    port: 443
    auth-str: secret
    protocol: udp
    up: 50 Mbps
    down: 200 Mbps
    sni: example.com

Key fields:

FieldEffect
auth / auth-strHysteria v1 authentication
protocoludp, wechat-video
up / downBandwidth hints that affect congestion/rate policies
obfs / obfs-passwordObfuscation
ports / hop-intervalPort hopping
recv-window / recv-window-connQUIC window

faketcp depends on Linux raw-socket behavior, so Spark does not expose this non-cross-platform protocol feature.

hysteria2 / hy2#

proxies:
  - name: hy2-node
    type: hysteria2
    server: example.com
    port: 443
    password: secret
    obfs: salamander
    obfs-password: obfs-pass
    sni: example.com
    skip-cert-verify: false
    up: 50 Mbps
    down: 200 Mbps

Key fields:

FieldEffect
passwordHysteria2 password
obfs: salamander / obfs-passwordSalamander obfuscation
sni / servernameTLS SNI
up / downBandwidth hints
ports / hop-intervalPort hopping
skip-cert-verifyCertificate verification
bbr-profileSelects a BBR parameter profile when congestion-controller: bbr. Supports standard, conservative, and aggressive.
realm-optsRealm relay configuration, used to help relay Hysteria2 through a realm server / STUN.

Hysteria2 has very few optional obfuscation combinations. The following two forms are supported:

Field combinationAllowed valuesActual effect
No obfuscationOmit obfs / obfs-passwordUses Hysteria2 QUIC/TLS traffic directly.
Salamander obfuscationobfs: salamander + obfs-password: <secret>QUIC packets are obfuscated with Salamander. Setting only obfs-password or only obfs will be rejected.

realm-opts is suitable when the server does not directly expose regular ports and forwarding must be coordinated through a realm server/STUN. After it is configured, server-url, token, realm-id, and at least one stun-servers entry must be provided. It cannot be used together with ports port hopping. realm-opts.proxy indicates the outbound used to access the realm control plane, and is not the same as the node’s own dialer-proxy.

realm-opts:
  enable: true
  server-url: https://realm.example
  token: xxxxx
  realm-id: hy2-realm
  stun-servers:
    - stun.example:3478
  sni: realm.example
  proxy: PROXY

Legacy protocol fields such as cipher, protocol, network, and plugin do not belong to Hysteria2. If these fields appear after conversion from another subscription format, they are usually ignored or rejected during validation.

juicity#

proxies:
  - name: juicity-node
    type: juicity
    server: example.com
    port: 443
    uuid: 00000000-0000-0000-0000-000000000000
    password: secret
    sni: example.com
    congestion-controller: bbr

Key fields: uuid, password, sni, skip-cert-verify, congestion-controller, udp.

naive#

proxies:
  - name: naive-node
    type: naive
    server: example.com
    port: 443
    username: alice
    password: secret
    tls: true

NaiveProxy uses an HTTP/2/HTTP/3-style upstream proxy. Key fields: username, password, tls, skip-cert-verify, servername, alpn.

Other Proxy Protocols#

Each protocol in this group has its own server ecosystem. Unlike VMess/VLESS, they do not share many transport fields, so the most important rule is to match the server documentation field by field: version, password/key, obfuscation, mask, padding, and UDP policy must all match.

snell#

proxies:
  - name: snell-node
    type: snell
    server: example.com
    port: 443
    psk: secret
    version: 3
    udp: true
    obfs-opts:
      mode: tls
      host: www.example.com

Key fields:

FieldEffect
pskSnell key
version1/2/3/4/5
udpSnell v3/v4/v5 support UDP over TCP
reuseExplicitly unsupported for now; reuse: true fails validation, and the default is equivalent to false
obfs-optsSnell obfuscation configuration

Supported Snell version/obfuscation combinations:

Field combinationAllowed valuesActual effect
version1, 2, 3, 4, 5; defaults to 1 if omittedThe version must match the server. 5 is handled as a v4-compatible client; udp: true is allowed with version: 3/4/5.
No obfuscationOmit obfs-opts or leave obfs-opts.mode emptyRuns the Snell protocol directly.
HTTP obfuscationobfs-opts.mode: http, optional obfs-opts.hostDisguises the first packet as an HTTP request. If host is omitted, the implementation uses a default value.
TLS obfuscationobfs-opts.mode: tls, optional obfs-opts.hostDisguises the first packet as TLS traffic. Must match the server configuration.

network is handled as TCP behavior. Snell is not a generic WebSocket/TLS transport protocol and does not support transport sub-configurations such as ws-opts or grpc-opts.

gost-relay#

proxies:
  - name: relay-node
    type: gost-relay
    server: relay.example.com
    port: 8420
    username: user
    password: pass
    dialer-proxy: DIRECT

gost-relay is a lightweight TCP outbound implementation for GOST relay v1. Link1 first connects to server:port, sends a relay CONNECT request, and then forwards subsequent TCP traffic to the target address. It is useful when a GOST relay server acts as a chained hop, or when it is used as the dialer-proxy for another outbound.

Key fields:

FieldEffect
server / portGOST relay server address.
username / passwordOptional relay user authentication. Each field is limited to 255 bytes.
dialer-proxyOptional front outbound; connects to the relay server through the specified node first.
interface-name / routing-mark / tfoControls the underlying TCP dial for the segment connecting to the relay server.

First-version limitations: TCP CONNECT only. udp: true, tls: true, and network: udp fail during configuration compilation. GOST relay TLS/mTLS, mux, and UDP forward/associate are intentionally out of scope for this phase.

anytls#

proxies:
  - name: anytls-node
    type: anytls
    server: example.com
    port: 443
    password: secret
    sni: example.com

Key fields: password, sni/servername, skip-cert-verify, udp, alpn, client-fingerprint.

brook#

proxies:
  - name: brook-node
    type: brook
    server: example.com
    port: 443
    password: secret
    network: ws
    ws-opts:
      path: /ws
    tls: true

Key fields:

FieldEffect
passwordBrook password
networktcp, ws, quic, etc.; validated by the implementation
without-brook-protocolCompatibility field for some WS/WSS/QUIC modes
fragmentBrook WSS server fragment configuration
http-mask*HTTP mask compatibility fields
udp-over-tcpSupported only by specific Brook server transports

mieru#

proxies:
  - name: mieru-node
    type: mieru
    server: example.com
    port: 443
    username: alice
    password: secret
    transport: TCP

Key fields: username, password, server, port, transport, multiplexing, handshake-mode.

trusttunnel#

proxies:
  - name: trust-node
    type: trusttunnel
    server: example.com
    port: 443
    username: alice
    password: secret
    alpn: [h2]
    udp: true
    udp-over-stream: true

Key fields:

FieldEffect
username / passwordOptional authentication. A username is required when a password is set.
alpnMust include h2
udp-over-streamUDP over stream
udp-relay-modeOnly native is allowed
congestion-controllercubic, new_reno, bbr
certificate / private-keyConfigured as a pair

sudoku#

proxies:
  - name: sudoku-node
    type: sudoku
    server: example.com
    port: 443
    password: secret
    aead-method: chacha20-poly1305
    udp: true
    sudoku-udp-policy: uot
    padding-min: 1
    padding-max: 8

Key fields:

FieldEffect
password / keyAt least one is required for authentication/keying
aead-methodchacha20-poly1305, aes-128-gcm, none
padding-min / padding-maxPadding range, 0-100
table-typeprefer_ascii or prefer_entropy
custom-table / custom-tablesMust be used with table-type=prefer_entropy
http-mask / httpmaskHTTP mask switch/compatibility configuration
http-mask-modelegacy, stream, poll, auto
http-mask-host / path-rootHTTP mask target appearance
http-mask-multiplexoff, auto, on
sudoku-udp-policyreject, direct, uot

Supported Sudoku security/obfuscation combinations:

Combination dimensionAllowed valuesActual effect
aead-methodchacha20-poly1305, aes-128-gcm, none; uses the default if omittedEncrypts data frames. none is only allowed in the special pure downlink scenario with enable-pure-downlink: true.
paddingpadding-min / padding-max from 0 to 100, and max must not be less than minChanges packet length distribution. Mismatched values on the two ends affect compatibility.
tabletable-type: prefer_ascii or prefer_entropy; custom tables require prefer_entropyControls the data transformation table. A custom table must be 8 characters, with x=2,p=2,v=4.
HTTP maskhttp-mask: true, http-mask-mode: legacy/stream/poll/auto, with optional http-mask-host, path-root, http-mask-tlsMakes Sudoku traffic look more like HTTP. Related fields are meaningful only when http-mask: true is set.
HTTP mask multiplexhttp-mask-multiplex: off/auto/onControls multiplexing under HTTP mask. It cannot be configured alone when HTTP mask is not enabled.
UDP policysudoku-udp-policy: reject/direct/uotreject rejects UDP; direct connects UDP directly; uot carries UDP using a UDP-over-TCP approach.

Sudoku currently implements only TCP outbound networking. If network is configured, it can only be tcp or left empty.

L3 Tunneling and Networking Protocols#

The biggest difference between L3 tunnels and regular proxies is that they provide a “virtual network link”, not just CONNECT/SOCKS forwarding. DNS, routing, MTU, tunnel addresses, and allowed routes all affect which addresses can be reached.

Users should clearly distinguish between two routing layers:

wireguard / wg#

proxies:
  - name: wg-node
    type: wireguard
    private-key: xxxxx
    ip: 172.16.0.2/32
    ipv6: 2606:4700::1/128
    mtu: 1280
    peers:
      - server: engage.cloudflareclient.com
        port: 2408
        public-key: xxxxx
        pre-shared-key: optional
        allowed-ips:
          - 0.0.0.0/0
          - ::/0

Key fields:

FieldEffect
private-keyLocal WireGuard private key
ip / ipv6Local tunnel address
public-key / pre-shared-keyPeer keys
reservedreserved bytes, required by some providers
allowed-ipsRouted prefixes that are allowed
peersMulti-peer list
mtuTunnel MTU
persistent-keepaliveNAT keepalive
amnezia-wg-optionAmneziaWG extension
dns / remote-dns-resolveRemote DNS related settings

WireGuard DNS and allowed-ips#

allowed-ips are the tunnel route prefixes for the WireGuard peer, not Link1 top-level rules. Providers usually supply 0.0.0.0/0 and ::/0, meaning all destinations after entering this outbound are allowed to go through this peer. If only enterprise intranet prefixes are provided, only those intranet IPs are reachable inside the tunnel.

dns and remote-dns-resolve are used to decide “where this domain name should be resolved”. VPN types default to remote-dns-resolve: true: when the destination is still a domain name, Link1 preferentially lets the VPN runtime resolve it using tunnel DNS. dns can manually specify tunnel DNS. If the runtime has no DNS provided by the server or configuration, enabling remote resolution will directly return an error and will not silently fall back to local DNS. To reuse local/global DNS, explicitly set remote-dns-resolve: false.

masque#

proxies:
  - name: masque-node
    type: masque
    server: example.com
    port: 443
    uri: https://example.com/.well-known/masque/udp/1.1.1.1/443/
    sni: example.com
    handshake-mode: strict
    congestion-controller: bbr
    mtu: 1280

Key fields:

FieldEffect
uriMASQUE target URI
sni / servernameTLS SNI
handshake-modestrict or compatibility mode
networkDefaults to h3; can be h3/http3/quic or h2/http2. h2 uses HTTP/2 fallback and does not support QUIC congestion control fields.
congestion-controllerQUIC congestion control: cubic, new_reno, bbr, brutal; only effective when network=h3.
bbr-profileBBR parameter profile. Supports standard, conservative, and aggressive; only supports network=h3. If set without specifying a controller, BBR is enabled by default.
cwndInitial congestion window; only effective when network=h3.
up / downBandwidth hints for brutal congestion control; only effective when network=h3.
dialer-proxyUses an upstream outbound when connecting to the MASQUE endpoint. After setting it, interface-name / routing-mark cannot be used at the same time.
remote-dns-resolve / dnsRemote DNS
mtuTunnel MTU

MASQUE DNS and URI#

The MASQUE uri is not just a normal URL. It describes where the HTTP/3 MASQUE server accepts CONNECT-UDP/IP. server/port decides which endpoint to connect to, sni/servername decides the TLS handshake domain name, and uri decides the MASQUE request target. These three may be the same, or they may be provided separately by the provider.

dns and remote-dns-resolve have meanings similar to WireGuard: they control domain resolution after entering the MASQUE tunnel. VPN MASQUE defaults to remote-dns-resolve: true; it can be explicitly set to false to fall back to local/global DNS. For WARP MASQUE, the provider materializes the DNS and remote resolve parameters from the WARP state into the generated MASQUE node.

tailscale#

proxies:
  - name: tailnet
    type: tailscale
    auth-key: tskey-xxxxx
    hostname: link1-router
    control-url: https://headscale.example.com
    exit-node: 100.64.0.10
    auto-route: true
    route-rule-set: tailnet-routes

Key fields:

FieldEffect
auth-keyKey for logging in to Tailscale/Headscale
hostnameNode name
control-urlControl-plane URL, used in Headscale scenarios
ephemeralEphemeral node
accept-routesWhether to accept routes pushed by the control plane; defaults to true
exit-nodeUse the specified exit node as the outbound
exit-node-allow-lan-accessWhether to keep local LAN access when using an exit node
remote-dns-resolveDefaults to true. Destination domains are resolved using Tailscale MagicDNS / tailnet DNS
auto-routeDefaults to true. Automatically injects a dynamic RULE-SET before MATCH
route-rule-setDefaults to $<proxy-name>. Dynamic route rule set name
dialer-proxyUpstream outbound used for Tailscale control-plane and DERP/peer connections

By default, route-rule-set directly uses the proxy name with a $ prefix. If the proxy name or explicit rule set name contains a comma, the automatically injected RULE-SET is wrapped in double quotes and escaped according to the common rule syntax.

Tailscale MagicDNS#

Tailscale outbound defaults to remote-dns-resolve: true. When a rule sends a domain destination to this outbound, Link1 first queries MagicDNS / tailnet DNS through the embedded Tailscale runtime DNS manager, then uses the resolved tailnet IP to establish the connection. If Tailscale DNS does not return an address, an error is returned and it will not silently fall back to local DNS. To reuse local or global DNS, explicitly set remote-dns-resolve: false.

Global DNS can also directly reference a Tailscale outbound:

dns:
  nameserver-policy:
    '+.tailnet.ts.net':
      - ts://tailnet

tailscale://tailnet and ts://tailnet are equivalent. Both mean “use the MagicDNS / tailnet DNS provided by the Tailscale outbound named tailnet”.

dialer-proxy applies to Tailscale’s own system dialing path: control-plane, DERP/relay, and peer direct connections all prefer the specified outbound. The current implementation uses a trimmed Tailscale fork in Link1 and connects the underlying WireGuard path to Link1’s internal WireGuard. The goal is to keep only the subset required for outbound use while preserving room for future WireGuard variant extensions.

openvpn#

OpenVPN outbound is not a regular “remote proxy port”; it is a full VPN client. Link1 first establishes a control channel with the OpenVPN server, completes TLS/certificate/username-password authentication, then creates a userspace tunnel network and places connections selected by rules into this tunnel. When dialer-proxy is configured, the underlying TCP/UDP channel used by OpenVPN to connect to the remote first goes through the specified outbound. UDP remotes require the upstream outbound to support UDP.

Its data flow can be understood as:

App connection
  -> Link1 rules select ovpn-node
  -> OpenVPN userspace netstack
  -> OpenVPN control/data channel
  -> VPN server
  -> Enterprise intranet or public target

Minimal example:

proxies:
  - name: ovpn-node
    type: openvpn
    server: vpn.example.com
    port: 1194
    network: udp
    username: alice
    password: secret
    ca: ./certs/ca.crt
    certificate: ./certs/client.crt
    private-key: ./certs/client.key
    private-key-passphrase: optional-passphrase
    route-rule-set: ovpn-node-routes

Multiple remote example:

proxies:
  - name: ovpn-node
    type: openvpn
    ca: ./certs/ca.crt
    username: alice
    password: secret
    remotes:
      - server: vpn1.example.com
        port: 1194
        protocol: udp
        sni: vpn.example.com
      - server: vpn2.example.com
        port: 443
        protocol: tcp
        servername: vpn.example.com

OpenVPN Field Reference#

FieldRequired/DefaultActual effect
server / port / networkRequired when there is no remotes; network defaults to UDPDeclares the default remote; network only allows UDP/TCP and compatible spellings.
remotes[]OptionalMultiple OpenVPN remote candidates. Link1 selects/switches remotes based on status.
remotes[].server / port / protocolRequired inside a remoteAddress, port, and transport protocol of a single remote.
remotes[].sni / servernameOptionalTLS name of a single remote. sni takes priority.
username / passwordDepends on the serverUsername/password authentication.
caUsually requiredVerifies the OpenVPN server certificate. If ca is not set, skip-cert-verify: true must be explicitly set.
certificate / private-keyConfigured as a pairClient certificate authentication. Setting only one of them is rejected.
private-key-passphraseOptionalPassword for the encrypted private key.
authOptionalOpenVPN auth digest.
cipher / data-ciphersOptionalData channel ciphers. Supports AES-128-GCM, AES-192-GCM, AES-256-GCM, CHACHA20-POLY1305, and legacy AES-128-CBC/AES-256-CBC; AES-CBC is treated as AES-128-CBC, and data-ciphers is a candidate list.
tls-auth / tls-crypt / tls-crypt-v2Mutually exclusiveOpenVPN TLS control channel protection. Only one of the three can be selected.
key-directionUsed with tls-authCan only be 0, 1, or bidirectional, and must be used with tls-auth.
ip / ipv6OptionalManually specifies the local tunnel address. It can be provided by the server when the server pushes ifconfig.
dnsOptionalManually specifies VPN DNS server IPs. If the server pushes DNS, it is overridden by the pushed result.
remote-dns-resolveDefaults to trueDestination domains are resolved by the OpenVPN runtime using pushed/configured VPN DNS. When explicitly set to false, local/global DNS is used instead.
mtuOptionalTunnel MTU. It may also be updated when the server pushes tun-mtu.
request-timeoutDefaults to 30sOpenVPN handshake timeout, in milliseconds.
ping-interval / ping-timeoutDefaults to 10s / 60sKeepalive and disconnection detection. Server push can also override them.
reneg-secDefaults to 3600sTLS renegotiation interval.
route-rule-setDefaults to $<proxy-name>Exposes a dynamic rule set for matching route prefixes pushed by the VPN server.
auto-routeDefaults to trueAutomatically inserts RULE-SET,<route-rule-set>,<proxy-name> before MATCH.
interface-name / routing-markOptionalUnderlying outbound control for the segment where OpenVPN connects to the server.

By default, route-rule-set directly uses the proxy name with a $ prefix. If the proxy name or explicit rule set name contains a comma, the automatically injected RULE-SET is wrapped in double quotes and escaped according to the common rule syntax.

Common unsupported fields:

How OpenVPN DNS Works#

OpenVPN DNS has three source layers, in descending priority:

  1. DNS pushed by the server: the OpenVPN server may send dhcp-option DNS 10.8.0.1 in PUSH_REPLY. Link1 records it in the OpenVPN runtime snapshot.
  1. The dns field in the node: if the server does not push DNS, you can manually set dns: [10.8.0.1].
  1. Global Link1 DNS: when remote-dns-resolve: false, or when a DNS query is not part of an outbound dialing target, normal DNS still follows global configuration such as dns.nameserver and nameserver-policy.

OpenVPN defaults to remote-dns-resolve: true. Domain destinations selected by rules and entering the OpenVPN outbound are resolved by the OpenVPN runtime using pushed/configured DNS. If no VPN DNS is available, an error is returned instead of falling back to local DNS.

If you need certain enterprise domains in the global DNS policy to explicitly call the internal OpenVPN DNS, write openvpn://<node-name> in dns.nameserver-policy:

dns:
  enable: true
  nameserver:
    - https://223.5.5.5/dns-query
  nameserver-policy:
    '+.corp.example.com':
      - openvpn://ovpn-node
    '+.internal.example.com':
      - openvpn://ovpn-node

Meaning:

openvpn://ovpn-node and remote-dns-resolve use the same type of remote DNS capability, but have different entry points: the former is a nameserver in the global DNS policy, while the latter is the resolution policy used when the OpenVPN outbound dials a target domain.

How OpenVPN Routing Works#

The OpenVPN server may push routes, such as route 10.0.0.0 255.0.0.0 or IPv6 routes. Link1 records these prefixes in the runtime snapshot of that node.

route-rule-set exposes these prefixes as a dynamic rule set:

proxies:
  - name: ovpn-node
    type: openvpn
    server: vpn.example.com
    port: 1194
    ca: ./certs/ca.crt
    route-rule-set: corp-vpn-routes
    auto-route: true

rules:
  - DOMAIN-SUFFIX,corp.example.com,ovpn-node
  - MATCH,PROXY

When auto-route: true, Link1 automatically inserts a rule like the following before MATCH:

rules:
  - RULE-SET,corp-vpn-routes,ovpn-node
  - MATCH,PROXY

Note: OpenVPN dynamic route rule-sets mainly match IP prefixes pushed by the server. For enterprise domains, it is still recommended to point them to openvpn://ovpn-node through dns.nameserver-policy. After they resolve to enterprise intranet IPs, the routing rules can then match them.

Common OpenVPN Issues#

SymptomCommon CauseAction
Config compilation reports ca is emptyNo CA is provided and certificate verification is not skippedConfigure ca, or explicitly set skip-cert-verify: true during testing
Reports certificate and private-key must be configured togetherOnly one of the client certificate and private key is configuredConfigure both, or configure neither
Enterprise domain resolution failsNo pushed/configured VPN DNS, or remote resolution is explicitly disabledConfigure dns, check the server push, or confirm whether remote-dns-resolve: false is needed
Intranet IPs do not use the VPNThe server did not push routes, or auto-route=falseCheck OpenVPN snapshot routes and route-rule-set
UDP remote is unreachableUDP is blocked by the networkUse a TCP remote or check the firewall

WARP provider#

WARP is Cloudflare's dynamic egress capability. Link1 does not design it as proxies[].type=warp, but as proxy-providers.type=warp. The reason is that WARP is not a fixed leaf node, but a "node source" that generates nodes.

Why it must be a provider:

  1. One WARP configuration may generate multiple egresses: the same WARP state can materialize both wireguard and masque node types.
  1. auto mode requires persistent state: accounts, keys, endpoints, reserved bytes, MASQUE parameters, and other data need to be managed and reused.
  1. It naturally fits policy group selection: nodes generated by the provider can enter policy groups such as select, url-test, and fallback, where users or health checks choose them.
  1. It is not a subscription download: the WARP provider does not use subscription fields such as url, path, format, and proxy; it builds local nodes from WARP state.
  1. Avoid configuration ambiguity: if proxies[].type=warp were allowed, users would assume it behaves like a normal protocol with only one fixed server/port. In reality, WARP must first determine the transport and state source.

Most common example:

proxy-providers:
  warp:
    type: warp
    mode: auto
    transports:
      - masque
      - wireguard

proxy-groups:
  - name: WARP
    type: select
    use: [warp]
    proxies:
      - DIRECT

rules:
  - MATCH,WARP

Meaning of this configuration:

WARP auto Mode Fields#

FieldDefault/LimitActual Effect
typeMust be warpDeclares this as a WARP provider.
modeDefaults to autoAutomatically loads/generates WARP state.
transportsDefaults to masque + wireguardSpecifies which candidates to materialize; only masque and wireguard are supported.
license-keySupported only in mode=autoUses the specified WARP license. It is rejected in manual mode.
endpoint-host / endpoint-portauto uses the default endpointSpecifies the WARP endpoint.
mtuDefault WARP MTUAffects the generated tunnel MTU.
persistent-keepaliveDefault WARP keepaliveWireGuard NAT keepalive.
dialer-proxyOptionalPassed to the generated WireGuard/MASQUE nodes so they use a fronting egress when connecting to the WARP endpoint.

Discovery fields that are no longer supported: probe-timeout, count, wg-candidates, masque-candidates. These fields belong to the old discovery design and will be rejected if written in the configuration.

WARP manual Mode Fields#

manual mode is suitable when you already have complete WARP parameters and do not want Link1 to automatically generate state.

proxy-providers:
  warp-manual:
    type: warp
    mode: manual
    transports: [wireguard, masque]
    wireguard:
      private-key: xxxxx
      public-key: xxxxx
      ip: 172.16.0.2
      ipv6: 2606:4700::1
      reserved:
        bytes: [0, 0, 0]
      server: engage.cloudflareclient.com
      port: 2408
      allowed-ips:
        - 0.0.0.0/0
        - ::/0
      mtu: 1280
      persistent-keepalive: 25
    masque:
      private-key: xxxxx
      public-key: xxxxx
      ip: 172.16.0.2
      ipv6: 2606:4700::1
      server: masque.cloudflareclient.com
      port: 443
      uri: https://masque.cloudflareclient.com/
      sni: masque.cloudflareclient.com
      dns:
        - 1.1.1.1
      remote-dns-resolve: true
      mtu: 1280
      congestion-controller: bbr
Sub-blockFieldActual Effect
wireguardprivate-key, public-keyLocal private key and peer public key for WARP/WireGuard.
wireguardip, ipv6Local tunnel address; at least one is required.
wireguardreserved.bytesWARP reserved bytes, required for some accounts.
wireguardserver, portWARP WireGuard endpoint.
wireguardallowed-ipsAllowed prefixes entering the tunnel. If omitted, it defaults to all IPv4 globally, and also includes ::/0 when IPv6 is present.
wireguardmtu, persistent-keepaliveMTU and NAT keepalive.
masqueprivate-key, public-key, ip, ipv6MASQUE account and tunnel addresses.
masqueserver, port, uri, sniMASQUE HTTP/3 endpoint and TLS name.
masquedns, remote-dns-resolveMASQUE internal DNS and remote resolution behavior.
masqueskip-cert-verifySkips certificate verification for the MASQUE endpoint. Not recommended for production.
masquemtu, congestion-controller, cwnd, up, downQUIC/tunnel performance parameters.

manual mode rules:

What Nodes the provider Generates#

The WARP provider eventually generates normal Link1 outbound nodes:

WARP transportGenerated leaf typeUser-visible Behavior
wireguardwireguardForwards like a normal WireGuard tunnel.
masquemasqueForwards like a MASQUE/HTTP3 tunnel, with UDP enabled by default.

Therefore, subsequent policy groups, rules, and health checks operate on these generated nodes, not directly on warp. This is also the fundamental reason why warp must be placed under a provider.

Common WARP Issues#

SymptomCommon CauseAction
proxies[].type=warp is rejectedWARP cannot be used as a leafChange it to proxy-providers.<name>.type: warp
The provider does not generate nodesauto state is empty, or the specified transport has no available stateCheck the App Provider page and logs to confirm whether WARP state has been generated
url/path/format is rejectedThe WARP provider is not a subscription providerRemove these fields
manual mode reports missing wireguard/masqueThe corresponding transport is enabled in transportsComplete the corresponding sub-block or remove it from transports
MASQUE is unreachable, but WireGuard worksLocal or network restrictions on HTTP/3/QUICSwitch to WireGuard in the policy group, or check UDP/QUIC
WireGuard is unreachable, but MASQUE worksWireGuard endpoint/UDP is blockedUse the MASQUE transport or check the endpoint/UDP

Enterprise VPN Protocols#

Enterprise VPN protocols depend on the target server version, login policy, CAPTCHA, device binding, and enterprise security policy. They are more like “using an enterprise VPN as a Link1 outbound” than ordinary subscription nodes.

Enterprise VPNs usually return two types of dynamic information:

Therefore, these protocols are often used together with dns.nameserver-policy, route-rule-set, and policy groups, instead of blindly sending all traffic to the enterprise VPN.

atrust#

proxies:
  - name: atrust-node
    type: atrust
    server: vpn.example.com
    username: alice
    password: secret
    auth-type: auth/psw
    remote-dns-resolve: true
    route-rule-set: corp-routes

Key fields:

FieldEffect
serverATrust service address
username / passwordLogin credentials
auth-typeauth/psw, auth/cas, auth/smsCheckCode
phone / code / cas-ticketParameters for the corresponding authentication method
remote-dns-resolveDefaults to true; target domains are resolved remotely using the VPN DNS
session-persistSession persistence
route-rule-setDefaults to $<proxy-name>; enterprise route rule set name
request-timeoutLogin/request timeout

Limitations: does not support fields for ordinary proxies such as TLS/QUIC/network. dialer-proxy applies to both the login control plane and the underlying enterprise tunnel connection.

feilian#

proxies:
  - name: feilian-node
    type: feilian
    server: vpn.example.com
    company-name: example
    username: alice
    password: secret
    vpn-select-strategy: default
    remote-dns-resolve: true

Key fields:

FieldEffect
company-name / serverAt least one is used to locate the enterprise
username / passwordLogin credentials
vpn-server-nameSpecifies the VPN gateway
vpn-select-strategyGateway selection strategy
remote-dns-resolveDefaults to true; target domains are resolved remotely using the VPN DNS
session-persistSession persistence
dialer-proxyThe Feilian control plane, VPN ping/connect requests, and WireGuard underlay all use the specified front outbound; UDP mode requires the front outbound to support UDP.

easyconnect#

proxies:
  - name: easyconnect-node
    type: easyconnect
    server: vpn.example.com
    port: 443
    username: alice
    password: secret
    remote-dns-resolve: true

Key fields:

FieldEffect
server / portEasyConnect service address
username / passwordLogin credentials
remote-dns-resolveDefaults to true; target domains are resolved remotely using the VPN DNS
auto-setup-routesAutomatically sets VPN routes
route-rule-setDefaults to $<proxy-name>; enterprise route rule set name
request-timeoutRequest timeout

Automatic injection of dynamic enterprise VPN route-rule-set follows the general rule syntax as well. If the proxy name or rule set name contains a comma, the corresponding field is automatically quoted.

Limitations: does not support fields for ordinary proxies such as TLS, QUIC, and network. dialer-proxy applies to both the login control plane and tunnel data connection.

Inbound Protocol Listeners#

Although this chapter mainly covers outbounds, Link1 can also act as a server for some protocols.

VLESS listener#

listeners:
  - name: vless-in
    type: vless
    listen: 0.0.0.0
    port: 443
    certificate: ./certs/server.crt
    private-key: ./certs/server.key
    users:
      - username: alice
        uuid: 00000000-0000-0000-0000-000000000000
        flow: xtls-rprx-vision
    ws-path: /ws
    proxy: PROXY

Key fields: users, uuid, certificate, private-key, ws-path, grpc-service-name, decryption, reality-config, proxy.

Hysteria2 listener#

listeners:
  - name: hy2-in
    type: hysteria2
    listen: 0.0.0.0
    port: 443
    certificate: ./certs/server.crt
    private-key: ./certs/server.key
    users:
      alice: password1
      bob: password2
    up: 100 Mbps
    down: 500 Mbps
    obfs: salamander
    obfs-password: secret
    alpn: [h3]
    masquerade: https://www.example.com
    proxy: PROXY

Key fields: users, certificate, private-key, up, down, obfs, obfs-password, max-idle-time, alpn, ignore-client-bandwidth, masquerade, proxy.

Protocol Selection Recommendations#

ScenarioRecommendation
First-time validationdirect or socks5
General remote proxyhysteria2, tuic, vless, trojan, ss
UDP/gaming/mobile networksPrefer hysteria2, tuic, wireguard, masque
Corporate intranet accessopenvpn, tailscale, atrust, feilian, easyconnect
Router transparent proxyA protocol that supports UDP + DNS/Fake-IP/TUN
Need a WARP outboundproxy-providers.type=warp

Compatibility Boundaries#