Proxy Protocols
Proxy Types

Protocol Types

Stash supports multiple types of proxy protocols, capable of handling TCP/UDP protocols.

Each proxy must include the following parameters:

  • name: The name of the proxy, which must be unique for each proxy.
  • type: The type of proxy.

Most proxies also require the following parameters:

  • server: The server address, which can be a domain name or an IP address.
  • port: The port.

The proxy may support the following parameters:

  • tls: Boolean value to indicate whether to forward based on TLS.
  • skip-cert-verify: Boolean value to specify whether to skip certificate verification during the TLS handshake.
  • server-cert-fingerprint: String value used to verify the SHA256 fingerprint of the server certificate in Hex format during the TLS handshake.
  • sni: String, specifies the Server Name Indication (opens in a new tab) sent during the TLS handshake. If sni is empty, it defaults to the server field.
  • alpn: String array specifying the Application-Layer Protocol Negotiation (ALPN) (opens in a new tab) sent during the TLS handshake.
  • interface-name: Specifies the network interface to bind exit to; only supported on macOS.

In addition, for latency testing of individual proxies, the following parameters can be modified:

  • benchmark-url: The URL used for latency testing, default is http://www.apple.com/.
  • benchmark-timeout: The timeout for latency testing in seconds, default is 5 seconds.
  • benchmark-disabled: Set to true to completely disable latency testing.

You can find more information on testing proxy latency here.


For protocols based on QUIC, support is available for periodically changing ports to counter ISP throttling on single ports, a method also known as port hopping.

  • ports: String supporting multiple ports or port ranges, separated by commas, e.g., 443,8443,5000-6000.
  • hop-interval: Integer specifying the port hopping interval in seconds, default is 30 seconds.

When handling UDP, to maximize compatibility with various protocol behaviors, proxies are only forwarded in the form of IP addresses, unlike TCP which hands over domain resolution to the proxy. Therefore, before initiating a UDP forwarding request, Stash will attempt DNS queries through the proxy to obtain a correct, CDN-optimized DNS resolution, then use that address to forward UDP packets.

Stash uses 1.0.0.1 for DNS queries by default, which can be modified using the following parameter:

  • udp-nameserver: Array used to specify DNS server addresses, only supports UDP protocol.

Example:

name: proxy
type: ss
udp-nameserver: ['8.8.4.4', '8.8.8.8:53']
# ...

Different types of proxies may require additional parameters, which can be found below.

Shadowsocks / Shadowsocks2022

name: ss1
type: ss
server: server
port: 443
cipher: chacha20-ietf-poly1305
password: 'password'
udp: true
plugin: null
plugin-opts:
  mode:
  host:

Supported encryption methods (cipher):

  • aes-128-gcm
  • aes-192-gcm
  • aes-256-gcm
  • aes-128-cfb
  • aes-192-cfb
  • aes-256-cfb
  • aes-128-ctr
  • aes-192-ctr
  • aes-256-ctr
  • rc4-md5
  • chacha20
  • chacha20-ietf
  • xchacha20
  • chacha20-ietf-poly1305
  • xchacha20-ietf-poly1305
  • 2022-blake3-aes-128-gcm
  • 2022-blake3-aes-256-gcm

Shadowsocks Plugins

Supported plugins (plugin):

obfs: Uses simple-obfs (opens in a new tab) to obfuscate TCP traffic.

plugin: obfs
plugin-opts:
  mode: tls # Obfuscation mode, can choose between http or tls
  host: bing.com # Obfuscation domain, must match the server configuration

v2ray-plugin: Uses v2ray-plugin (opens in a new tab) to carry traffic over WebSocket.

plugin: v2ray-plugin
plugin-opts:
  mode: websocket # Currently QUIC is not supported
  tls: true # wss
  skip-cert-verify: true # Don't verify certificate
  host: bing.com
  path: '/'
  headers: # Custom request headers
    key: value

shadow-tls: Uses shadow-tls (opens in a new tab) to perform real TLS handshake and can utilize certificates from major companies or institutions without needing to issue one yourself.

⚠️

Currently only supports Shadow TLS v2 (opens in a new tab) and v3 (opens in a new tab) versions.

plugin: shadow-tls
plugin-opts:
  password: singalongsong
  host: weather-data.apple.com
  skip-cert-verify: false # Don't verify certificate
  version: 3 # Only supports version 2 and 3

ShadowsocksR

name: ssr
type: ssr
server: server
port: 443
cipher: chacha20-ietf
password: 'password'
obfs: ''
protocol: ''
obfs-param: ''
protocol-param: ''

Supported encryption methods (cipher) are the same as Shadowsocks.

Supported obfuscation methods (obfs):

  • plain
  • http_simple
  • http_post
  • random_head
  • tls1.2_ticket_auth
  • tls1.2_ticket_fastauth

Supported protocols (protocol):

  • origin
  • auth_sha1_v4
  • auth_aes128_md5
  • auth_aes128_sha1
  • auth_chain_a auth_chain_b

SOCKS5

