mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-13 12:35:05 +00:00
feat(remote): add --local-proxy to send server requests through the client
A reverse tunnel over the remote connection: the server's service traffic leaves through the client's own network. Only the client dials. Adds the tunnel-test command.
This commit is contained in:
@@ -146,10 +146,14 @@ hood the client walks a remote session through its lifecycle.
|
||||
`controld://<resolver>@dns.controld.com`. The server counts it as a full proxy
|
||||
URI and runs its own forwarder for it. A bare region skips Control D, because its
|
||||
proxy is a forwarder on the client. See
|
||||
[Control D](../../guide/proxies-and-vpn.md#control-d)
|
||||
[Control D](../../guide/proxies-and-vpn.md#control-d).
|
||||
The client also downloads playlists and segments through the same proxy,
|
||||
as a local run does. `--no-proxy-download` and `--proxy-download` change
|
||||
that for downloads only.
|
||||
- A `--local-proxy` goes as `tunnel:<id>`. The client opens
|
||||
`GET /api/tunnel` first, and the server replaces the ID with a loopback SOCKS5
|
||||
proxy that relays to the client's own connection. See
|
||||
[Send the server's requests through your machine](../../guide/proxies-and-vpn.md#send-the-servers-requests-through-your-machine).
|
||||
- Track-selection hints (`range_`, `vcodec`, `quality`, `best_available`,
|
||||
`generate_dv`) so the server fetches the right manifests
|
||||
- Your language and audio codec selection (`-l`, `-vl`, `-al`, `-a`, `-fs`)
|
||||
@@ -400,6 +404,11 @@ serve:
|
||||
gets a persistent per-account cache instead, so the account's tokens outlive the
|
||||
remote session. The server and the client both refuse a forwarded cache file that is not
|
||||
JSON or that names a type other than a date or time, and the service then authenticates again.
|
||||
- **A tunnel belongs to its API key.** The server accepts `tunnel:<id>` only from the API key
|
||||
that opened the tunnel. Its SOCKS5 proxy listens on loopback only, and it needs a username and
|
||||
password for that tunnel, so a raw `socks5h://127.0.0.1:<port>` proxy from a client fails.
|
||||
- **Only the client dials.** The server ignores a request from the client to open a
|
||||
connection, so a tunnel never gives a client access to the server's network.
|
||||
- **The server redacts secrets in logs.** It redacts remote session IDs, service tags,
|
||||
and other user values before it writes them to the log.
|
||||
|
||||
@@ -427,6 +436,8 @@ The server mounts all these routes, even in `--remote-only` mode. Paths use the
|
||||
| Method | Path | Purpose |
|
||||
|---|---|---|
|
||||
| `POST` | `/api/session/create` | Build + authenticate a service instance; returns a session ID immediately |
|
||||
| `GET` | `/api/tunnel` | WebSocket that relays the connections of a `tunnel:<id>` proxy to the client; `?id=` reconnects |
|
||||
| `GET` | `/api/tunnel/check?id=` | Exit IP address and lookup time through the caller's tunnel, for `unshackle tunnel-test` |
|
||||
| `GET` | `/api/session/{id}/titles` | Fetch and cache the title list |
|
||||
| `POST` | `/api/session/{id}/tracks` | Resolve tracks, manifests, chapters, headers/cookies for a title |
|
||||
| `POST` | `/api/session/{id}/segments` | Resolve per-segment/track download descriptors |
|
||||
|
||||
@@ -207,6 +207,7 @@ order the service used, then renumbers the episodes into the order you asked for
|
||||
| Flag | Description |
|
||||
|---|---|
|
||||
| `--proxy` | Proxy URI, a country or location code resolved from configured providers, or `provider:region` (e.g. `nordvpn:ca`, `gluetun:us`, `protonvpn:de:berlin`, `controld:yul`). |
|
||||
| `--local-proxy` | With `--remote`, send the server's service requests through your machine's own connection. Works with no other proxy option. Check it first with `unshackle tunnel-test`. See [Proxies & VPN](proxies-and-vpn.md#send-the-servers-requests-through-your-machine). |
|
||||
| `--no-proxy` | Force-disable all proxy use. |
|
||||
| `--no-proxy-download` | Bypass the proxy for **all downloads** (manifest, licence, and auth stay proxied). |
|
||||
| `--proxy-download` | Use a different proxy for **all downloads**, in the same forms as `--proxy` (manifest, licence, and auth stay on `--proxy`). |
|
||||
@@ -250,6 +251,7 @@ unshackle logs in to the service before the search. A service that declares a se
|
||||
|---|---|
|
||||
| `-p`, `--profile` | Profile for credentials and cookies. |
|
||||
| `--proxy` | Proxy URI, country or location code, or `provider:region` (e.g. `controld:ca`). |
|
||||
| `--local-proxy` | With `--remote`, send the server's search requests through your machine's own connection. Works with no other proxy option. |
|
||||
| `--no-proxy` | Force-disable all proxy use. |
|
||||
| `--remote` | Search on a remote unshackle server. The server logs in to the service. unshackle sends it your credentials, cookies and cache for the profile, and saves the cache that the server sends back. A service that searches with no login gets none of them. |
|
||||
| `--local` | Search with the local service code, also when the config sets `remote: true` for the service. |
|
||||
@@ -285,6 +287,24 @@ The export file can be a `mediaexport` file from `dl --export`, an export from a
|
||||
|
||||
---
|
||||
|
||||
## `tunnel-test`
|
||||
|
||||
Check `--local-proxy` before a real `--remote` run. The command finds the IP address that this
|
||||
machine exits from, opens a tunnel to the server, and makes the server look up its exit IP address
|
||||
through the tunnel. It stops at the first step that fails.
|
||||
|
||||
```
|
||||
unshackle tunnel-test [--server NAME]
|
||||
```
|
||||
|
||||
| Flag | Description |
|
||||
|---|---|
|
||||
| `--server` | Name of the remote server from `remote_services` config, if you configure more than one. |
|
||||
|
||||
See [Proxies & VPN](proxies-and-vpn.md#send-the-servers-requests-through-your-machine).
|
||||
|
||||
---
|
||||
|
||||
## `setup`
|
||||
|
||||
Install the external tools and make a first config.
|
||||
|
||||
@@ -22,11 +22,12 @@ a query to a real proxy URL: [basic static proxies](#basic-static-proxies),
|
||||
|
||||
## The `--proxy` flag
|
||||
|
||||
Four options on the `dl` command control proxying at download time:
|
||||
Five options on the `dl` command control proxying at download time:
|
||||
|
||||
| Option | Effect |
|
||||
|---|---|
|
||||
| `--proxy` | The proxy to use. Either an explicit URI, or a query that unshackle resolves against your configured providers. |
|
||||
| `--local-proxy` | With `--remote`, send the server's service requests through your machine's own connection. Works with no other proxy option. See [Send the server's requests through your machine](#send-the-servers-requests-through-your-machine). |
|
||||
| `--no-proxy` | Force **all** proxy use off. No providers are initialised and no proxy query is resolved. |
|
||||
| `--no-proxy-download` | Use the proxy for the manifest, licence, and authentication, but bypass it for the **downloads** themselves. |
|
||||
| `--proxy-download` | Use `--proxy` for the manifest, licence, and authentication, and a different proxy for the **downloads**. Takes the same forms as `--proxy`. |
|
||||
@@ -204,6 +205,75 @@ sees your own IP, but the service does not.
|
||||
A `socks5://` proxy makes the DNS lookup of each host on your machine and gives no warning.
|
||||
Use `socks5h://` to make the proxy do the DNS lookups too.
|
||||
|
||||
### Send the server's requests through your machine
|
||||
|
||||
With `--remote`, the server sends the service requests, and they leave from the server's own
|
||||
connection. Add `--local-proxy` to send them through your machine's connection instead:
|
||||
|
||||
```shell
|
||||
unshackle dl --remote --local-proxy EXAMPLE 81234567
|
||||
```
|
||||
|
||||
A VPN app that covers your whole machine then also covers the server's requests, so the
|
||||
service sees your VPN's IP address. `--local-proxy` needs `--remote` (or a service with
|
||||
`remote: true`), and it works with no other proxy option: unshackle stops if you also give
|
||||
`--proxy`, `--no-proxy`, `--proxy-download` or `--no-proxy-download`. A proxy option from the `dl`
|
||||
config defaults does not count: `--local-proxy` turns it off for the run.
|
||||
|
||||
A `--proxy` on `localhost` or a loopback address, such as the local port of a VPN app, stops a
|
||||
`--remote` run with `That proxy is on your machine, so --remote cannot use it`. Connect the VPN
|
||||
app for the whole machine, then use `--local-proxy` without `--proxy`.
|
||||
|
||||
#### Test it first
|
||||
|
||||
`unshackle tunnel-test` checks the route before a real run. Add `--server <name>` to test a
|
||||
server other than the default one:
|
||||
|
||||
```shell
|
||||
unshackle tunnel-test
|
||||
```
|
||||
|
||||
It does three steps, and it stops at the first one that fails:
|
||||
|
||||
1. It looks up the IP address that your machine exits from.
|
||||
2. It opens a tunnel to the server.
|
||||
3. It makes the server look up its exit IP address through the tunnel. That address must be
|
||||
the same as in step 1, or in the same country when one lookup used IPv4 and the other IPv6.
|
||||
It fails when the lookup left from the server's own address. It also shows how long one
|
||||
lookup takes.
|
||||
|
||||
#### How the tunnel works
|
||||
|
||||
1. The client opens a WebSocket on the server, on the same host and port as the other
|
||||
remote session requests. Only a client opens a tunnel. The server never connects to
|
||||
a host for a client, so a tunnel gives no access to the server's network.
|
||||
2. The server gives the service a SOCKS5 proxy on its loopback address, with a username and
|
||||
password for that tunnel only. Another API key cannot use it.
|
||||
3. The server sends each connection that the service opens through the tunnel. The client
|
||||
connects to the host and relays the bytes.
|
||||
|
||||
The client logs `The server sends its requests through your connection on this machine`. You
|
||||
do not configure ports: the server picks a free one, and your
|
||||
machine opens none, because the client opens the connection to the server. A NAT router, a
|
||||
firewall, or a Cloudflare tunnel in front of the server does not stop it.
|
||||
|
||||
The service traffic stays encrypted from the server to the service, so the client relays only
|
||||
encrypted bytes. The client refuses to connect to `localhost`, and to a host name or IP address
|
||||
that resolves only to a loopback, private or link-local address, so the server cannot reach
|
||||
your local network.
|
||||
|
||||
!!! note "Each request crosses the tunnel twice"
|
||||
A request from the server goes to your machine and then to the service, so it takes
|
||||
longer than a request that the server sends directly. The segments do not go through the
|
||||
tunnel: the client downloads them as before.
|
||||
|
||||
A service that uses a server account does not work with `--local-proxy`, because the server
|
||||
logs in with its own account. If the tunnel drops, the client connects again, and a new request
|
||||
from the server waits up to 10 seconds for it. A request that was in progress when the tunnel
|
||||
dropped fails. The server closes a tunnel when its client has not connected for 60 seconds, and
|
||||
the client then stops with `The tunnel to the server closed`. An API key can have 4 tunnels
|
||||
open at once.
|
||||
|
||||
## Basic (static proxies)
|
||||
|
||||
The `Basic` proxy provider is pure static configuration, with no accounts and no network
|
||||
|
||||
Reference in New Issue
Block a user