This runbook gives a proxy-aware application access to an existing WireGuard path without publishing a proxy port on the VPN server or the internet. The SOCKS daemon supplies the application interface, WireGuard supplies the already-approved IP path, and neither one authenticates the user for you. Each step below produces something you can inspect, and each has a rollback: stop the instance, remove the rule, or drop the application's proxy setting. Nothing here changes the host's default route.

The example assumes Dante 1.4.x installed as a dedicated, managed instance on a trusted Linux workstation, with its package-provided service account and logging configuration left in place. The workstation owns 10.77.0.2 on its WireGuard interface, reaches 10.60.0.20:443 through that tunnel, and the service's proper name is app.corp.example.

Step 1: bind the listener to loopback only

Put the network, method and rule sections into the instance's active configuration, replacing the example addresses. All server settings go before the rule blocks:

internal: 127.0.0.1 port = 1080
external: 10.77.0.2
external.protocol: ipv4
clientmethod: none
socksmethod: none

client pass {
    from: 127.0.0.1/32 to: 127.0.0.1/32
}

socks pass {
    from: 127.0.0.1/32 to: 10.60.0.20/32 port = 443
    command: connect
    protocol: tcp
}

This is a fragment, not a replacement for the package's user and logging settings. Pick an unused local port, and confirm this dedicated instance has no other listeners, no broader pass rules and no upstream chaining entries that would change the contract. If a previous config left a socks pass with no destination constraint, remove it before testing anything.

Rollback for this step is stopping the instance; the configuration file can stay on disk while you revert it.

Step 2: write two rules, not one

Dante's configuration reference gives the two rule types different jobs. The client rule admits a connection to the loopback listener, and its destination is the listener address itself. The SOCKS rule permits the requested onward connection to the approved host and port. Unmatched requests are blocked by default, which is why a missing rule looks identical to a broken route.

Note what this configuration deliberately does not do: it requests no SOCKS password. That suits a trusted local host, and it is not user authentication. Any other process on that machine can use loopback too. Keep the remote application's own authentication in place, and do not reuse this unauthenticated shape for untrusted local users or a LAN-facing listener.

Step 3: verify the route from the right source

external selects an outgoing source address; it does not install a WireGuard route. Read-only lookup for the example source and destination:

ip -4 route get 10.60.0.20 from 10.77.0.2

Run that in Dante's actual network namespace, not in whatever shell you happen to have open. The route, the WireGuard peer selection, the remote-side permission and the return path all have to fit that source address. A successful lookup is necessary and not sufficient, because it says nothing about whether the far end accepts the request.

Resist the temptation to add a default route so the lookup succeeds. The proxy port exists on this workstation only; changing the host's default route to create it inverts the whole design.

Step 4: test with the intended identity

After the owner validates the installed configuration and starts the instance through its service manager, an illustrative request is:

curl --proxy socks5h://127.0.0.1:1080 --noproxy '' https://app.corp.example/

With socks5h, Dante performs destination resolution, but Dante runs on this workstation, so the setting does not send DNS to the far end of the tunnel by itself. The approved resolver that Dante uses must return the permitted address for that name. The empty no-proxy list stops an inherited exception from quietly bypassing SOCKS.

Preserve HTTPS hostname and certificate validation in the test, then inspect the actual listener and confirm both halves of the contract: the permitted request succeeds and an excluded destination fails. Also verify that unsupported forwarding commands stay denied, because this fragment permits the SOCKS CONNECT command over TCP and nothing resembling a general UDP or whole-device tunnel.

Step 5: decide what happens when the tunnel drops

Test tunnel loss and instance restart before you call this production. A supervisor that starts Dante after WireGuard does not create fail-closed routing, and it does not create fail-closed DNS either; both have to be enforced through the network owner. Watch what the application does when the tunnel is down: a clean error is a good outcome, a silent fallback to a public resolver is not.

Coordinate updates if the bound tunnel address changes, because external is pinned to it. When the arrangement is no longer needed, retire this instance and the application's proxy setting together, and leave the WireGuard path to whoever owns it.

អត្ថបទពាក់ព័ន្ធ