Practical guide · Qeli 0.8.1

Ready-made scenarios

Choose a goal, copy the minimal pattern, then replace addresses, interfaces and secrets with your own. These examples show how settings fit together; they are not complete configuration files.

Decision map

Start with the desired outcome

GoalPatternKey setting
Send all traffic through the VPS public IPServer NAT + client full tunnelrouting.nat.enabled + gateway
Reach only a home NAS, cameras and servicesAn exact pushed route without a default routeroute + gateway = false
One server with different modes and portsIndependent [profile:*] listenersbind.port + unique TUN/pool
A primary TCP path and a backup UDP pathTwo profiles and two linksprofiles + manual selection
Split resource groups by IPLocal include/exclude rules or a fileroute_file / exclude
Recover after sleep and Wi-Fi/LTE changesReconnect + automatic MTUreconnect + mtu = 0
Connect two sitesSite-to-site without NATclient_subnet + forward
First identify the direction of traffic. route tells a client what to reach through Qeli; allowed_networks limits destinations a user may reach; client_subnet registers a network located behind a client. These settings are not interchangeable.
Scenario 1

A VPS as a full-tunnel VPN

The server sends traffic from the Qeli pool through its WAN, while the client installs a default route into the tunnel. The server DNS proxy keeps name resolution off the physical network.

/etc/qeli/server.conf · [profile:main]
routing.nat.enabled = true
routing.forward_private = true
dns.enabled = true
dns.listen = 10.9.0.1
dns.upstream = 1.1.1.1
client.conf · [qeli]
gateway = true
kill_switch = true
dns = tunnel
mtu = 0
NAT requires Linux and iptables on the server. If WAN detection chooses the wrong interface, set routing.nat.interface = ens3. On Android, kill switch requires system Always-on VPN and Block connections without VPN; on iOS, VPN On Demand provides that role.
Scenario 2

Home-network access only

The client keeps its default route and receives only the home-LAN route. The Qeli server forwards packets without translating addresses, while the home router sends replies to the VPN pool through the Qeli server's LAN address. This preserves real client addresses and provides normal bidirectional routing.

/etc/qeli/server.conf · [profile:home]
routing.nat.enabled = false
routing.forward_private = true
route = 192.168.50.0/24 gateway=10.9.0.1 metric=100
/etc/qeli/users.conf + client.conf
[user:home]
allowed_networks = 192.168.50.0/24

[qeli]
gateway = false
home router · return route
# pool=10.9.0.0/24; Qeli-LAN=192.168.50.2
sudo ip route replace 10.9.0.0/24 via 192.168.50.2
A return route is required. Reserve LAN address 192.168.50.2 for the Qeli server and create a route on the main home router: destination 10.9.0.0/24 (pool.cidr), next hop 192.168.50.2. The command above is a Linux example; persist the route using your OS or router's supported method.
NAT is only a fallback compromise. If the home router cannot add a static route, you can enable routing.nat.enabled = true and select the LAN interface. LAN devices will then stop seeing the clients' real VPN addresses, which weakens logging and access-control rules.
Scenario 3

A server with multiple profiles and ports

Each profile is a separate listener with its own transport, port, TUN and pool. Users are global, while the profiles field can restrict them to selected entry points.

/etc/qeli/server.conf · structural example
[profile:reality-tls]
bind.port = 443
bind.transport = tcp
tun.name = vpn0
tun.address = 10.9.0.1
pool.cidr = 10.9.0.0/24
obf.mode = reality-tls

[profile:udp-quic]
bind.port = 8449
bind.transport = udp
tun.name = vpn7
tun.address = 10.9.7.1
pool.cidr = 10.9.7.0/24
obf.mode = fake-tls
obf.quic.enabled = true
This is only a skeleton. reality-tls also requires a target, a matching SNI, your own short_id and the remaining masking settings. Start from the complete server-multiprofile.conf, remove profiles you do not need and open each TCP/UDP port separately in the firewall.
Scenario 4

reality-tls as primary, udp-quic as backup

Allow one user on both server profiles and issue two links. Save them on the client as Primary and Backup: TCP/reality-tls is usually more predictable, while UDP/QUIC can be faster on a healthy UDP path.

users.conf + share links
[user:alice]
profiles = reality-tls, udp-quic

sudo qeli share-link alice --host vpn.example.com:443 --profile reality-tls
sudo qeli share-link alice --host vpn.example.com:8449 --profile udp-quic
Roaming does not switch profiles or transports automatically. It moves the current profile's session between physical paths. To move from reality-tls to udp-quic, still disconnect and select the backup profile manually; TCP 443 and UDP 8449 need separate firewall rules.
Scenario 5

Split routing for domestic and foreign resources

Qeli accepts IP addresses and CIDRs, not domains or country names. Geographic splitting therefore relies on a network list that you maintain and remains approximate because CDNs, anycast and service addresses change.

variant A · selected networks through Qeli
[qeli]
gateway = false
route_file = C:\Qeli\foreign-cidrs.txt
foreign-cidrs.txt · documentation-only addresses
# one IPv4 address or CIDR per line
203.0.113.0/24
198.51.100.7
variant B · full tunnel, selected networks direct
[qeli]
gateway = true
exclude = 203.0.113.0/24, 198.51.100.7/32
route_file is applied only on Windows/macOS and adds split routes. On the Linux CLI and mobile clients, use include/exclude or server push with repeated route entries. The networks above are reserved for documentation; replace them with a verified current list.
Scenario 6

Mobile networks and unstable Wi-Fi

Keep infinite reconnects and automatic MTU. For UDP, active MTU probing adapts to the path more safely than a hand-picked value; do not hard-code socket buffers without measurements.

client.conf · [qeli]
reconnect = true
reconnect_retries = -1
reconnect_base_delay = 1
reconnect_max_delay = 60
timeout = 30
mtu = 0
mtu_probe = true
Keep roaming=auto in 0.8.1. On Wi-Fi/LTE changes, Qeli first tries to move the current session while preserving TUN, routes and lease; if the platform, server or transport lacks the full contract, it performs a safe reconnect. Use required only for a fully upgraded fleet.
Additional scenario

Site-to-site: two local networks

Two Linux clients act as site routers. The server registers each LAN behind its corresponding user and permits client-to-client forwarding without NAT.

server.conf + users.conf
[profile:sites]
routing.client_to_client = true
routing.forward_private = true
routing.nat.enabled = false

[user:branch-a]
client_subnet = 192.168.50.0/24
route = 192.168.60.0/24 gateway=10.9.0.1

[user:branch-b]
client_subnet = 192.168.60.0/24
route = 192.168.50.0/24 gateway=10.9.0.1
both Linux gateways · [qeli]
gateway = false
forward = true
Local routers need return routes. At site A, route 192.168.60.0/24 through Qeli client A; at site B, route 192.168.50.0/24 through client B. Site subnets and VPN pools must not overlap.
Next level

More useful ready-made patterns

For a team or family, separate access with profiles, allowed_networks, max_sessions and groups. Do not share one password across every device: separate users make revocation and auditing easier.

Before starting

A universal scenario checklist

configuration checks
sudo qeli check-config --config /etc/qeli/server.conf
qeli check-config --client --config /etc/qeli/client.conf
sudo systemctl restart qeli
sudo journalctl -u qeli -n 100 --no-pager
Verify the path from both ends: the required TCP/UDP port is open, TUN and pool values are unique, the pushed route appeared on the client, the ACL permits the destination, a return route exists, and DNS and the public IP match the chosen pattern.
Primary sources

v0.8.1 configurations and documentation