routing-switch
System-wide traffic routing through various proxy protocols
File Information
| Property | Value |
|---|---|
| Binary Name | routing-switch |
| Version | 10.0.3 |
| Build Date | Not disclosed |
| Rust Version | 1.70.0 |
| File Size | 14.6MB |
| Author | Warith Al Maawali |
| License | Proprietary |
| Category | Kodachi Binary |
| Description | System-wide traffic routing through various proxy protocols |
| Git Commit | unknown |
| Metadata Generated | 2026-09-29T22:00:26Z |
| Binary Timestamp | Unknown |
| JSON Data | View Raw JSON |
SHA256 Checksum
8d994529be5e7b64dda99f4fcaf3646d8807987e2bc8a99e8723338a113bdaba
Features
| # | Feature |
|---|---|
| 1 | System-wide traffic routing through proxy protocols |
| 2 | Support for OpenVPN, WireGuard, and Dante SOCKS5 |
| 3 | Support for Tor, Shadowsocks, V2Ray, and Xray protocols |
| 4 | Support for Mieru/Mita and Hysteria2 protocols |
| 5 | Support for obfuscated transports: AmneziaWG and OpenVPN over Cloak |
| 6 | Automatic protocol scoring and selection |
| 7 | DNS leak prevention with multiple modes |
| 8 | Metric-based and direct routing options |
| 9 | External configuration file support |
| 10 | IPv4/IPv6 dual-stack support |
| 11 | QR code generation for mobile clients |
| 12 | VPNGate free VPN integration (100+ public servers; browsing is auth-free, vpngate-connect requires authentication) |
| 13 | External VPN Providers sub-tree (routing-switch providers): 20 verbs over a user-editable catalog of commercial and free providers (VPN Gate, Riseup, NordVPN, IVPN, PIA, Surfshark, AirVPN, Mullvad-WG), with credential storage, custom config import, latency benchmarking, and random/fastest pick |
| 14 | Microsocks SOCKS5 server mode: share this machine's active tunnel with other devices on the LAN |
| 15 | Comprehensive logging and monitoring |
Global Options
| Flag | Description |
|---|---|
-h, --help |
Print help information |
-v, --version |
Print version information |
-n, --info |
Display detailed information |
-e, --examples |
Show usage examples |
--json |
Output in JSON format |
--json-pretty |
Pretty-print JSON output with indentation |
--json-human |
Enhanced JSON output with improved formatting (like jq) |
--verbose |
Enable verbose output |
-o, --output-format <FORMAT> |
Force output format: text (default) or json |
Commands
CONNECTION COMMANDS
connect
Connect to a proxy protocol (openvpn, wireguard, amneziawg use native routing; openvpn-cloak runs OpenVPN inside a locally spawned Cloak client; tor uses redsocks and requires WireGuard, plain OpenVPN, or a supported routed proxy; AmneziaWG, OpenVPN over Cloak, and no-TUN routes cannot underlay Remote Tor; dante, shadowsocks, v2ray, xray-*, mita, hysteria2 use tun2socks). Requires root and a prior online-auth login.
Usage:
sudo routing-switch connect <PROTOCOL> [OPTIONS]
Options:
--config <FILE>: Use an external config file instead of the auth card (.ovpn / .conf for OpenVPN and WireGuard, card-native services.<proto> JSON for the rest)--ipv4: Force the IPv4 endpoint of a dual-stack protocol (conflicts with --ipv6)--ipv6: Force the IPv6 endpoint of a dual-stack protocol (conflicts with --ipv4)--force: Disconnect the currently active protocol first, then connect this one. It does NOT stack two VPNs. Not needed for `connect tor`, which layers only on WireGuard, plain OpenVPN, or a supported routed proxy. AmneziaWG, OpenVPN over Cloak, and no-TUN routes are excluded--dns-mode <MODE>: DNS routing: auto (default, DNS flows through the tunnel), hybrid (VPN server DNS bypasses the tunnel), strict (ALL DNS through the tunnel), system (ALL DNS bypasses the tunnel: LEAKS, debugging only)--exclude-private: Keep private/LAN networks off the VPN so local devices stay reachable--no-tun: Run the proxy client without a TUN device: system routing is untouched and you point apps at the local SOCKS5 port by hand. Supported by the tun2socks protocols only, `connect tor --no-tun` is rejected--metric: Metric-based routing: keeps the original route as a fallback. LESS SECURE, traffic can leak to the clear net if the TUN drops. Default is direct routing--skip-prerequisites: Skip the IPv4-forwarding / NAT / MASQUERADE checks before connecting--allow-ipv6-leak: DANGER: keep the connection alive even when an IPv6 leak is detected. The default is fail-closed (the connection is torn down). With this flag your real IPv6 address stays exposed
Examples:
sudo routing-switch connect wireguard
sudo routing-switch connect openvpn --config /path/to/vpn.ovpn --force
sudo routing-switch connect wireguard && sudo routing-switch connect tor
sudo routing-switch connect shadowsocks --no-tun
disconnect
Disconnect the current proxy connection and restore normal routing
Usage:
sudo routing-switch disconnect [OPTIONS]
Options:
--force: Kill the protocol processes outright and skip the graceful cleanup checks--clean-firewall: Also flush the iptables rules (Docker/KVM chains are preserved). Use when the network stays stuck after a normal disconnect. REQUIRES AUTHENTICATION: it tears down the kill-switch rules, so unlike a plain disconnect it is not auth-exempt
Examples:
sudo routing-switch disconnect
sudo routing-switch disconnect --force --clean-firewall
status
Show the current connection status (auth-exempt, but needs sudo to read privileged system state)
Usage:
sudo routing-switch status [OPTIONS]
Options:
--detailed: Add the exact Connected Since timestamp to the normal status block
Examples:
sudo routing-switch status
sudo routing-switch status --detailed --json
INFORMATION COMMANDS
dns-info
Display current DNS server information (auth-exempt)
Usage:
routing-switch dns-info [OPTIONS]
Examples:
routing-switch dns-info
routing-switch dns-info --json
tor-dns-info
Display the Tor DNS and SOCKS endpoints. Kodachi's Tor is VPN-side: its SOCKS5 lives on the worker (10.0.0.1:9050 over WireGuard, 172.16.0.1:9050 over OpenVPN), never on 127.0.0.1
Usage:
routing-switch tor-dns-info [OPTIONS]
Examples:
routing-switch tor-dns-info
routing-switch tor-dns-info --json
vps-info
Display VPS server information (hostname, IP, stats)
Usage:
routing-switch vps-info [OPTIONS]
Options:
--detailed: Include CPU load, memory usage, uptime and connection counts
Examples:
routing-switch vps-info
routing-switch vps-info --detailed
list-protocols
List available protocols with their security/speed scores (auth-exempt)
Usage:
routing-switch list-protocols [OPTIONS]
Options:
--detailed: Show the full scoring breakdown per protocol, not just the overall score--test: Probe each protocol's endpoint for real instead of scoring from the auth card alone (slower, more accurate, needs network)--available-only: Hide protocols the auth card does not provide--sort-by-security: Sort by security score (conflicts with --sort-by-speed)--sort-by-speed: Sort by speed score (conflicts with --sort-by-security)
Examples:
routing-switch list-protocols
routing-switch list-protocols --detailed --sort-by-security
TESTING COMMANDS
test-protocol
Test one protocol's endpoint (or `all`) without touching routing. Reads the auth card, so it needs authentication
Usage:
routing-switch test-protocol <PROTOCOL|all> [OPTIONS]
Options:
--extended: Run the longer test set (latency and throughput checks) instead of a plain reachability probe
Examples:
routing-switch test-protocol wireguard
routing-switch test-protocol amneziawg
routing-switch test-protocol openvpn-cloak --json
routing-switch test-protocol all --json
benchmark
Measure TCP connection latency for all available protocols. Requires authentication because it reads auth-card endpoints
Usage:
routing-switch benchmark [OPTIONS]
Options:
--iterations <N>: Number of test iterations per protocol (default: 3). More iterations means slower but steadier numbers
Examples:
routing-switch benchmark
routing-switch benchmark --iterations 5 --json
CONFIGURATION COMMANDS
export-config
Export protocol configurations to files. Requires authentication
Usage:
routing-switch export-config [PROTOCOL|all] [OPTIONS]
Options:
-p, --path <PATH>: Directory to write the configs to (default: ./results/configs/). Created if it does not exist--include-credentials: WARNING: writes the real passwords and keys into the exported files
Examples:
routing-switch export-config wireguard
routing-switch export-config amneziawg
routing-switch export-config openvpn-cloak
routing-switch export-config all --path /tmp/vpn-configs/
showconfig
Show a protocol's configuration. Requires authentication
Usage:
routing-switch showconfig [PROTOCOL|all] [OPTIONS]
Options:
--mask-sensitive: Redact passwords, keys and credential-bearing URLs so the output is safe to share or log
Examples:
routing-switch showconfig wireguard
routing-switch showconfig amneziawg
routing-switch showconfig openvpn-cloak
routing-switch showconfig dante --mask-sensitive
showconfigurl
Show a protocol's configuration as a connection URL (ss://, socks5://, ...). Requires authentication
Usage:
routing-switch showconfigurl [PROTOCOL|all] [OPTIONS]
Examples:
routing-switch showconfigurl shadowsocks
routing-switch showconfigurl openvpn-cloak
routing-switch showconfigurl all --json
showconfigqr
Show a protocol's configuration as a QR code for mobile clients. Requires authentication. amneziawg is supported and needs an AmneziaWG client to import it; openvpn and openvpn-cloak are NOT, because an OpenVPN body carries inline certificates and cannot fit a scannable code, so use showconfigurl or export-config for those two
Usage:
routing-switch showconfigqr [PROTOCOL|all] [OPTIONS]
Options:
--ipv4: Generate the IPv4 QR code (this is the default for dual-stack protocols)--ipv6: Generate the IPv6 QR code. Can be combined with --ipv4 to emit both--skip-validation: Do not re-read the generated QR to verify it (faster, for debugging)--strict-validation: Fail the whole operation if any generated QR code fails validation--save-files: Also write the QR codes as PNG files into ./results/qr-codes/
Examples:
routing-switch showconfigqr wireguard
routing-switch showconfigqr amneziawg
routing-switch showconfigqr shadowsocks --ipv4 --ipv6 --save-files
validate-qr
Validate QR code configurations against the auth card (by file, by stdin, or by protocol). Requires authentication
Usage:
routing-switch validate-qr [PROTOCOL|<FILE>.png|all] [OPTIONS]
Options:
-f, --file <FILE>: Path to a QR image to decode. Equivalent to passing the filename positionally. If the file is not in the current directory, ./results/qr-codes/ is searched--stdin: Read the QR payload (the URL) from stdin instead of an image--test-readability: Round-trip check: generate a QR for the protocol and confirm it decodes back to the same config
Examples:
routing-switch validate-qr shadowsocks_ipv4.png
echo 'ss://...' | routing-switch validate-qr --stdin
MANAGEMENT COMMANDS
auto-select
Score the available protocols, pick the best one, and connect to it. Requires authentication
Usage:
sudo routing-switch auto-select [OPTIONS]
Options:
--min-security <SCORE>: Reject protocols scoring below this security threshold, 0 to 100 (default: 80)--prefer-speed: Weight speed above the other factors when ranking--prefer-obfuscated: Opt into amneziawg and openvpn-cloak; without this flag both are excluded from the default ranking, and with it each ranks above the plain protocol it wraps
Examples:
sudo routing-switch auto-select
sudo routing-switch auto-select --min-security 90
sudo routing-switch auto-select --prefer-obfuscated
reset
Reset all routing to the system default state. DESTRUCTIVE: drops the active tunnel, so you are back on the clear net afterwards. Auth-exempt on purpose (it must work when the network is down)
Usage:
sudo routing-switch reset [OPTIONS]
Options:
--force: Reset even when the stored state says a connection is still active or the teardown reports errors
Examples:
sudo routing-switch reset
sudo routing-switch reset --force
cleanup
Clean up orphaned protocol processes and leftover resources. Auth-exempt
Usage:
sudo routing-switch cleanup [OPTIONS]
Options:
--thorough: Deeper sweep: also removes stale TUN devices, routes and iptables rules, not just stray processes. Can disturb an active connection, so run it after disconnecting
Examples:
sudo routing-switch cleanup
sudo routing-switch cleanup --thorough
recover
Diagnose and repair a half-broken routing state (cleanup, route restore, DNS reset). The 'my internet is stuck' command. Auth-exempt
Usage:
sudo routing-switch recover [OPTIONS]
Options:
--force: Run the recovery even when routing-switch believes the state is healthy. DESTRUCTIVE: drops any active tunnel and restores the clear-net default route
Examples:
sudo routing-switch recover
sudo routing-switch recover --force
check-prerequisites
Check and fix the network prerequisites for VPN connections (IPv4 forwarding, NAT MASQUERADE). Fixes only what is wrong. Auth-exempt
Usage:
sudo routing-switch check-prerequisites [OPTIONS]
Options:
--ipv6: Also check (and enable, if the system supports it) the IPv6 forwarding prerequisites
Examples:
sudo routing-switch check-prerequisites
sudo routing-switch check-prerequisites --ipv6 --json
MICROSOCKS SERVER MANAGEMENT
microsocks-enable
Run a SOCKS5 server on this machine so other devices on the LAN can ride its active tunnel. Connect a protocol FIRST, then enable this. Requires authentication
Usage:
sudo routing-switch microsocks-enable (-u <USERNAME> -p <PASSWORD> | --stdin-credentials) [--port PORT]
Options:
-u, --username <USERNAME>: SOCKS5 username the client devices must present (required)-p, --password <PASSWORD>: SOCKS5 password (required). The listener binds 0.0.0.0, so use a strong one--stdin-credentials: Read required username/password JSON from bounded stdin and redact the password from output--port <PORT>: Listening port. Omit to auto-pick the first free port in the 30050-30054 range
Examples:
sudo routing-switch microsocks-enable -u microkodachi-8273 -p 'S@Cur9P@s@Wo-Ds'
sudo routing-switch microsocks-enable -u microkodachi-8273 -p 'S@Cur9P@s@Wo-Ds' --port 30051
microsocks-disable
Stop the microsocks SOCKS5 server. Requires authentication
Usage:
sudo routing-switch microsocks-disable
Examples:
sudo routing-switch microsocks-disable
sudo routing-switch microsocks-disable --json
microsocks-status
Show the microsocks server status (running, port, PID, uptime). Auth-exempt
Usage:
routing-switch microsocks-status [OPTIONS]
Examples:
routing-switch microsocks-status
routing-switch microsocks-status --json
VPNGATE FREE VPN
vpngate-fetch
Fetch the VPNGate public server list into the local cache (auth-exempt, refreshes hourly)
Usage:
routing-switch vpngate-fetch [OPTIONS]
Examples:
routing-switch vpngate-fetch
routing-switch vpngate-fetch --json
vpngate-list
List the cached VPNGate servers with filtering and sorting (auth-exempt). The index it prints is what vpngate-connect and vpngate-export take
Usage:
routing-switch vpngate-list [OPTIONS]
Options:
-c, --country <COUNTRY>: Filter by country name or code (for example JP, Japan, US)-s, --sort <CRITERIA>: score (default, highest first), speed (highest first), ping (lowest first), sessions (lowest first, i.e. least crowded)-l, --limit <N>: Show only the first N results after filtering and sorting
Examples:
routing-switch vpngate-list
routing-switch vpngate-list --country JP --sort speed -l 10
vpngate-connect
Connect to a VPNGate server by index (OpenVPN, public vpn/vpn credentials). REQUIRES AUTHENTICATION: it rewrites routes, DNS and firewall like any other connect. Only VPNGate BROWSING (fetch/list/export) is auth-free
Usage:
sudo routing-switch vpngate-connect <INDEX> [OPTIONS]
Options:
--force: Disconnect the currently active connection first--skip-prerequisites: Skip the IPv4-forwarding / NAT / MASQUERADE checks before connecting
Examples:
sudo routing-switch vpngate-connect 5
sudo routing-switch vpngate-connect 12 --force
vpngate-export
Export one cached VPNGate server's OpenVPN config as a standalone .ovpn file (auth-exempt)
Usage:
routing-switch vpngate-export <INDEX> [OPTIONS]
Examples:
routing-switch vpngate-export 1
routing-switch vpngate-export 5 --json
vpngate-export-all
Export every cached VPNGate server as a .ovpn file into results/vpngate-configs (auth-exempt)
Usage:
routing-switch vpngate-export-all [OPTIONS]
Examples:
routing-switch vpngate-export-all
routing-switch vpngate-export-all --json
providers
External VPN Providers sub-tree (20 verbs) over a user-editable catalog of commercial and free providers (VPN Gate, Riseup, NordVPN, IVPN, PIA, Surfshark, AirVPN, Mullvad-WG). EVERY providers verb requires authentication, and every cache-writing verb requires root. Run `routing-switch providers --help` for the per-verb flags
Usage:
routing-switch providers <SUBCOMMAND> [OPTIONS]
Options:
list | refresh-catalog: Show the catalog with cache freshness; re-read the catalog JSON after editing dashboard/hooks/config/vpn-providers-public-api.jsonfetch <ID> [--force]: Fetch a provider's profile list into the cache. --force bypasses the cache TTL. Needs rootlist-profiles <ID> [-c|--country CC] [-p|--protocol PROTO] [-l|--limit N]: Browse the cached profiles, filtered by 2-letter country code and/or transport protocol substring (udp, tcp, openvpn, wireguard)get-profile <ID> <PROFILE_ID>: Print one profile's raw config body. Lazily fetches on a cache miss, so it needs rootconnect <ID> <PROFILE_ID> [--force] [--skip-prerequisites]: Connect through a provider profile, auto-injecting any stored credentials. Needs rootconnect-random <ID> [--country CC] [--force]: Pick a random profile from the provider's cache (optionally country-filtered) and connect. Needs rootconnect-fastest <ID> [--country CC] [--force]: Pick the fastest profile (benchmarked latency first, then provider-reported speed, then load) and connect. Needs rootbenchmark <ID> [--country CC] [--top N] [--concurrency N] [--timeout S]: Latency-probe the cached profiles and store the result so connect-fastest can use it. Manual only, never auto-runs. Needs rootcredentials-list | credentials-set <ID> --field k=v | credentials-delete <ID>: Manage per-provider VPN account credentials (never the dashboard login). Values are sealed with AES-256-GCM. Set and delete need rootimport-config --name N (--file F | --text T) [--protocol-hint P] | validate-config: Import your own OpenVPN / WireGuard / Shadowsocks / V2Ray / Hysteria2 config as a custom profile (import needs root); validate-config previews the detection without writingdelete-custom-profile <PROFILE_ID> | delete-custom-profiles-bulk (--id ID... | --all): Remove imported custom profiles and their stored credentials. Irreversible, no confirmation prompt. Needs rootresolve-country <ID> <PROFILE_ID> [--force] | resolve-ip <ID> <PROFILE_ID> | resolve-ips <ID> [--concurrency N]: Fill in a cached profile's missing country (via ip-fetch geo) or its missing IPv4 (via DNS), writing back to the cache. Needs rootclear-cache [<ID>] [--all]: Drop a provider's cached index and configs, or every provider's with --all. Credentials are NEVER touched. Needs root
Examples:
routing-switch providers list
sudo routing-switch providers fetch vpngate --force
routing-switch providers list-profiles vpngate --country jp --limit 5
sudo routing-switch providers connect-fastest vpngate --country jp --force
Operational Scenarios
Scenario-oriented workflows generated from the binary's built-in -e --json examples.
Scenario 1: BASIC CONNECTIONS
Connect to a proxy protocol. Every connect verb needs root (it rewrites routes, DNS and iptables) and needs a prior online-auth login: without one you get 'Authentication required'. Only one connection is active at a time; add --force to replace an existing one. The one exception is `connect tor`, which LAYERS on a supported routed underlay and therefore does not take --force.
Step 1: Connect via OpenVPN
sudo routing-switch connect openvpn
Note
Requires OpenVPN configuration in auth card
Step 2: Connect via WireGuard
sudo routing-switch connect wireguard
Note
Ultra-fast, modern VPN protocol
Step 3: Connect via AmneziaWG (obfuscated WireGuard)
sudo routing-switch connect amneziawg
Note
Use when plain WireGuard is blocked by DPI. A plain WireGuard handshake is always a 148-byte packet with a constant type field, which is trivially fingerprinted; AmneziaWG sends Jc junk packets first and pads the handshake by S1 bytes, so nothing on the wire is 148 bytes. It is a SEPARATE protocol on its own node interface (awg0, UDP 3481), not a flag on wireguard: a stock wg client cannot talk to an AmneziaWG server at all. Additive - the node keeps its plain WireGuard listener and both can be used.
Step 4: Connect via AmneziaWG using the short alias
sudo routing-switch connect awg
Note
`awg` is an alias for `amneziawg`; identical behaviour.
Step 5: Connect via OpenVPN wrapped in a Cloak transport
sudo routing-switch connect openvpn-cloak
Note
Use when TLS-in-TLS is fingerprinted or the network actively probes. Cloak makes the outer connection look like a browser reaching a real HTTPS site, and anything that fails Cloak authentication is served a genuine decoy web page instead of a reset, so an active prober sees a normal web server. Costs a second hop, so prefer plain openvpn on an unfiltered network. Requires the ck-client binary. Runs over TCP on the node's high Cloak port; the OpenVPN process itself only ever dials 127.0.0.1.
Step 6: Connect via OpenVPN over Cloak using the short alias
sudo routing-switch connect cloak
Note
`cloak` is an alias for `openvpn-cloak`; identical behaviour.
Step 7: Connect via AmneziaWG and emit machine-readable status
sudo routing-switch connect amneziawg --json
Note
The interface is awg0, not wg0, so an AmneziaWG tunnel and a plain WireGuard tunnel never collide.
Step 8: Connect via Dante SOCKS5 proxy
sudo routing-switch connect dante
Note
Dante rides the shared tun_routing device, so it clashes with any other tun2socks protocol (shadowsocks, v2ray, xray-*, mita, hysteria2). If one of those is already up, disconnect first, or pass --force (which drops the existing connection before dialing).
Step 9: Route traffic through Tor over a supported active Kodachi underlay
sudo routing-switch connect wireguard && sudo routing-switch connect tor
Note
Kodachi's Tor SOCKS proxy is bound to approved Kodachi network subnets only and is never exposed on a public IP, because a public Tor SOCKS port gets abused as an open proxy. So `connect tor` is NOT a standalone command: first connect WireGuard, plain OpenVPN, or a supported routed proxy (Shadowsocks, V2Ray, Xray VLESS, VLESS-Reality, VMess or Trojan, Hysteria2, Mita, or Dante), then `connect tor` layers Tor on that underlay. AmneziaWG, OpenVPN over Cloak, and no-TUN routes are unsupported. Cloak creates tun0, but its 10.88.0.0/24 client subnet is outside the server Tor and firewall allowlists, so an interface-only check is not proof of end-to-end compatibility. Running `connect tor` with no supported underlay is refused with on-screen guidance. Easier alternative for WireGuard or plain OpenVPN: set your browser's SOCKS5 proxy to 10.0.0.1:9050 over WireGuard or 172.16.0.1:9050 over plain OpenVPN.
Step 10: Connect via Shadowsocks
sudo routing-switch connect shadowsocks
Note
Optimized for bypassing censorship
Step 11: Connect via V2Ray VMess
sudo routing-switch connect v2ray
Note
tun2socks protocol: local SOCKS5 is allocated from 30005-30009. Conflicts with any other tun2socks protocol on tun_routing.
Step 12: Connect via Xray VLESS TLS
sudo routing-switch connect xray-vless
Note
Lightweight, fast protocol with TLS
Step 13: Connect via Xray VLESS Reality
sudo routing-switch connect xray-vless-reality
Note
Most advanced censorship resistance
Step 14: Connect via Xray Trojan
sudo routing-switch connect xray-trojan
Note
Mimics HTTPS traffic
Step 15: Connect via Xray VMess
sudo routing-switch connect xray-vmess
Note
VMess over the Xray core: local SOCKS5 is allocated from 30010-30014. Conflicts with any other tun2socks protocol on tun_routing.
Step 16: Connect via Mieru/Mita protocol
sudo routing-switch connect mita
Note
Anti-censorship protocol
Step 17: Connect via Hysteria2 protocol
sudo routing-switch connect hysteria2
Note
UDP-based, high-performance anti-censorship protocol
Scenario 2: EXTERNAL CONFIGURATION FILES
Connect a custom profile with --config instead of the auth card. OpenVPN/WireGuard take standard text bodies; v2ray/xray/shadowsocks/hysteria2/mita take the card-native services.<proto> JSON object (a custom profile is just a card service slice). AmneziaWG and OpenVPN over Cloak do NOT accept --config: they are refused with a named error, because an AmneziaWG body missing its nine obfuscation parameters would silently connect as plain WireGuard. Use the authentication card path for those two.
Step 1: Connect using external OpenVPN config file
sudo routing-switch connect openvpn --config /home/user/vpn.ovpn
Note
Supports standard .ovpn configuration files
Step 2: Connect using external WireGuard config
sudo routing-switch connect wireguard --config /path/to/wg0.conf
Note
Uses standard WireGuard .conf format
Step 3: Connect a custom Shadowsocks profile
sudo routing-switch connect shadowsocks --config /path/to/shadowsocks-profile.json
Note
File is the card-native services.shadowsocks JSON object (method, password, port, ipv4{host,url})
Step 4: Connect a custom V2Ray (VMess) profile
sudo routing-switch connect v2ray --config /path/to/v2ray-profile.json
Note
File is the card-native services.v2ray JSON object (uuid, port, network, path, security, alterId, ipv4{host,url})
Step 5: Connect a custom Xray profile (xray-vless / xray-vless-reality / xray-trojan / xray-vmess)
sudo routing-switch connect xray-vless-reality --config /path/to/xray-profile.json
Note
File is the card-native services.xray JSON object (domain, protocols{vless|trojan|vmess}, reality_public_key)
Step 6: Connect a custom Hysteria2 profile
sudo routing-switch connect hysteria2 --config /path/to/hysteria2-profile.json
Note
File is the card-native services.hysteria2 JSON object (password, port, protocol, obfs_type, obfs_password, ipv4{host,url})
Step 7: Connect a custom Mita/Mieru profile
sudo routing-switch connect mita --config /path/to/mita-profile.json
Note
File is the card-native services.mita JSON object (username, password, port, protocol, mtu, multiplexing, ipv4{host,url})
Step 8: Force connection with external config
sudo routing-switch connect openvpn --config ./vpn.ovpn --force
Note
Combines --config with other flags like --force
Step 9: External config in no-TUN mode
sudo routing-switch connect shadowsocks --config ~/configs/ss.json --no-tun
Note
Use external config for manual proxy setup
Scenario 3: IPV4/IPV6 SELECTION
Explicitly choose the IPv4 or the IPv6 endpoint of a protocol. --ipv4 and --ipv6 are mutually exclusive (clap rejects both together). If an IPv6 leak is detected while connecting, routing-switch fails closed and tears the connection down; --allow-ipv6-leak is the only way to override that, and it is documented in DNS MODES AND SECURITY below. The two obfuscated protocols are the exception: AmneziaWG and OpenVPN over Cloak carry ONE endpoint each in the authentication card and no IPv6 sibling. AmneziaWG's is the Endpoint line inside its WireGuard-shaped config body, Cloak's is its own server_host/server_port pair (the inner OpenVPN never dials anything but 127.0.0.1), so there is nothing for --ipv6 to select on either one.
Step 1: Force IPv4 connection to Dante
sudo routing-switch connect dante --ipv4
Step 2: Force IPv6 connection to Dante
sudo routing-switch connect dante --ipv6
Note
Requires IPv6 support
Step 3: Connect Shadowsocks over IPv4
sudo routing-switch connect shadowsocks --ipv4
Step 4: Layer Tor on an active WireGuard tunnel and use the worker's IPv6 Tor SOCKS endpoint
sudo routing-switch connect wireguard && sudo routing-switch connect tor --ipv6
Note
UNDERLAY REQUIRED: `connect tor` on its own is refused. Kodachi's Tor SOCKS proxy is bound to approved Kodachi network subnets only (never exposed on a public IP), so an end-to-end supported routed underlay must already be up. --ipv6 picks the card's IPv6 Tor endpoint, so both the underlay and the worker need working IPv6.
Step 5: Use IPv6 for Xray VLESS
sudo routing-switch connect xray-vless --ipv6
Step 6: Connect Hysteria2 over IPv4
sudo routing-switch connect hysteria2 --ipv4
Step 7: Connect Hysteria2 over IPv6
sudo routing-switch connect hysteria2 --ipv6
Note
Requires IPv6 support
Scenario 4: NETWORK PREREQUISITES
Check and manage network prerequisites for VPN connections
Step 1: Check and fix network prerequisites
sudo routing-switch check-prerequisites
Note
Fixes only what's wrong, preserves correct settings
Step 2: Check prerequisites for IPv6 connections
sudo routing-switch check-prerequisites --ipv6
Note
Only enables IPv6 if system supports it
Step 3: Get prerequisites status in JSON format
sudo routing-switch check-prerequisites --json
Step 4: Connect with automatic prerequisites check
sudo routing-switch connect shadowsocks
Note
Prerequisites are checked by default
Step 5: Connect without prerequisites check
sudo routing-switch connect shadowsocks --skip-prerequisites
Note
Skips prerequisites for backward compatibility
Step 6: Force reconnection with prerequisites check
sudo routing-switch connect wireguard --force
Note
Prerequisites persist after disconnect for other VPN tools
Scenario 5: CONNECTION STATUS
Check and monitor connection status
Step 1: Show current connection status
sudo routing-switch status
Note
Requires sudo for accurate results (reads privileged system state). No online-auth login needed: status is auth-exempt.
Step 2: Status plus the exact timestamp the connection was established
sudo routing-switch status --detailed
Note
--detailed adds the Connected Since line on top of the normal status block. Everything else is the same.
Step 3: Get status in JSON format
sudo routing-switch status --json
Step 4: Pretty-printed JSON status
sudo routing-switch status --json-pretty
Step 5: Human-readable JSON status
sudo routing-switch status --json-human
Scenario 6: DNS MODES AND SECURITY
Control DNS routing for security and compatibility (DEFAULT: auto mode)
Step 1: DEFAULT: Auto mode (no special DNS routing)
sudo routing-switch connect wireguard
Note
DEFAULT safe mode - DNS flows through tunnel like all traffic. Note: May not work with all protocols
Step 2: Auto mode: DNS flows naturally through tunnel (explicit)
sudo routing-switch connect wireguard --dns-mode auto
Note
Same as omitting --dns-mode; explicit form for scripting
Step 3: Hybrid mode: VPN server DNS bypasses tunnel
sudo routing-switch connect wireguard --dns-mode hybrid
Note
⚠️ WARNING: May cause internet loss! Use 'sudo routing-switch recover' to restore connectivity. Good balance of security and reliability for home/office use when you need LAN access
Step 4: Strict mode: ALL DNS through tunnel
sudo routing-switch connect wireguard --dns-mode strict
Note
Most secure, may fail if VPN server uses hostname
Step 5: System mode: DNS bypasses tunnel
sudo routing-switch connect wireguard --dns-mode system
Note
⚠️ NOT SECURE - DNS leaks! Use only for debugging
Step 6: Keep the connection up even when an IPv6 leak is detected (default is fail-closed)
sudo routing-switch connect wireguard --allow-ipv6-leak
Note
DANGER: this is the one flag that deliberately weakens leak protection. By default routing-switch terminates the connection the moment it sees an IPv6 leak, so your real IPv6 address cannot escape. With --allow-ipv6-leak the connection is kept and your real IPv6 address stays reachable to every site you visit. Use it only on a host with no usable IPv6, and only when you accept the deanonymisation risk.
Step 7: Exclude private networks from VPN
sudo routing-switch connect wireguard --exclude-private
Note
Keep LAN access while using VPN
Step 8: Hybrid DNS with private network exclusion
sudo routing-switch connect wireguard --dns-mode hybrid --exclude-private
Note
Good for home/office use when you need LAN access
Scenario 7: ROUTING MODES - SECURITY vs RETAINED CLEAR ROUTE
Choose between Direct routing and Metric routing that intentionally keeps the original clear route usable
Step 1: DEFAULT: Direct routing mode (MOST SECURE), Tor layered on WireGuard
sudo routing-switch connect wireguard && sudo routing-switch connect tor
Note
✅ RECOMMENDED, strongest default, paired with leak checks and kill-switch controls. UNDERLAY REQUIRED: `connect tor` on its own is refused, Kodachi's Tor SOCKS proxy is Kodachi-network-side only. Connect WireGuard, plain OpenVPN, or a supported routed proxy first. AmneziaWG, OpenVPN over Cloak, and no-TUN routes are unsupported.
Step 2: Metric routing mode (LESS SECURE, retains clear route), Tor layered on WireGuard
sudo routing-switch connect wireguard && sudo routing-switch connect tor --metric
Note
⚠️ WARNING: the original clear route remains usable and traffic can leak if the TUN fails. Use metric mode only when you explicitly accept that behavior. UNDERLAY REQUIRED: `connect tor` on its own is refused, and an end-to-end supported routed underlay must already be up.
Step 3: Direct mode for Shadowsocks (default)
sudo routing-switch connect shadowsocks
Note
Strongest default; leak checks and health controls decide failure handling
Step 4: Metric mode for corporate VPN scenarios
sudo routing-switch connect dante --metric
Note
Less secure mode for cases that require an intentionally retained clear route. Recheck routing status before resuming traffic.
Step 5: Metric mode with LAN access preserved
sudo routing-switch connect xray-vless --metric --exclude-private
Note
Corporate setup with LAN access. The retained clear route can leak traffic if the tunnel drops.
Scenario 8: DISCONNECTION
Disconnect and restore normal routing
Step 1: Disconnect current proxy
sudo routing-switch disconnect
Step 2: Force disconnect even if issues
sudo routing-switch disconnect --force
Note
Kills all processes forcefully
Step 3: Disconnect and clean all firewall rules
sudo routing-switch disconnect --clean-firewall
Note
Use when network is stuck after disconnect due to lingering iptables rules
Step 4: Force disconnect with complete firewall cleanup
sudo routing-switch disconnect --force --clean-firewall
Note
Emergency recovery - resets all iptables rules (preserves Docker/KVM chains)
Step 5: Disconnect with JSON output
sudo routing-switch disconnect --json
Scenario 9: FORCE FLAG & PROTOCOL COMPATIBILITY
Understanding --force behavior and which protocols can layer together. PROTOCOL TYPES: native VPNs own their interface (openvpn -> tun0, wireguard -> wg0, amneziawg -> awg0, openvpn-cloak -> its own tun via a local ck-client). Tor is redsocks based (iptables NAT, no interface of its own). Everything else is tun2socks based and shares ONE device, tun_routing: shadowsocks, dante, v2ray, xray-vless, xray-vless-reality, xray-trojan, xray-vmess, mita, hysteria2. The two obfuscated protocols are native: amneziawg owns awg0 and openvpn-cloak owns its own tun, so neither competes for tun_routing. COMPATIBILITY: WireGuard, plain OpenVPN, or a supported routed proxy + Tor layer through an approved end-to-end route. AmneziaWG is rejected because awg0 has no accepted Remote Tor path. OpenVPN over Cloak creates tun0, but its 10.88.0.0/24 client subnet is outside the server Tor and firewall allowlists. Two tun2socks protocols never coexist, because they fight over tun_routing. RECOMMENDED LAYERING: connect WireGuard, plain OpenVPN, or one supported routed proxy FIRST, then `connect tor` on top. --force is not needed for that, because Tor over a supported underlay is allowed through the single-connection guard on purpose. Use --force only when you want to REPLACE the active connection with a different one. Always re-test connectivity after layering.
Step 1: Creates LAYERED connection: Tor-over-WireGuard ✓ (no --force needed)
sudo routing-switch connect wireguard && sudo routing-switch connect tor
Note
LAYERED: connect tor keeps WireGuard as its underlay and does NOT disconnect it. Traffic: App → Tor (redsocks) → WireGuard → Internet. The worker Tor is reachable only through a supported Kodachi-network underlay.
Step 2: Creates LAYERED connection: Tor-over-OpenVPN ✓ (no --force needed)
sudo routing-switch connect openvpn && sudo routing-switch connect tor
Note
connect tor keeps plain OpenVPN as its underlay. Tor uses iptables NAT, with no interface conflict on tun0. The worker Tor cannot be connected standalone.
Step 3: Creates LAYERED connection: Tor-over-proxy ✓ (works for Shadowsocks, V2Ray, Xray, Hysteria2, Mita, and Dante)
sudo routing-switch connect shadowsocks && sudo routing-switch connect tor
Note
connect tor keeps the supported routed proxy as its underlay. Shadowsocks, V2Ray, Xray VLESS, VLESS-Reality, VMess or Trojan, Hysteria2, Mita, and Dante ride the tun2socks tun_routing device. The underlay's own uplink to its worker is auto-excluded from the Tor redirect so the tunnel is not broken.
Step 4: REFUSED: two tun2socks protocols cannot both be up ✗
sudo routing-switch connect shadowsocks && sudo routing-switch connect dante
Note
All tun2socks protocols (shadowsocks, dante, v2ray, xray-*, mita, hysteria2) share the same tun_routing device, so they cannot coexist. Adding --force does NOT stack them: it disconnects shadowsocks first and then connects dante.
Step 5: REPLACE the active connection: --force disconnects WireGuard, then dials OpenVPN
sudo routing-switch connect wireguard && sudo routing-switch connect openvpn --force
Note
This is what --force is actually for: swapping one connection for another. It does NOT stack two VPNs. Without --force the second connect is refused with 'another connection is active'.
Scenario 10: DNS INFORMATION
Check DNS configuration
Step 1: Show current DNS servers
routing-switch dns-info
Step 2: DNS info in JSON format
routing-switch dns-info --json
Scenario 11: TOR DNS INFORMATION
Check Tor DNS and SOCKS configuration
Step 1: Show Tor DNS and SOCKS endpoints
routing-switch tor-dns-info
Note
Resolves both regular and .onion domains
Step 2: Tor DNS info in JSON format
routing-switch tor-dns-info --json
Scenario 12: VPS SERVER INFORMATION
Display VPS server details and statistics
Step 1: Show basic VPS information
routing-switch vps-info
Step 2: Show detailed VPS stats
routing-switch vps-info --detailed
Note
Includes CPU load, memory, uptime, and connection stats
Step 3: VPS info in JSON format
routing-switch vps-info --json
Scenario 13: PROTOCOL LISTING
List available protocols with scores. The full listing carries 14 protocols, and the two obfuscated ones are listed ALONGSIDE the protocol each wraps, never in place of it: amneziawg next to wireguard, openvpn-cloak next to openvpn. Each scores the SAME security as the protocol it wraps (amneziawg 98.0 like WireGuard, openvpn-cloak 95.0 like OpenVPN) and a LOWER speed score: junk packets and a padded handshake cost AmneziaWG throughput, and Cloak pays for a second local process plus TCP-over-TCP. So on an unfiltered network the plain protocol still wins the ranking, which is the intended answer. `auto-select` skips both unless you pass --prefer-obfuscated (see AUTO-SELECTION); `list-protocols` always shows them.
Step 1: List all available protocols
routing-switch list-protocols
Step 2: Protocol list in JSON
routing-switch list-protocols --json
Step 3: Show the full scoring breakdown per protocol, not just the overall score
routing-switch list-protocols --detailed
Step 4: Probe each protocol's endpoint for real instead of scoring from the card alone
routing-switch list-protocols --test
Note
Slower (it opens a connection per protocol) but far more accurate than the static scores. Needs network access.
Step 5: Show only available protocols
routing-switch list-protocols --available-only
Note
Based on auth card
Step 6: Sort by security score
routing-switch list-protocols --sort-by-security
Step 7: Sort by speed score
routing-switch list-protocols --sort-by-speed
Scenario 14: AUTO-SELECTION
Automatically select best protocol
Step 1: Auto-select best protocol
sudo routing-switch auto-select
Step 2: Auto-select with minimum security
sudo routing-switch auto-select --min-security 90
Step 3: Prioritize speed in selection
sudo routing-switch auto-select --prefer-speed
Step 4: Opt into amneziawg/openvpn-cloak, ranked above the plain protocol each wraps. Excluded by default because they cost throughput or need a kernel module
sudo routing-switch auto-select --prefer-obfuscated
Step 5: Auto-select with JSON output
sudo routing-switch auto-select --json
Scenario 15: PORT USAGE INFORMATION
Local SOCKS5 port allocation reference. When a tun2socks protocol connects it picks the first free port in its own reserved range on 127.0.0.1: Shadowsocks 30000-30004, V2Ray 30005-30009, Xray VMess 30010-30014, Xray VLESS 30015-30019, VLESS Reality 30020-30024, Xray Trojan 30025-30029, Mieru/Mita 30030-30034, Tor 30035-30039, Dante 30040-30044, Hysteria2 30045-30049, microsocks 30050-30054. The ranges are high (30000+) so they never collide with system services, and each protocol gets its own so two of them can never fight over a port. TRAFFIC FLOW (tun2socks protocols): application -> tun_routing interface -> tun2socks -> 127.0.0.1:<PORT> -> protocol client -> remote server. NATIVE VPNs are different: WireGuard uses the UDP port from its config (typically 51820) and OpenVPN the TCP/UDP port from its config (typically 1194). Neither uses tun2socks or a local SOCKS5 port. AMNEZIAWG is native too: UDP straight to the node's AmneziaWG listener (3481 on a Kodachi node) on its own awg0 interface, no tun2socks and no local SOCKS5 port. OPENVPN OVER CLOAK is the one native protocol that does open a LOCAL port, and it is NOT a proxy port: ck-client runs on this machine, makes the real outer TCP connection to the node's high Cloak port, and the inner OpenVPN body is rewritten to `remote 127.0.0.1 <ck-client port>` over TCP. That loopback port speaks the Cloak transport, not SOCKS5, so no browser or application can be pointed at it. It is also why `disconnect` has to reap ck-client: kill the tunnel and leave ck-client, and the transport is still holding TCP connections to the node. KODACHI TOR is VPN-side, not local: its SOCKS5 lives on the worker at 172.16.0.1:9050 over OpenVPN and 10.0.0.1:9050 over WireGuard.
Step 1: See the local SOCKS5 port a tun2socks protocol actually took
sudo routing-switch connect shadowsocks --no-tun
Note
No-TUN mode is the mode that prints the allocated port, because that port is the whole point of it. In normal (TUN) mode the port is internal plumbing between tun2socks and the protocol client, and you never need it.
Step 2: Get the allocated local SOCKS5 port back as JSON (no-TUN mode reports it explicitly)
sudo routing-switch connect v2ray --no-tun --json
Scenario 16: JSON OUTPUT FORMATS
Different JSON output options
Step 1: Compact JSON output
sudo routing-switch status --json
Note
Requires sudo for accurate results
Step 2: Pretty-printed JSON
sudo routing-switch status --json-pretty
Step 3: Human-enhanced JSON
sudo routing-switch status --json-human
Step 4: Pretty JSON protocol list
routing-switch list-protocols --json --json-pretty
Scenario 17: BENCHMARKING
Test protocol performance
Step 1: Benchmark all protocols (3 iterations default)
routing-switch benchmark
Note
This command measures reachability latency only; it does not claim download or upload throughput
Step 2: Benchmark with custom iteration count
routing-switch benchmark --iterations 5
Note
More iterations = more accurate results
Step 3: Benchmark results in JSON
routing-switch benchmark --json
Scenario 18: TESTING PROTOCOLS
Probe a protocol's endpoint without touching routing. Reads the endpoints from the auth card, so it needs a prior online-auth login.
Step 1: Test whether the worker's Tor SOCKS endpoint is reachable
routing-switch test-protocol tor
Note
Does not change routing. The endpoint comes from the auth card's Tor socks_url, so it is the worker address (VPN-side), never 127.0.0.1. Without a tunnel up it will simply report unreachable, which is expected.
Step 2: Probe the AmneziaWG endpoint (UDP, so it cannot be fully verified)
routing-switch test-protocol amneziawg
Note
`udp_unverified` is a PASS, not a failure. A WireGuard-family endpoint answers nothing without a real cryptographic handshake, so the probe reports the protocol as available while declining to claim connectivity. Plain `wireguard` reports exactly the same status for the same reason. `openvpn-cloak` is different: it rides TCP 8447, so its probe does complete and reports status `ok` with a latency.
Step 3: Probe the Cloak outer endpoint and get a machine-readable verdict
routing-switch test-protocol openvpn-cloak --json
Note
The endpoint probed is the REAL node on TCP 8447, never the inner OpenVPN on 127.0.0.1:11194. If this reports the loopback address, that is a bug worth reporting.
Step 4: Extended protocol test
routing-switch test-protocol shadowsocks --extended
Step 5: Test all available protocols
routing-switch test-protocol all
Step 6: Test with JSON output
routing-switch test-protocol wireguard --json
Scenario 19: NO-TUN MODE (MANUAL PROXY)
Run a proxy client without creating a TUN device, so system traffic is untouched and only the apps you point at the local SOCKS5 port go through it. Configure the client by hand: Firefox -> Settings -> Network Settings -> Manual proxy -> SOCKS5 host 127.0.0.1, port <the allocated port>. Chrome/Chromium: start it with --proxy-server="socks5://127.0.0.1:30000". --no-tun works for the tun2socks protocols (shadowsocks, dante, v2ray, xray-*, mita, hysteria2). It does NOT work for `connect tor`: Kodachi's Tor is redsocks/iptables based and rejects --no-tun outright (see the tor entry below). The NATIVE VPNs refuse it as well: openvpn, wireguard, amneziawg and openvpn-cloak have no SOCKS5 listener to hand you, so --no-tun on any of them fails with "Protocol '<name>' does not support no-TUN mode". openvpn-cloak is the tempting one to get wrong: it DOES open a 127.0.0.1 port, but that port is the Cloak transport endpoint that only its own OpenVPN speaks to, not a proxy you can point an application at.
Step 1: Start Shadowsocks SOCKS5 proxy without TUN
sudo routing-switch connect shadowsocks --no-tun
Note
Configure browser/app manually with localhost:30000
Step 2: Connect to Dante SOCKS5 without routing traffic
sudo routing-switch connect dante --no-tun
Note
Direct connection to remote Dante server
Step 3: Use Kodachi's Tor as a manual proxy: connect a supported routed underlay, then read the Tor SOCKS endpoint and point your app at it
sudo routing-switch connect wireguard && routing-switch tor-dns-info
Note
`connect tor --no-tun` is NOT supported and fails with 'Tor via redsocks does not support no-TUN mode'. Kodachi's Tor is redsocks/iptables based, and its SOCKS5 lives on the worker inside the Kodachi network (10.0.0.1:9050 over WireGuard or 172.16.0.1:9050 over plain OpenVPN), never on 127.0.0.1. OpenVPN over Cloak is excluded because its 10.88.0.0/24 client subnet is outside the server Tor and firewall allowlists. So the manual-proxy path for Tor is: connect a supported routed underlay, then set your browser's SOCKS5 proxy to that worker address.
Step 4: V2Ray proxy in manual mode with JSON output
sudo routing-switch connect v2ray --no-tun --json
Note
V2Ray client runs, no system routing
Step 5: Xray VLESS proxy for manual configuration
sudo routing-switch connect xray-vless --no-tun
Step 6: Stop the proxy (works for both TUN and no-TUN modes)
sudo routing-switch disconnect
Scenario 20: CONFIGURATION EXPORT AND DISPLAY
Export and display protocol configurations
Step 1: Export all configurations to default location
routing-switch export-config
Note
Creates timestamped config files
Step 2: Export specific protocol configuration
routing-switch export-config wireguard
Note
The file name is the protocol name, not a timestamped one: a re-export overwrites in place, and the previous generation is cleaned up rather than accumulated.
Step 3: Export the AmneziaWG profile
routing-switch export-config amneziawg
Note
Written as amneziawg.conf, WireGuard-shaped but NOT interchangeable with wireguard.conf: the body carries the nine obfuscation parameters (Jc/Jmin/Jmax/S1/S2/H1-H4) and needs awg-quick, not wg-quick. Feed it back with awg-quick, not with `connect amneziawg --config`, which is refused on purpose.
Step 4: Export the OpenVPN-over-Cloak profile
routing-switch export-config openvpn-cloak
Note
JSON, not a bare .ovpn, and that is deliberate. The inner OpenVPN body is rewritten at connect time to dial 127.0.0.1, so exported alone it is either useless or actively harmful: a user who 'repairs' it by pointing it back at the node connects with NO transport at all and loses the exact property they chose Cloak for. The exported object keeps the UID, the node public key and the real outer endpoint together with the inner body. It carries a per-user secret, so it is written owner-only.
Step 5: Export all configs to custom path
routing-switch export-config all --path /tmp/vpn-configs/
Note
Creates directory if it doesn't exist
Step 6: Export with credentials included
routing-switch export-config shadowsocks --include-credentials
Note
⚠️ WARNING: Contains sensitive passwords
Step 7: Export with JSON output showing results
routing-switch export-config --json
Step 8: Display WireGuard configuration
routing-switch showconfig wireguard
Note
Masks sensitive data by default
Step 9: Show all protocol configs in pretty JSON
routing-switch showconfig all --json-pretty
Step 10: Show config with passwords hidden
routing-switch showconfig dante --mask-sensitive
Note
Safe for sharing/logging
Step 11: Get Shadowsocks connection URL
routing-switch showconfigurl shadowsocks
Note
URL can be imported into mobile apps
Step 12: Get SOCKS5 URLs in JSON format
routing-switch showconfigurl dante --json
Step 13: Get URLs for all available protocols
routing-switch showconfigurl all
Step 14: Get the OpenVPN-over-Cloak profile as a single URL
routing-switch showconfigurl openvpn-cloak
Note
The URL carries the WHOLE Cloak object (UID, node public key, real outer endpoint, inner OpenVPN body), never the inner body alone, which would dial 127.0.0.1 and carry none of the transport identity. AmneziaWG gets its own amneziawg:// scheme for the same reason: emitting it as wireguard:// would lose the fact that it is a different protocol.
Step 15: Generate a QR code for the AmneziaWG config
routing-switch showconfigqr amneziawg
Note
Scan with an AmneziaWG mobile client; a stock WireGuard app cannot use it. `showconfigqr openvpn-cloak` is NOT supported and returns the same not-supported error as `showconfigqr openvpn`: an OpenVPN body with an inline <ca> block does not fit a scannable code. Use showconfigurl or export-config for Cloak.
Step 16: Generate QR code for WireGuard config
routing-switch showconfigqr wireguard
Note
Scan with WireGuard mobile app
Step 17: Generate IPv4 QR code for Shadowsocks (default)
routing-switch showconfigqr shadowsocks
Note
Shows IPv4 QR code by default for dual-stack protocols
Step 18: Generate IPv6 QR code for Shadowsocks
routing-switch showconfigqr shadowsocks --ipv6
Note
Use --ipv6 flag to show IPv6 QR for dual-stack protocols
Step 19: Generate QR without validation (faster)
routing-switch showconfigqr shadowsocks --skip-validation
Note
Skips automatic QR validation for debugging
Step 20: Generate all QR codes with strict validation
routing-switch showconfigqr all --strict-validation
Note
Fails if any QR code validation fails
Step 21: Get QR data in JSON format
routing-switch showconfigqr dante --json
Note
JSON includes the URL for QR generation
Step 22: Generate QR code and save as PNG file
routing-switch showconfigqr shadowsocks --save-files
Note
Saves clean PNG file: shadowsocks_ipv4.png
Step 23: Generate IPv6 QR code and save as PNG file
routing-switch showconfigqr shadowsocks --ipv6 --save-files
Note
Saves clean PNG file: shadowsocks_ipv6.png
Step 24: Generate both IPv4 and IPv6 QR codes
routing-switch showconfigqr shadowsocks --ipv4 --ipv6 --save-files
Note
Saves both shadowsocks_ipv4.png and shadowsocks_ipv6.png
Step 25: Generate all QR codes with pretty JSON output
routing-switch showconfigqr all --save-files --json-pretty
Note
Creates clean PNG files for all available protocols, supports all JSON formats
Step 26: Save QR file with human-enhanced JSON output
routing-switch showconfigqr wireguard --save-files --json-human
Note
VPN protocols use single filename (no IP version suffix)
Scenario 21: QR CODE VALIDATION
Validate QR codes against auth card
Step 1: Validate QR code from image file (NEW: direct filename)
routing-switch validate-qr shadowsocks_ipv4.png
Note
Smart detection: automatically finds file in current dir or results/qr-codes/
Step 2: Validate QR code from results/qr-codes directory
routing-switch validate-qr dante_ipv4.png
Note
Automatically looks in ./results/qr-codes/ if not found in current directory
Step 3: Validate QR code using explicit --file flag (legacy syntax)
routing-switch validate-qr --file shadowsocks_qr.png
Note
Both direct filename and --file flag work identically
Step 4: Validate QR URL from stdin
echo 'ss://...' | routing-switch validate-qr --stdin
Note
Useful for clipboard validation
Step 5: Validate all generated QR codes
routing-switch validate-qr all
Note
Checks all QR codes in results/qr-codes/
Step 6: Test QR code readability
routing-switch validate-qr --test-readability shadowsocks
Note
Round-trip test of QR generation
Step 7: JSON validation output
routing-switch validate-qr qr_code.png --json
Note
Machine-readable validation results
Scenario 22: ERROR RECOVERY
Recover from a broken or half-torn-down connection. reset, cleanup, recover and a plain disconnect are all auth-exempt on purpose: they have to work when the network (and therefore online-auth) is down.
Step 1: Force disconnect stuck connection
sudo routing-switch disconnect --force
Note
Use when normal disconnect fails
Step 2: Reset all routing to default
sudo routing-switch reset
Note
Emergency recovery command
Step 3: Reset routing even when the state file says something is still connected
sudo routing-switch reset --force
Note
DESTRUCTIVE: tears down the active tunnel, its routes and its DNS overrides without asking. Your traffic goes back to the clear-net default route, so you are NOT anonymised afterwards. Use only when a normal disconnect will not complete.
Step 4: Clean up orphaned processes
sudo routing-switch cleanup
Step 5: Deeper sweep: also removes leftover TUN devices, routes and iptables rules, not just stray processes
sudo routing-switch cleanup --thorough
Note
Heavier than plain cleanup and can disturb an active connection, so run it after disconnecting.
Step 6: Automatically diagnose and fix routing issues, restore network settings
sudo routing-switch recover
Note
Performs comprehensive recovery including cleanup, route restoration, and DNS reset
Step 7: Run the recovery even when routing-switch thinks nothing is wrong
sudo routing-switch recover --force
Note
DESTRUCTIVE: drops any active tunnel and restores the clear-net default route, so you lose VPN/Tor protection. This is the last-resort 'my internet is stuck' command.
Scenario 23: MICROSOCKS SERVER MODE
Turn this Kodachi box into a SOCKS5 proxy server so other devices on your LAN can ride its active tunnel. WORKFLOW: 1) connect routing-switch to any protocol (WireGuard, OpenVPN, V2Ray, Shadowsocks, Hysteria2, ...). 2) `microsocks-enable` with a username and password. 3) On the other device, set SOCKS5 host = this machine's LAN IP, port = the listening port (30050-30054), plus those credentials. All of that device's traffic then leaves through this machine's tunnel. microsocks-enable and microsocks-disable need root AND a prior online-auth login. microsocks-status is auth-exempt. SECURITY: the listener binds 0.0.0.0, so anything that can reach this host on that port can try to use it. Pick a strong password, and disable the server when you are done.
Step 1: Enable microsocks server with auto port detection
sudo routing-switch microsocks-enable -u microkodachi-8273 -p 'S@Cur9P@s@Wo-Ds'
Note
Automatically selects available port from 30050-30054 range. Used when Kodachi acts as a server. After connecting routing-switch to any service (WireGuard, V2Ray, etc.), enable microsocks so other PCs on your network can connect through this machine using the listening microsocks port. Strong credentials recommended for security.
Step 2: Enable with specific port
sudo routing-switch microsocks-enable -u microkodachi-8273 -p 'S@Cur9P@s@Wo-Ds' --port 30051
Note
Use when you need a specific port number within the 30050-30054 range
Step 3: Check microsocks server status
routing-switch microsocks-status
Note
Auth-exempt and no sudo needed. microsocks-enable writes results/microsocks-state.json mode 0664, and liveness is a /proc/<pid> existence check, which works across UIDs. Measured 2026-09-10 on 192.168.104.246 with the server running: root and unprivileged output were byte-identical, same pid, port, username and started_at.
Step 4: Check status in JSON format
routing-switch microsocks-status --json
Step 5: Stop microsocks server
sudo routing-switch microsocks-disable
Step 6: Complete server workflow: bring up a tunnel, then share it over SOCKS5
sudo routing-switch connect wireguard && sudo routing-switch microsocks-enable -u microkodachi-8273 -p 'S@Cur9P@s@Wo-Ds'
Note
The other device then points its SOCKS5 client at socks5://microkodachi-8273:<password>@<this-machine-LAN-IP>:30050 (for example 192.168.1.100:30050). Its traffic leaves through this machine's WireGuard tunnel. Order matters: enable microsocks AFTER the tunnel is up.
Scenario 24: VPNGATE FREE VPN
Use the free VPNGate public server pool. AUTH: browsing is auth-free (vpngate-fetch, vpngate-list, vpngate-export, vpngate-export-all all work on a fresh shell). `vpngate-connect` is NOT auth-free: it mutates routes, DNS and firewall exactly like `connect`, so it goes through the same online-auth gate and needs root. The servers themselves cost nothing, the auth gate is Kodachi's, not VPNGate's.
Step 1: Fetch VPNGate server list from public API
routing-switch vpngate-fetch
Note
Downloads and caches server list (refreshes every hour)
Step 2: List all cached VPNGate servers
routing-switch vpngate-list
Note
Shows servers sorted by score (default)
Step 3: List top 10 Japanese servers by speed
routing-switch vpngate-list --country JP --sort speed -l 10
Note
Filter by country name or code, sort by speed/ping/score/sessions
Step 4: List US servers sorted by lowest ping
routing-switch vpngate-list --country US --sort ping
Step 5: List the 10 least congested servers (fewest active VPN sessions)
routing-switch vpngate-list --sort sessions -l 10
Note
--sort accepts score (default, highest first), speed (highest first), ping (lowest first) and sessions (LOWEST first, i.e. least crowded).
Step 6: Connect to VPNGate server at index 5
sudo routing-switch vpngate-connect 5
Note
Uses OpenVPN with the public vpn/vpn credentials. REQUIRES AUTHENTICATION: unlike vpngate-fetch/list/export, this one establishes a connection, so it goes through the online-auth gate and needs root. Index comes from vpngate-list, so fetch and list first.
Step 7: Force connect to server 12 (disconnect existing first)
sudo routing-switch vpngate-connect 12 --force
Step 8: Connect without running the network prerequisite checks first
sudo routing-switch vpngate-connect 3 --skip-prerequisites
Note
Skips the IPv4-forwarding / NAT / MASQUERADE checks. Only use it if you know those are already correct: on a box that is not set up, the connection can come up half-broken.
Step 9: Fetch servers with JSON output
routing-switch vpngate-fetch --json
Step 10: List servers in pretty JSON format
routing-switch vpngate-list --json-pretty
Step 11: Export top server's OpenVPN config as .ovpn file
routing-switch vpngate-export 1
Note
Includes embedded vpn/vpn credentials for standalone use
Step 12: Export all cached servers as .ovpn files
routing-switch vpngate-export-all
Note
Bulk export for use in external OpenVPN clients
Step 13: Export server #5 config with JSON output
routing-switch vpngate-export 5 --json
Scenario 25: EXTERNAL VPN PROVIDERS
Browse, fetch, and connect through commercial and free third-party VPN providers (VPN Gate, Riseup, NordVPN, IVPN, PIA, Surfshark, AirVPN, Mullvad-WG). This is the largest surface in routing-switch: 20 verbs under `routing-switch providers`. Run `routing-switch providers --help` for the full list. AUTH: EVERY `providers` verb requires a prior online-auth login, including the read-only ones (list, list-profiles, get-profile). The catalog and the fetched configs are curated content, not open scrape targets. SUDO: any verb that writes the provider cache needs root, because the cache lives under dashboard/hooks/cache/vpn-providers/<id>/ which is root-owned in /opt. That is fetch, get-profile (it lazily fetches on a cache miss), import-config, delete-custom-profile, delete-custom-profiles-bulk, resolve-country, resolve-ip, resolve-ips, benchmark, clear-cache, credentials-set, credentials-delete, and all three connect verbs. Only `list`, `list-profiles`, `credentials-list`, `refresh-catalog` and `validate-config` are pure reads. COLONYOPS: profiles the user stars in the dashboard become runnable cells in the ColonyOps VPN Profiles store, each one a `providers connect <provider_id> <profile_id>` call. Only starred profiles that are ready to connect (logged in, cached, credentials saved) are offered there.
Step 1: Show every provider in the catalog with cache freshness
routing-switch providers list
Note
Reads dashboard/hooks/config/vpn-providers-public-api.json (user-editable)
Step 2: Same list in machine-readable JSON for the GUI / scripts
routing-switch providers list --json
Step 3: Fetch the live profile list for a provider into the cache
sudo routing-switch providers fetch vpngate
Note
Hits the provider's public endpoint. Cache lives at /opt/kodachi/dashboard/hooks/cache/vpn-providers/<id>/
Step 4: Bypass the per-provider cache TTL and always re-fetch
sudo routing-switch providers fetch vpngate --force
Note
Use this when you specifically want fresh data (e.g. after edits to the catalog endpoints).
Step 5: Browse cached profiles for a provider (table view)
routing-switch providers list-profiles vpngate
Step 6: Filter to top 5 Japanese profiles
routing-switch providers list-profiles vpngate --country jp --limit 5
Note
Country code is 2-letter ISO, lowercase.
Step 7: Filter a provider's profiles by transport protocol
routing-switch providers list-profiles nordvpn --protocol wireguard --limit 20
Note
--protocol (-p) is a substring match against the profile's transport: udp, tcp, openvpn, wireguard. Combine it with --country (-c) and --limit (-l).
Step 8: JSON form (the GUI's primary surface)
routing-switch providers list-profiles vpngate --json-pretty
Step 9: Dump a single profile's .ovpn content to stdout (or pipe to a file)
sudo routing-switch providers get-profile vpngate 1_219-100-37-203 > /tmp/jp.ovpn
Note
Needs root: on a cache miss it lazily fetches the profile and writes it into the root-owned provider cache. profile_id format is provider-specific, see `providers list-profiles --json`. The body is the actual OpenVPN config text, so you can feed it to `routing-switch connect openvpn --config /tmp/jp.ovpn`.
Step 10: Re-read the catalog JSON after editing it on disk
routing-switch providers refresh-catalog
Note
Use this after manually editing vpn-providers-public-api.json (add custom providers, change endpoints) without restarting anything.
Step 11: Connect using a profile previously fetched via `providers get-profile`
sudo routing-switch connect openvpn --config /tmp/jp.ovpn --force
Note
The catalog provides the profile metadata; the connect command does the actual handshake. For paid-tier providers, use `providers credentials-set <id>` first, then `providers connect <id> <profile_id>` which auto-injects auth-user-pass.
Step 12: Save NordVPN service credentials (separate from the dashboard login)
sudo routing-switch providers credentials-set nordvpn --field username=foo --field password=bar
Note
Stored at ~/.config/kodachi/vpn-credentials.json with mode 0600, values sealed with AES-256-GCM (machine-bound key). credentials-list shows which providers are configured.
Step 13: Show which providers have stored credentials (values are never printed)
routing-switch providers credentials-list
Step 14: Connect via a provider profile, auto-injecting saved credentials into auth-user-pass
sudo routing-switch providers connect nordvpn pl150-nordvpn-com_udp
Note
Equivalent to: get-profile -> patch auth-user-pass -> connect openvpn --config <tempfile>. Re-execs in the same routing-switch process so all the connect prerequisites still run.
Step 15: Phase 5: import your own .ovpn / .conf / JSON / YAML config as a custom profile
sudo routing-switch providers import-config --name 'My VPN' --file /tmp/my.ovpn
Note
Auto-detects OpenVPN / WireGuard / Shadowsocks / V2Ray / Hysteria2. Validation produces warnings, never blockers.
Step 16: Save the VPN account username/password for an imported OpenVPN profile (Proton VPN and most commercial providers)
sudo routing-switch providers credentials-set custom/my-vpn-20260522 --field username=foo --field password=bar
Note
Needed when the imported .ovpn has a bare `auth-user-pass` line. `connect custom <id>` then builds the auth-user-pass file automatically. The dashboard's Import panel does this for you.
Step 17: Import inline text with an explicit protocol hint (overrides auto-detect)
sudo routing-switch providers import-config --name 'WG Peer' --text "$(cat ~/wg.conf)" --protocol-hint wireguard
Note
Needs root: the imported profile is written into the root-owned custom-provider cache. --file and --text are mutually exclusive.
Step 18: Browse the configs you've imported
routing-switch providers list-profiles custom
Step 19: Remove a previously-imported custom profile
sudo routing-switch providers delete-custom-profile my-vpn-20260520143000
Note
Needs root (it removes files from the root-owned cache). Irreversible: the imported config body is gone, re-import it if you still need it.
Step 20: Delete several imported custom profiles in one root invocation
sudo routing-switch providers delete-custom-profiles-bulk --id my-vpn-20260520143000 --id work-vpn-20260601090000 --json
Note
--id is repeatable. Any credentials stored under custom/<id> are wiped with the profile. Irreversible. --id and --all are mutually exclusive.
Step 21: Delete EVERY imported custom profile
sudo routing-switch providers delete-custom-profiles-bulk --all --json
Note
DESTRUCTIVE and irreversible: wipes every config you ever imported, plus their stored credentials. There is no confirmation prompt. This is what the dashboard's 'Delete all' bulk action calls.
Step 22: Delete the stored credentials for one provider
sudo routing-switch providers credentials-delete nordvpn
Note
Only removes the credentials, the cached profiles stay (use `providers clear-cache <id>` for those). After this, `providers connect nordvpn <profile>` fails until you run credentials-set again. For an imported profile the id is the custom/<profile_id> form.
Step 23: CV-3 dry-run: preview detected protocol + endpoint + warnings without writing to cache
routing-switch providers validate-config --text "vless://uuid@example.com:8443?type=tcp#NY" --json
Note
Validates URI schemes (vmess/vless/trojan/ss/hysteria2/tuic), Clash YAML, sing-box JSON, and plain OpenVPN/WireGuard bodies. Always warnings, never blockers.
Step 24: Look up the country for a cached profile via ip-fetch (skips if already tagged)
sudo routing-switch providers resolve-country riseup vpn12-nyc_udp_1194
Note
Pass --force to re-verify even if a country is already set (Verify mode).
Step 25: DNS-resolve the profile's hostname to an IPv4 and store in remote_ip
sudo routing-switch providers resolve-ip riseup vpn12-nyc_udp_1194
Note
Uses `getent hosts` for resolution so it honors /etc/hosts overrides.
Step 26: Bulk DNS-resolve every cached profile in a provider that's missing an IP
sudo routing-switch providers resolve-ips riseup --concurrency 8
Note
Bounded parallelism via tokio::sync::Semaphore so we don't hammer the resolver.
Step 27: Pick a random profile (optionally filtered by country) and connect
sudo routing-switch providers connect-random vpngate --country jp --force
Note
Useful for VPN Gate where load is largely uniform and randomness gives crowd-cover.
Step 28: Pick the fastest profile and connect (lowest measured latency if you've benchmarked; otherwise highest speed_bps)
sudo routing-switch providers connect-fastest vpngate --country jp --force
Note
Prefers latency_ms from `providers benchmark`. Without a benchmark, falls back to provider-reported speed_bps then lowest load.
Step 29: User-triggered latency probe: pings each cached server (ICMP, falling back to TCP-connect) and stores latency_ms. Manual only, same UX as ip-fetch's cache refresh.
sudo routing-switch providers benchmark vpngate --country jp --top 20 --concurrency 8 --timeout 3 --json
Note
Never auto-runs. `connect-fastest` will prefer benchmarked profiles once latency is stored.
Step 30: Drop the on-disk cache for one provider (index + configs/). Credentials are NOT touched.
sudo routing-switch providers clear-cache riseup --json
Note
Symmetric with `providers fetch`. Use --all to wipe every cached provider.
Step 31: Bulk wipe: remove every cached provider's index + configs in one shot
sudo routing-switch providers clear-cache --all --json
Note
Used by the dashboard "Clear all" bulk action. Idempotent.
Environment Variables
| Variable | Description | Default | Values |
|---|---|---|---|
RUST_LOG |
Set logging level (default: info) | info | error, warn, info, debug, trace |
Exit Codes
| Code | Description |
|---|---|
| 0 | Success |
| 1 | General error |
| 2 | Invalid arguments |
| 3 | Permission denied |