Profile manual
Networks and the tunnel
On this page
What changes with the network the device is on, what Pipe's iOS VPN tunnel takes in, and on a Mac, the network it serves.
[General]
ipv6-vif = auto
tun-excluded-routes = 192.168.0.0/16
tun-included-routes = 10.7.0.1/32
[SSID Setting]
TYPE:CELLULAR cellular-fallback=off
SSID:Home dns-server=192.168.1.1, encrypted-dns-server=off
SSID:Hotel* suspend=true
[IP Rewrite]
10.7.0.1 = reflect
[Port Forwarding]
127.0.0.1:6841 db.internal.example:3306 policy=Office
Subnet expressions#
Subnet groups, SUBNET rules and [SSID Setting] lines name networks
with subnet expressions.
| Expression | Holds |
|---|---|
SSID:Home, SSID:Office* |
On Wi-Fi whose name matches, in its case. * is any run of characters and ? one character. |
BSSID:aa:bb:cc:dd:ee:ff |
On Wi-Fi with that access point, in any case. * and ? work too. |
ROUTER:192.168.1.1 |
On a network whose router — the default gateway — is that address. |
TYPE:WIFI, TYPE:WIRED, TYPE:CELLULAR |
On that kind of network. |
MCCMNC:001-01 |
On cellular, not on Wi-Fi, with that carrier's MCC and MNC. Only the digits count: 00101 is the same. |
RADIO:LTE |
On cellular, with that radio, in any case: LTE, NRNSA, NR, WCDMA, … |
CARRIER:Example Mobile, CARRIER:001-01 |
On cellular, with that carrier, by its name (in any case) or its MCC and MNC. |
- A prefix is read in any case:
ssid:isSSID:. - An expression has its prefix. One without (
Home,192.168.1.1) is not one: aSUBNETrule with it is an error, and a subnet group's condition or an[SSID Setting]line with it is warned about, and left out. A Surge profile's are given theirs when it is imported. - An expression with a prefix and nothing after it is not one, and is warned about where it stands.
RADIO:andCARRIER:are whatCELLULAR-RADIOandCELLULAR-CARRIERrules come to.
What a network is — its kind, its router, its Wi-Fi name and BSSID where iOS gives them, its radio and carrier on cellular — is what the app last said of it. Expressions are tried against it connection by connection, so a change of network is felt by the next connection.
On a Mac, a network reached over Ethernet may have Wi-Fi associated
beside it. SSID and BSSID expressions match the primary network
alone, unless subnet-exp-wifi-always-match = true
says they keep matching while Wi-Fi is not the primary interface.
TYPE:WIFI is about the primary network either way.
[SSID Setting]#
Each line names networks with a subnet expression, then says what
changes on them: <networks> key=value, ….
[SSID Setting]
TYPE:CELLULAR suspend=true
SSID:Home dns-server=192.168.1.1, 192.168.1.2, encrypted-dns-server=off
SSID:Office* encrypted-dns-server=https://dns.corp.example/dns-query
SSID:My Phone's Hotspot cellular-fallback=off, tfo-behaviour=force-disabled
- The expression ends where the first
key=begins: a Wi-Fi name may hold spaces. - For each kind of setting — suspending, DNS servers, cellular and Fast Open — the first line that gives it and whose networks hold the device's network applies.
- Settings are separated by commas. A list of servers runs on to the next
key=.
| Key | Values | What it does |
|---|---|---|
suspend |
true, false |
Traffic goes directly on these networks, whatever the mode and rules. |
dns-server |
servers, as dns-server takes them |
Plain servers for these networks. |
encrypted-dns-server |
servers, as encrypted-dns-server takes them, or off |
Encrypted servers for these networks; off: none. |
cellular-fallback |
default, off, wifi-assist, hybrid |
What these networks do with cellular. off: neither Wi-Fi Assist nor Hybrid. wifi-assist, hybrid: that one. default: as the profile says (Leaving the device). |
tfo-behaviour |
auto, force-enabled, force-disabled |
force-disabled turns TCP Fast Open off on these networks; force-enabled uses it for every policy that asks for it. The system's own detection of networks that break Fast Open stays the system's. |
cellular-mode |
true, false |
On a computer, these networks are metered (below). |
Which DNS servers a network gets:
- its own encrypted servers, when the line gives some;
- or else the profile's encrypted servers, unless the line says
encrypted-dns-server=off; - with no encrypted servers, its own plain servers, or else the profile's.
So plain servers alone do not turn the profile's encrypted ones off:
SSID:Home dns-server=192.168.1.1, encrypted-dns-server=off does.
A line without a key=, or whose expression Pipe cannot read, is
warned about, and left out. cellular-mode on iOS is read past without
a word: it belongs to a computer. Any other key is noted, and read past. A
value Pipe cannot read is warned about, and that setting is left out.
Metered Network Mode#
A phone's hotspot costs by the byte, and a computer has applications that take all they are given. On a Mac or a Linux host, a network can be said to be metered:
[SSID Setting]
SSID:PhoneHotspot cellular-mode=true
- There, only the applications on the list you keep in the app reach the internet. Connections from anything else are refused, those whose process cannot be told included.
- Names on the list match as
PROCESS-NAMEdoes: an executable's name, or its path when written as one, in any case. - The mode decides before anything else does: what it lets through goes on as the claims, the mode and the rules say. The local network, and external programs' own connections, are not held back.
- Pipe's own requests, for rule lists and the like, are not held back.
- The list lives in the app: it is given to the engine with
POST /metered, as{"allowed": ["Safari", "/usr/bin/curl"]}. So is the switch by hand:{"manual": "on"}or"off", whatever the network, and"auto"to go by the network again.GET /meteredsays where it stands.
The tunnel#
On iOS, Pipe takes traffic in through a VPN tunnel. These
[General] keys say what it takes in. The
tunnel's own addresses are in 198.18.0.0/15: its address, its DNS
server, and the fake IPs names are answered with.
ipv6-vif#
Whether the tunnel carries IPv6.
| Value | What it does |
|---|---|
disabled, the default |
The tunnel carries IPv4 alone. Names are answered with IPv4 addresses, so only an app that connects to an IPv6 address itself goes past the tunnel. |
auto |
It carries IPv6 while the network the phone is on has IPv6: looked at when the tunnel starts, and again whenever the network changes. |
always |
It always carries IPv6. Noted: it can break apps on a network without IPv6. |
Any other value is warned about, and disabled is used.
On a Mac, a tunnel that carries IPv6 also answers names with
fake IPv6 addresses, and takes DNS at fd00:6152::2,
which is what a network of IPv6 alone needs. A
tun-excluded-routes range that holds
fd00:6152::/64 is left out, with a warning.
tun-excluded-routes#
tun-excluded-routes = 192.168.0.0/16, 10.0.0.0/8, 239.255.255.250
Address ranges, IPv4 and IPv6, that go past the tunnel as if it were not there.
- An address alone is a route to that address. Bits past the prefix are
ignored (
10.1.2.3/8is10.0.0.0/8), and a range written twice is one. - An IPv6 range while the tunnel carries no IPv6 changes nothing, and is warned about.
- A range that would take the tunnel's own addresses past it — anything
that overlaps
198.18.0.0/15— is warned about and left out: no name would be reachable. - What cannot be read is warned about, and left out.
tun-included-routes#
tun-included-routes = 100.64.0.0/10, 10.7.0.1/32
Ranges the tunnel claims besides its default route: smaller routes, which win over the network's own routes for the same addresses — to reach through Pipe an address the local network would otherwise take.
0.0.0.0/0is the tunnel's default route, which it has anyway: noted.- A range that is in
tun-excluded-routestoo stays out of the tunnel, with a warning. - A range that holds a whole local-network range —
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16— is noted: claiming one is normally unnecessary, and can cause trouble on the device. An address inside one, such as10.7.0.1/32, is not. - An IPv6 range while the tunnel carries no IPv6 changes nothing, and is warned about.
What iOS lets past the tunnel#
| Key | What it does |
|---|---|
include-all-networks |
iOS sends everything into the tunnel, even what an app sends out of a network of its own choosing. |
include-local-networks |
The local network goes into the tunnel too. |
include-apns |
Apple's push notifications go into the tunnel too. |
include-cellular-services |
The carrier's services — calls over Wi-Fi, MMS, voicemail — go into the tunnel too. |
include-device-communication |
Talking to devices over USB and Wi-Fi — Xcode, a Mac — goes into the tunnel too. |
All are false unless set. The four after the first mean something only
with include-all-networks = true: without it, each is warned about and
changes nothing.
icmp-forwarding#
On unless set to false. A ping sent into the tunnel is sent on by Pipe —
to the real address behind a fake IP's name — and its reply brought back,
so that ping works through the tunnel. With false, pings into the
tunnel are dropped.
udp-priority#
With true, when packets wait to be written back into the tunnel, UDP,
DNS answers and pings go before TCP, so that a game's datagram does not
queue behind a download. Off unless set.
In pipe run, which sets up no tunnel, these settings change nothing,
and are read past without a word.
[IP Rewrite]#
address or range = action
[General]
tun-included-routes = 10.7.0.1/32
[IP Rewrite]
10.7.0.1 = reflect
203.0.113.0/24 = drop
198.51.100.7 = reject
Each line decides what happens to the tunnel's packets for an address or a range — by where they go — before anything else sees them: the TCP and UDP stacks, the rules, the policies. The first line that matches decides.
| Action | What happens |
|---|---|
reflect |
The packet goes back to the device with its source and destination swapped, so that an address in the tunnel stands for the device itself, as developer services on the device need. |
reject |
TCP is answered with a reset, anything else with ICMP's "administratively prohibited": the sender fails at once. |
drop |
Nothing comes back. |
Only packets that enter the tunnel can be rewritten: to rewrite an
address the network would otherwise take, claim it with
tun-included-routes. A line that is not address = action, whose
address is not one, or whose action is none of these, is warned about
and left out.
[Snell Server]#
On a Mac or a Linux host, Pipe serves Snell itself, for your other devices:
[Snell Server]
interface = 0.0.0.0
port = 6160
psk = a-key-of-your-own
version = 4
obfs = off
| Key | Values | Default | What it does |
|---|---|---|---|
port |
a port | required | Where it listens. |
psk |
text | required | The key its clients share. Version 6 takes 12 to 255 bytes. |
interface |
an address | 0.0.0.0 |
The address it listens on. |
version |
1 to 6 |
4 |
The Snell version it speaks. 5 also takes version 4 clients. |
mode |
default, unshaped, unsafe-raw |
default |
Version 6's kind of records, as its clients have it. unsafe-raw seals nothing, and needs a userkey. |
obfs |
off, http, tls |
off |
simple-obfs around each connection, versions 1 to 5. obfs-host is noted, and read past: the server takes off whatever host a client shows. |
userkey |
a list | none | The user keys requests may carry; none, and any user of the psk is taken. |
- Each client connection and UDP tunnel goes through the profile's rules and policies, as any connection does, and shows in the connection table under the inbound's name.
- It serves the local network alone unless
proxy-restricted-to-lan = falsesays otherwise: it is on your network that you share it. - A section that cannot be read is warned about, and no server runs.
- On iOS the section is kept in the file and read past without a word, as a computer's. A module cannot run a server.
[MTProto]#
On a Mac or a Linux host, Pipe serves Telegram's MTProxy, for the Telegram apps on your other devices. A profile has one:
[MTProto]
interface = 0.0.0.0
port = 8443
secret = dd00112233445566778899aabbccddeeff
| Key | Values | Default | What it does |
|---|---|---|---|
port |
a port | required | Where it listens. |
secret |
32 hex digits, after an optional dd |
required | What a client has to know. With dd, clients must use padded framing, which says less on the wire. An ee secret is Fake TLS, which Pipe does not speak: the server is not run, and that is said. |
interface |
an address | 0.0.0.0 |
The address it listens on. |
ipv6 |
true, false |
false |
Data centers are reached over IPv6. |
dc-config-url |
a URL | none | Where the data centers' addresses are kept current from, as below. |
- A client's connection goes to the data center it asks for, through the
profile's rules and policies:
PROTOCOL,MTPROTO,Proxychooses the policy, and it shows in the connection table under the inbound's name. - A client with the wrong secret hears nothing, and is not closed on sooner than one that said too little. An opening seen before is treated as a wrong one: someone recorded it.
- It serves the local network alone unless
proxy-restricted-to-lan = falsesays otherwise.
Pipe knows Telegram's published data center addresses. A dc-config-url
replaces them, read when Pipe starts and daily after: a file of at most
64 KiB and 256 addresses, of proxy_for <dc> <address>:<port>; lines and
default <dc>;, as Telegram's getProxyConfig is written. Pipe connects
to data centers directly, so a line on port 8888, a middle proxy's, is
left out: Telegram's own file comes to nothing that way, and a file that
comes to nothing leaves the addresses as they were.
[Port Forwarding]#
listen-address:port target-host:port [policy=Policy]
[Port Forwarding]
127.0.0.1:6841 db.internal.example:3306 policy=Office
0.0.0.0:8022 10.0.0.5:22
Each line listens on the address and port it gives, and sends every TCP connection made to it on to the target — through the policy it names, or, without one, where the rules send it.
- The listen address is an address and a port:
127.0.0.1:6841serves the device's own apps;0.0.0.0:8022other devices too. - A port listening beyond the device itself serves only devices on the
local network, while
proxy-restricted-to-lanis on (the default), as the shared proxy does. - The target is
host:port: a name or an address. - A policy the profile does not have is an error. A
REJECTone is warned about, and the port is not forwarded. IN-PORTrules see the listen port.- A line Pipe cannot read is warned about, and left out. A parameter
other than
policyis noted, and read past.
Gateway Mode#
On a Mac, Pipe can be the way out of the local network for devices that run no proxy themselves: consoles, TVs, a printer's firmware. They use the Mac as their gateway and their DNS, and what they send goes through the rules like the Mac's own. The Mac needs Enhanced Mode on, and an address of its own on the network that does not change.
[General]
gateway-restricted-to-lan = true
[DHCP]
default-lease-time = 3600
min-lease-time = 300
max-lease-time = 86400
one-lease-per-client = true
ping-check = true
[Rule]
DEVICE-NAME,Apple-TV,Proxy
MAC-ADDRESS,aa:bb:cc:dd:ee:ff,DIRECT
SRC-IP,192.168.1.60,Proxy
FINAL,Proxy
A device is given the Mac as its gateway by hand, in its own network
settings, or by Pipe's DHCP server, which also gives it the tunnel's DNS
address. On a phone there is no gateway: [DHCP] is read past without a
word, and DEVICE-NAME and MAC-ADDRESS rules are left out with a
warning.
- The gateway carries IPv4. A network that also has IPv6 routers keeps giving devices a way past it.
- With
gateway-restricted-to-lan(the default), a flow from outside the local network is dropped as it begins. - Every device's flows are the Mac's to carry: a connection's record says which device it came from, and the device list what each carried.
[DHCP]#
Pipe's DHCP server answers on the one interface the app names. Before it answers anything it listens for another DHCP server there, a few seconds, and stands down if it hears one, usually the router's: two servers on a network hand out one address twice. It looks again every five minutes, and also stands down if a device asks for an address from another server. Turn the router's DHCP off to use Pipe's.
| Key | Values | Default | What it does |
|---|---|---|---|
default-lease-time |
seconds | 3600 | How long an address is given for, to a device that does not ask. |
min-lease-time, max-lease-time |
seconds | 300, 86400 | The least and the most a device that asks is given. At most 90 days. |
one-lease-per-client |
true, false |
true |
A device is its hardware address. false: a device that sends a client identifier is that identifier, so that two systems on one machine have an address each. |
ping-check |
true, false |
true |
An address new to a device is checked first, and passed over for ten minutes if something answers. |
- A value that cannot be read is warned about, and its default is used. So is a time past 90 days. Bounds that disagree are warned about, and made to agree; a default outside them is brought inside.
- A device keeps its address for as long as nobody else needs it. Leases are kept across restarts.
- An address the Mac sees in use that no lease explains is a device's own, set by hand, and is left alone.
- A device can have an address reserved: it always gets that one, and no other device gets it. It may lie outside the pool, on the subnet.
- A module cannot change
[DHCP].
Devices#
Pipe lists the devices it hears of: from DHCP, from the Mac's neighbour table, and from their connections. Each has a name you give it, or else the one it gave DHCP. Names, reservations and what each carried are kept across restarts, for up to 1,024 devices; those you named stay.
DEVICE-NAME matches a device's
name, MAC-ADDRESS its hardware address, and SRC-IP its address. A
connection from a device Pipe has no name for has no DEVICE-NAME. A
connection from the Mac itself is no device's: only SRC-IP sees it.
The UDP fast path#
Some software talks to hundreds of peers over UDP, a few packets each. A device that opens 10 UDP flows within a second, or 30 within ten seconds, has its new flows sent straight out for the next minute, past the rules: Pipe stops deciding each one. What is already under way stays as it is.
- Destination ports below 1024 stay with the rules, and so does every flow to a name. Only an address given by the device itself goes this way.
- In Global mode and with an exit node, nothing does.
- A device can be pinned to either way: always the fast path, or never.
- These flows are in no connection list, and go out directly whatever the
rules say. Pin a device to
neverwhen that matters for it.