name: socks
type: socks5
server: server
port: 443
# username: username
# password: password
# tls: true
# skip-cert-verify: true
# udp: true

HTTP

name: http
type: http
server: server
port: 443
headers:
  key: value
tls: true # https
skip-cert-verify: true
# username: username
# password: password

VMess

name: vmess
type: vmess
server: server
port: 443
uuid: d0529668-8835-11ec-a8a3-0242ac120002
cipher: auto
alterId: 64
network:

Supported encryption methods (cipher):

  • auto
  • aes-128-gcm
  • chacha20-poly1305
  • none

Supported transport networks (network):

  • ws
  • h2
  • http
  • grpc
network: ws
ws-opts:
  path: /path
  headers:
    Host: v2ray.com
  max-early-data: 2048
  early-data-header-name: Sec-WebSocket-Protocol
network: h2
tls: true
h2-opts:
  host:
    - http.example.com
    - http-alt.example.com
  path: /

Snell

name: snell
type: snell
server: server
port: 443
psk: yourpsk
udp: true # Requires v3 and above server
version: 3
# obfs-opts:
# mode: http # or tls
# host: bing.com

Snell UDP requires support from v3 or above server versions.

Supported obfuscation modes (obfs-opts.mode):

  • http
  • tls

Trojan

name: trojan
type: trojan
server: server
port: 443
password: yourpassword
# udp: true
# sni: example.com # Server Name Indication, uses server value if empty
# alpn:
#   - h2
#   - http/1.1
# skip-cert-verify: true

Supported transport networks (network):

  • ws
  • grpc

Hysteria

Hysteria is a feature-rich network tool optimized for harsh network environments (dual acceleration), such as satellite networks, crowded public Wi-Fi, connecting to foreign servers in China, etc. Based on a modified QUIC protocol.

Please refer to here (opens in a new tab) for Hysteria server deployment.

name: 'hysteria'
type: hysteria
server: server
port: 443
up-speed: 100 # Upload bandwidth in Mbps
down-speed: 100 # Download bandwidth in Mbps
auth-str: your-password
# auth: aHR0cHM6Ly9oeXN0ZXJpYS5uZXR3b3JrL2RvY3MvYWR2YW5jZWQtdXNhZ2Uv # bytes encoded in base64
protocol: '' # udp / wechat-video
obfs: '' # obfs password
sni: example.com # Server Name Indication, uses server value if empty
alpn:
  - hysteria
skip-cert-verify: true

Upload and download bandwidth should be specified in Mbps. Please fill in as accurately as possible, as exceeding the actual bandwidth may have negative effects.

External link: base64 encoding tool (opens in a new tab).

Hysteria2

⚠️

Please note that Hysteria 2 is completely incompatible with Hysteria 1.x. Refer to the official guidance (opens in a new tab) for differences between the two versions.

Please refer to here (opens in a new tab) for Hysteria2 server deployment.

name: 'hysteria2'
type: hysteria2
server: server
port: 443
auth: your-password
fast-open: true
sni: example.com # Server Name Indication, uses server value if empty
skip-cert-verify: true
up-speed: 100 # Upload bandwidth (optional, in Mbps)
down-speed: 100 # Download bandwidth (optional, in Mbps)

VLESS

XTLS protocol detaches from redundant encryption in TLS environments, providing superior forwarding performance.

name: vless
type: vless
server: server
port: 443
uuid: d0529668-8835-11ec-a8a3-0242ac120002
# flow: xtls-rprx-direct
# skip-cert-verify: true
# network: h2
# tls: true
# client-fingerprint: chrome
# ws-opts:
#   path: /path
#   headers:
#     Host: v2ray.com
# grpc-opts:
#   grpc-service-name: "example"
# h2-opts:
#   host:
#     - http.example.com
#     - http-alt.example.com
#   path: /
# reality-opts:
#   public-key:
#   short-id:

Supported XTLS modes (flow):

  • xtls-rprx-origin
  • xtls-rprx-direct
  • xtls-rprx-splice
  • xtls-rprx-vision

TUIC

TUIC is a lightweight QUIC-based proxy protocol written in Rust and currently supports v4 and v5 versions. You can find more information here (opens in a new tab).

name: tuic-v5
type: tuic
server: server
port: 443
version: 5
uuid: d0529668-8835-11ec-a8a3-0242ac120002 # for v5
password: your_password # for v5
skip-cert-verify: true
sni: ''
alpn:
  - h3
name: tuic-v4
type: tuic
server: server
port: 443
version: 4
token: 'your_token' # for v4
skip-cert-verify: true
sni: ''
alpn:
  - h3
💡

Note that Stash client does not support empty ALPN, default ALPN is h3. Add --alpn h3 parameter on TUIC server.

Choose the appropriate congestion control algorithm on the server with the --congestion-controller parameter to fully utilize bandwidth.

Juicity

Juicity (opens in a new tab) is a QUIC-based proxy protocol inspired by TUIC.

name: juicity
type: juicity
server: server
port: 443
uuid: d0529668-8835-11ec-a8a3-0242ac120002
password: your_password
skip-cert-verify: true
sni: ''
alpn:
  - h3

WireGuard

WireGuard (opens in a new tab) is an efficient Layer 3 VPN, Stash supports using it as a Layer 4 proxy and supports forwarding WireGuard packets through other protocols.

name: wireguard
type: wireguard
server: server # domain is supported
port: 51820
ip: 10.8.4.8
# ipv6: fe80::e6bf:faff:fea0:9fae # optional
private-key: 0G6TTWwvgv8Gy5013/jv2GttkCLYYaNTArHV0NdNkGI= # client private key
public-key: 0ag+C+rINHBnvLJLUyJeYkMWvIAkBjQPPObicuBUn1U= # peer public key
# preshared-key: # optional
dns: [1.0.0.1, 223.6.6.6] # optional
# mtu: 1420 # optional
# reserved: [0, 0, 0] # optional
# keepalive: 45 # optional
💡

WireGuard is not designed as a high-throughput proxy protocol. Stash needs to complete Layer 3 to Layer 4 conversion in user space, which results in more performance loss compared to common proxy protocols. On mobile devices, WireGuard usually has lower throughput compared to Layer 4 proxy protocols.

Tailscale

Tailscale nodes can be added directly to Stash as a type: tailscale proxy.

name: tailnet-main
type: tailscale
auth-key: tskey-auth-xxxxxxxxxxxxxxxx
hostname: tailnet-main
control-url: https://controlplane.tailscale.com
ephemeral: false
exit-node: exit-gateway.tailnet-main.ts.net

Supported parameters:

  • auth-key: The Tailscale pre-authentication key. You can generate it from the Tailscale admin console. See the official documentation: Auth keys (opens in a new tab). If you plan to use the same auth-key on multiple devices, enable Reusable when creating the key instead of One-off, otherwise other devices will not be able to join the tailnet.
  • hostname: The machine name of the node. It may contain only lowercase letters, digits, and -. If left empty, Stash uses the Stash Device ID as the hostname.
  • control-url: Custom control plane URL. In most cases, you can leave this unset and use the default Tailscale control plane.
  • ephemeral: Whether to use an ephemeral node. According to the official Tailscale documentation, Ephemeral nodes (opens in a new tab) are automatically removed from the tailnet after being offline for some time, and they receive a new IP address when created again. When enabling this option, use an ephemeral auth key.
  • exit-node: Optional. Prefer a specific exit node. Stash accepts the exit node Stable ID, MagicDNS/FQDN, hostname, or Tailscale IP. If the specified node is currently unavailable, Stash falls back to the first available exit node in the current tailnet. Leaving it empty or omitting it uses the same automatic selection behavior.

OAuth support is currently under development and will allow connecting without relying on an auth-key in the future.

Like other proxy protocols, tailscale is just another selectable proxy node. Traffic only goes through it when you route traffic to this node through rules, proxy groups, or other routing methods.

You can route traffic to resources inside your tailnet like this:

proxies:
  - name: tailnet-main
    type: tailscale
    auth-key: tskey-auth-xxxxxxxxxxxxxxxx
 
rules:
  - DOMAIN,app.tailnet-main.ts.net,tailnet-main
  - IP-CIDR,100.64.0.0/10,tailnet-main,no-resolve

Notes:

  • If the auth-key is invalid, the first connection will fail.
  • Due to Tailscale limitations, auth-key usage is affected by Key Expiry. Please enable Expiry disabled for the corresponding Stash device on the Machines page in the Tailscale admin console to prevent the node from expiring later.
  • If exit-node is omitted, Stash automatically selects the first available exit node in the current tailnet. If no exit node is available, no exit node is selected.
  • If exit-node cannot be uniquely resolved or the target is currently unavailable, Stash falls back to automatic selection instead of failing permanently.
  • If the tailnet target is not authorized, waiting for machine approval, or the control plane requires login, Stash returns a clear error.

SSH

Forward TCP traffic through the Secure Shell Protocol (SSH) (opens in a new tab), supporting both password and key authentication.

💡

Since SSH does not support forwarding UDP protocol, Stash cannot forward UDP traffic over SSH protocol.

name: ssh
type: ssh
server: server # domain is supported
port: 22
user: root
password: password
private-key: |
  -----BEGIN RSA PRIVATE KEY-----
  MIIEpAIBAAKCAQEA0G6TTWwvgv8Gy5013/jv2GttkCLYYaNTArHV0NdNkGI=
  ...
  -----END RSA PRIVATE KEY-----
private-key-passphrase: your-passphrase # optional

DIRECT with Specified Interface

By creating a proxy of type direct, and specifying interface-name, certain traffic can be forced to travel through a specified network interface, useful in situations where VPN and Stash cannot be used simultaneously.

For example, the local OpenVPN uses utun3, and traffic with 10.4.8.0/24 should enter utun3 instead of the default macOS network interface.

name: my-corp-vpn
type: direct
interface-name: utun3
rules:
  - IP-CIDR,10.4.8.0/24,my-corp-vpn
💡

Please modify utun3 according to actual conditions.

You can use netstat -rn | grep utun3 to query the static routing table of utun3.