feat(cli): make connect-url --relay a full anywhere pairing link
- --relay links now carry both routes: direct LAN plus relay fallback, matching the UI's Anywhere pairing; devices prefer the direct route - pairing sessions created by the CLI are marked with usesRelay, and the server reconciles relay demand on a timer, so a headless instance brings the relay up on its own after connect-url --relay - warn with LAN_UNREACHABLE when the link's direct route points at loopback and other devices cannot use it - document the --relay flow and the --lan binding caveat in Connect a Device and Remote Instances across all locales
This commit is contained in:
@@ -40,13 +40,25 @@ The same physical device keeps one entry even if it signs in again later — you
|
||||
|
||||
## Connect from the command line
|
||||
|
||||
If the server runs headless (no UI open), create a connection link from a terminal on that machine:
|
||||
If the server runs headless (no UI open), create a connection link from a terminal on that machine.
|
||||
|
||||
For a device on the same network:
|
||||
|
||||
```bash
|
||||
openchamber connect-url --port 3000 --qr
|
||||
```
|
||||
|
||||
The printed link and QR code work exactly like the ones from the settings dialog.
|
||||
For a device that should connect from **anywhere** — the equivalent of picking **Anywhere** in the dialog:
|
||||
|
||||
```bash
|
||||
openchamber connect-url --relay --qr
|
||||
```
|
||||
|
||||
A `--relay` link carries both routes, just like the dialog: the device connects directly over your local network when it can reach the server, and falls back to the [Private Relay](/private-relay/) when away. The relay starts on its own: a running instance picks the link up within a minute, a stopped one on its next launch.
|
||||
|
||||
> The direct route only works if the server actually listens on your network. By default OpenChamber listens on the machine itself only — start it with `--lan` to make it reachable over Wi-Fi. The command warns you (`[LAN_UNREACHABLE]`) when the link's direct route won't be usable from other devices; a `--relay` link still works then, just always through the relay.
|
||||
|
||||
The printed link and QR code work exactly like the ones from the settings dialog — single-use, expiring, revocable.
|
||||
|
||||
## Related
|
||||
|
||||
|
||||
@@ -40,13 +40,25 @@ El mismo dispositivo físico mantiene una sola entrada aunque vuelva a iniciar s
|
||||
|
||||
## Conecta desde la línea de comandos
|
||||
|
||||
Si el servidor funciona en modo headless (sin UI abierta), crea un enlace de conexión desde una terminal en esa máquina:
|
||||
Si el servidor funciona en modo headless (sin UI abierta), crea un enlace de conexión desde una terminal en esa máquina.
|
||||
|
||||
Para un dispositivo en la misma red:
|
||||
|
||||
```bash
|
||||
openchamber connect-url --port 3000 --qr
|
||||
```
|
||||
|
||||
El enlace y el código QR impresos funcionan exactamente igual que los del diálogo de ajustes.
|
||||
Para un dispositivo que debe conectarse desde **cualquier lugar** —el equivalente a elegir **En cualquier lugar** en el diálogo—:
|
||||
|
||||
```bash
|
||||
openchamber connect-url --relay --qr
|
||||
```
|
||||
|
||||
Un enlace `--relay` lleva ambas rutas, igual que el diálogo: el dispositivo se conecta directamente por tu red local cuando puede alcanzar el servidor, y recurre al [Private Relay](/es/private-relay/) cuando está fuera. El relay arranca por sí solo: una instancia en marcha recoge el enlace en menos de un minuto, y una detenida lo hace en su próximo arranque.
|
||||
|
||||
> La ruta directa solo funciona si el servidor realmente escucha en tu red. De forma predeterminada, OpenChamber solo escucha en la propia máquina; inícialo con `--lan` para que sea accesible por Wi-Fi. El comando te avisa (`[LAN_UNREACHABLE]`) cuando la ruta directa del enlace no será utilizable desde otros dispositivos; un enlace `--relay` sigue funcionando en ese caso, solo que siempre a través del relay.
|
||||
|
||||
El enlace y el código QR impresos funcionan exactamente igual que los del diálogo de ajustes: de un solo uso, con caducidad y revocables.
|
||||
|
||||
## Relacionado
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ También puedes crear un enlace desde una terminal en la máquina remota:
|
||||
openchamber connect-url --port 3000 --server http://your-host:3000 --qr
|
||||
```
|
||||
|
||||
`connect-url` inicia el servidor primero si no hay nada ejecutándose en ese puerto. Añade `--api-only` para un servidor headless, `--lan` para escuchar en la LAN al iniciar, `--ui-password` para proteger el acceso del navegador y `--name` para etiquetar la conexión guardada.
|
||||
`connect-url` inicia el servidor primero si no hay nada ejecutándose en ese puerto. Añade `--api-only` para un servidor headless, `--lan` para escuchar en la LAN al iniciar, `--ui-password` para proteger el acceso del navegador y `--name` para etiquetar la conexión guardada. Añade `--relay` para un enlace que también funciona fuera de la red local: el dispositivo prefiere la conexión directa cuando el servidor está accesible y recurre al [Private Relay](/es/private-relay/) en caso contrario; la instancia levanta el relay por sí sola.
|
||||
|
||||
El enlace generado contiene un secreto de vinculación de un solo uso. Una vez importado, el dispositivo conserva su propio token de cliente —independiente de la contraseña de la UI del navegador— que sobrevive a los reinicios del servidor hasta que lo revoques en el servidor emisor.
|
||||
|
||||
|
||||
@@ -40,13 +40,25 @@ Le même appareil physique garde une seule entrée même s’il se reconnecte pl
|
||||
|
||||
## Se connecter depuis la ligne de commande
|
||||
|
||||
Si le serveur tourne en headless (aucune UI ouverte), créez un lien de connexion depuis un terminal sur cette machine :
|
||||
Si le serveur tourne en headless (aucune UI ouverte), créez un lien de connexion depuis un terminal sur cette machine.
|
||||
|
||||
Pour un appareil sur le même réseau :
|
||||
|
||||
```bash
|
||||
openchamber connect-url --port 3000 --qr
|
||||
```
|
||||
|
||||
Le lien et le QR code affichés fonctionnent exactement comme ceux du dialogue des paramètres.
|
||||
Pour un appareil qui doit se connecter depuis **n’importe où** — l’équivalent du choix **Partout** dans le dialogue :
|
||||
|
||||
```bash
|
||||
openchamber connect-url --relay --qr
|
||||
```
|
||||
|
||||
Un lien `--relay` contient les deux routes, exactement comme le dialogue : l’appareil se connecte directement via votre réseau local quand il peut joindre le serveur, et bascule sur le [Relais privé](/private-relay/) en déplacement. Le relais démarre tout seul : une instance en cours d’exécution prend le lien en compte en moins d’une minute, une instance arrêtée au prochain lancement.
|
||||
|
||||
> La route directe ne fonctionne que si le serveur écoute réellement sur votre réseau. Par défaut, OpenChamber n’écoute que sur la machine elle-même — démarrez-le avec `--lan` pour le rendre joignable en Wi-Fi. La commande vous prévient (`[LAN_UNREACHABLE]`) quand la route directe du lien ne sera pas utilisable depuis d’autres appareils ; un lien `--relay` fonctionne quand même dans ce cas, simplement toujours via le relais.
|
||||
|
||||
Le lien et le QR code affichés fonctionnent exactement comme ceux du dialogue des paramètres — à usage unique, avec expiration, révocables.
|
||||
|
||||
## Pages liées
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ Vous pouvez aussi créer un lien depuis un terminal sur la machine distante :
|
||||
openchamber connect-url --port 3000 --server http://your-host:3000 --qr
|
||||
```
|
||||
|
||||
`connect-url` démarre d’abord le serveur si rien ne tourne sur ce port. Ajoutez `--api-only` pour un serveur headless, `--lan` pour écouter sur le LAN au démarrage, `--ui-password` pour protéger l’accès navigateur et `--name` pour nommer la connexion enregistrée.
|
||||
`connect-url` démarre d’abord le serveur si rien ne tourne sur ce port. Ajoutez `--api-only` pour un serveur headless, `--lan` pour écouter sur le LAN au démarrage, `--ui-password` pour protéger l’accès navigateur et `--name` pour nommer la connexion enregistrée. Ajoutez `--relay` pour un lien qui fonctionne aussi hors du réseau local : l’appareil préfère la connexion directe quand elle est joignable et bascule sur le [Relais privé](/private-relay/) — l’instance active le relais toute seule.
|
||||
|
||||
Le lien généré contient un secret d’association à usage unique. Une fois importé, l’appareil détient son propre token client — séparé du mot de passe de l’UI navigateur — qui survit aux redémarrages du serveur jusqu’à révocation sur le serveur émetteur.
|
||||
|
||||
|
||||
@@ -42,11 +42,23 @@ description: 1 回限りの QR コードで、スマートフォン、デスク
|
||||
|
||||
サーバーがヘッドレス(UI を開いていない状態)で動いている場合は、そのマシンのターミナルから接続リンクを作成できます。
|
||||
|
||||
同じネットワーク上のデバイス用にはこちらです。
|
||||
|
||||
```bash
|
||||
openchamber connect-url --port 3000 --qr
|
||||
```
|
||||
|
||||
出力されるリンクと QR コードは、設定ダイアログから作成したものとまったく同じように機能します。
|
||||
**どこからでも**接続するデバイス用 — ダイアログで **どこでも** を選ぶのと同等 — にはこちらです。
|
||||
|
||||
```bash
|
||||
openchamber connect-url --relay --qr
|
||||
```
|
||||
|
||||
`--relay` リンクには、ダイアログと同様に両方の経路が含まれます。デバイスはサーバーに到達できるときはローカルネットワーク経由で直接接続し、外出先では [Private Relay](/private-relay/) にフォールバックします。リレーは自動的に起動します。実行中のインスタンスは 1 分以内にリンクを拾い、停止中のインスタンスは次回の起動時に拾います。
|
||||
|
||||
> 直接経路は、サーバーが実際にネットワーク上で待ち受けている場合にのみ機能します。デフォルトでは OpenChamber はそのマシン上でのみ待ち受けます。Wi-Fi 経由で到達できるようにするには `--lan` を付けて起動してください。リンクの直接経路が他のデバイスから使えない場合、コマンドは警告(`[LAN_UNREACHABLE]`)を表示します。その場合でも `--relay` リンクは機能しますが、常にリレー経由になります。
|
||||
|
||||
出力されるリンクと QR コードは、設定ダイアログから作成したものとまったく同じように機能します — 1 回限りで、期限切れになり、無効化できます。
|
||||
|
||||
## 関連
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ SSH と UI のパスワードを保存するか、毎回入力するかを選べ
|
||||
openchamber connect-url --port 3000 --server http://your-host:3000 --qr
|
||||
```
|
||||
|
||||
`connect-url` は、そのポートで何も実行されていなければ先にサーバーを起動します。ヘッドレスサーバーには `--api-only`、起動時に LAN にバインドするには `--lan`、ブラウザアクセスを保護するには `--ui-password`、保存接続にラベルを付けるには `--name` を追加します。
|
||||
`connect-url` は、そのポートで何も実行されていなければ先にサーバーを起動します。ヘッドレスサーバーには `--api-only`、起動時に LAN にバインドするには `--lan`、ブラウザアクセスを保護するには `--ui-password`、保存接続にラベルを付けるには `--name` を追加します。ローカルネットワークの外でも使えるリンクには `--relay` を追加します。デバイスは到達可能なときは直接接続を優先し、外出先では [Private Relay](/private-relay/) にフォールバックします。リレーはインスタンスが自動的に立ち上げます。
|
||||
|
||||
生成されたリンクには 1 回限りのペアリングシークレットが含まれます。インポートすると、デバイスは専用のクライアントトークンを保持します。これはブラウザ UI パスワードとは別で、発行元サーバーで無効化するまでサーバー再起動後も残ります。
|
||||
|
||||
|
||||
@@ -40,13 +40,25 @@ description: 일회용 QR 코드로 휴대폰, 데스크톱, 다른 브라우저
|
||||
|
||||
## 명령줄에서 연결하기
|
||||
|
||||
서버가 headless(UI가 열려 있지 않음)로 실행 중이면 그 컴퓨터의 터미널에서 연결 링크를 만드세요:
|
||||
서버가 headless(UI가 열려 있지 않음)로 실행 중이면 그 컴퓨터의 터미널에서 연결 링크를 만드세요.
|
||||
|
||||
같은 네트워크의 기기라면:
|
||||
|
||||
```bash
|
||||
openchamber connect-url --port 3000 --qr
|
||||
```
|
||||
|
||||
출력된 링크와 QR 코드는 설정 대화 상자에서 만든 것과 똑같이 작동합니다.
|
||||
**어디서든** 연결해야 하는 기기라면(대화 상자에서 **어디서나**를 선택하는 것과 동일):
|
||||
|
||||
```bash
|
||||
openchamber connect-url --relay --qr
|
||||
```
|
||||
|
||||
`--relay` 링크에는 대화 상자와 마찬가지로 두 경로가 모두 들어 있습니다. 기기가 서버에 도달할 수 있으면 로컬 네트워크로 직접 연결하고, 밖에 있으면 [Private Relay](/ko/private-relay/)로 대체합니다. 릴레이는 스스로 시작됩니다. 실행 중인 인스턴스는 1분 안에 링크를 인식하고, 멈춰 있는 인스턴스는 다음 실행 시 인식합니다.
|
||||
|
||||
> 직접 경로는 서버가 실제로 네트워크에서 수신 대기할 때만 작동합니다. 기본적으로 OpenChamber는 그 컴퓨터 자체에서만 수신 대기하므로, Wi-Fi에서 접근할 수 있게 하려면 `--lan`으로 시작하세요. 링크의 직접 경로를 다른 기기에서 사용할 수 없는 경우 명령이 경고(`[LAN_UNREACHABLE]`)를 표시합니다. 이때도 `--relay` 링크는 여전히 작동하며, 항상 릴레이를 통해 연결될 뿐입니다.
|
||||
|
||||
출력된 링크와 QR 코드는 설정 대화 상자에서 만든 것과 똑같이 작동합니다. 일회용이고, 만료되며, 해지할 수 있습니다.
|
||||
|
||||
## 관련 항목
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ SSH 및 UI 비밀번호를 저장할지, 매번 입력할지 결정합니다.
|
||||
openchamber connect-url --port 3000 --server http://your-host:3000 --qr
|
||||
```
|
||||
|
||||
해당 포트에 서버가 없으면 `connect-url`이 먼저 서버를 시작합니다. Headless 서버에는 `--api-only`, 시작 시 LAN에 바인딩하려면 `--lan`, 브라우저 접근 보호에는 `--ui-password`, 저장된 연결 이름에는 `--name`을 사용하세요.
|
||||
해당 포트에 서버가 없으면 `connect-url`이 먼저 서버를 시작합니다. Headless 서버에는 `--api-only`, 시작 시 LAN에 바인딩하려면 `--lan`, 브라우저 접근 보호에는 `--ui-password`, 저장된 연결 이름에는 `--name`을 사용하세요. 로컬 네트워크 밖에서도 작동하는 링크가 필요하면 `--relay`를 추가하세요. 기기는 도달 가능할 때 직접 연결을 우선하고, 밖에서는 [Private Relay](/ko/private-relay/)로 대체합니다. 인스턴스가 릴레이를 알아서 올립니다.
|
||||
|
||||
생성된 링크에는 일회용 페어링 시크릿이 들어 있습니다. 한 번 가져오면 기기는 브라우저 UI 비밀번호와 별개인 고유 client token을 갖게 되며, 발급한 서버에서 해지하기 전까지 서버 재시작 후에도 유지됩니다.
|
||||
|
||||
|
||||
@@ -40,13 +40,25 @@ To samo fizyczne urządzenie zachowuje jeden wpis, nawet jeśli zaloguje się po
|
||||
|
||||
## Połącz z wiersza poleceń
|
||||
|
||||
Jeśli serwer działa headless (bez otwartego UI), utwórz link połączenia z terminala na tej maszynie:
|
||||
Jeśli serwer działa headless (bez otwartego UI), utwórz link połączenia z terminala na tej maszynie.
|
||||
|
||||
Dla urządzenia w tej samej sieci:
|
||||
|
||||
```bash
|
||||
openchamber connect-url --port 3000 --qr
|
||||
```
|
||||
|
||||
Wypisany link i kod QR działają dokładnie tak samo jak te z okna ustawień.
|
||||
Dla urządzenia, które ma łączyć się **z dowolnego miejsca** — odpowiednik wybrania opcji **Wszędzie** w oknie dialogowym:
|
||||
|
||||
```bash
|
||||
openchamber connect-url --relay --qr
|
||||
```
|
||||
|
||||
Link `--relay` zawiera obie trasy, dokładnie jak okno dialogowe: urządzenie łączy się bezpośrednio przez sieć lokalną, gdy może dotrzeć do serwera, a poza domem przełącza się na [Private Relay](/pl/private-relay/). Relay uruchamia się sam: działająca instancja podejmuje link w ciągu minuty, a zatrzymana — przy następnym starcie.
|
||||
|
||||
> Trasa bezpośrednia działa tylko wtedy, gdy serwer rzeczywiście nasłuchuje w Twojej sieci. Domyślnie OpenChamber nasłuchuje wyłącznie na samej maszynie — uruchom go z `--lan`, aby był osiągalny przez Wi-Fi. Polecenie ostrzega (`[LAN_UNREACHABLE]`), gdy trasa bezpośrednia linku nie będzie użyteczna z innych urządzeń; link `--relay` nadal wtedy działa, tyle że zawsze przez relay.
|
||||
|
||||
Wypisany link i kod QR działają dokładnie tak samo jak te z okna ustawień — są jednorazowe, wygasają i można je unieważnić.
|
||||
|
||||
## Powiązane
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ Link możesz też utworzyć z terminala na zdalnej maszynie:
|
||||
openchamber connect-url --port 3000 --server http://your-host:3000 --qr
|
||||
```
|
||||
|
||||
`connect-url` najpierw uruchamia serwer, jeśli nic nie działa na tym porcie. Dodaj `--api-only` dla serwera headless, `--lan` aby nasłuchiwać w LAN przy starcie, `--ui-password` aby chronić dostęp z przeglądarki oraz `--name` aby nazwać zapisane połączenie.
|
||||
`connect-url` najpierw uruchamia serwer, jeśli nic nie działa na tym porcie. Dodaj `--api-only` dla serwera headless, `--lan` aby nasłuchiwać w LAN przy starcie, `--ui-password` aby chronić dostęp z przeglądarki oraz `--name` aby nazwać zapisane połączenie. Dodaj `--relay`, aby link działał także poza siecią lokalną: urządzenie preferuje połączenie bezpośrednie, gdy serwer jest osiągalny, a w przeciwnym razie przełącza się na [Private Relay](/pl/private-relay/) — instancja sama uruchomi relay.
|
||||
|
||||
Wygenerowany link zawiera jednorazowy sekret parowania. Po zaimportowaniu urządzenie ma własny token klienta — osobny od hasła UI w przeglądarce — który przetrwa restarty serwera, dopóki nie unieważnisz go na serwerze, który go wydał.
|
||||
|
||||
|
||||
@@ -40,13 +40,25 @@ O mesmo dispositivo físico mantém uma única entrada mesmo que entre de novo m
|
||||
|
||||
## Conectar pela linha de comando
|
||||
|
||||
Se o servidor roda headless (sem UI aberta), crie um link de conexão a partir de um terminal nessa máquina:
|
||||
Se o servidor roda headless (sem UI aberta), crie um link de conexão a partir de um terminal nessa máquina.
|
||||
|
||||
Para um dispositivo na mesma rede:
|
||||
|
||||
```bash
|
||||
openchamber connect-url --port 3000 --qr
|
||||
```
|
||||
|
||||
O link e o código QR impressos funcionam exatamente como os do diálogo de configurações.
|
||||
Para um dispositivo que deve conectar de **qualquer lugar** — o equivalente a escolher **Em qualquer lugar** no diálogo:
|
||||
|
||||
```bash
|
||||
openchamber connect-url --relay --qr
|
||||
```
|
||||
|
||||
Um link com `--relay` carrega as duas rotas, igual ao diálogo: o dispositivo conecta diretamente pela sua rede local quando consegue alcançar o servidor e recorre ao [Private Relay](/pt-br/private-relay/) quando está fora. O relay inicia sozinho: uma instância em execução capta o link em até um minuto; uma parada, na próxima vez que iniciar.
|
||||
|
||||
> A rota direta só funciona se o servidor de fato escutar na sua rede. Por padrão, o OpenChamber escuta apenas na própria máquina — inicie-o com `--lan` para torná-lo alcançável pelo Wi-Fi. O comando avisa (`[LAN_UNREACHABLE]`) quando a rota direta do link não será utilizável de outros dispositivos; um link com `--relay` ainda funciona nesse caso, só que sempre pelo relay.
|
||||
|
||||
O link e o código QR impressos funcionam exatamente como os do diálogo de configurações — de uso único, com expiração e revogáveis.
|
||||
|
||||
## Relacionado
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ Você também pode criar um link a partir de um terminal na máquina remota:
|
||||
openchamber connect-url --port 3000 --server http://your-host:3000 --qr
|
||||
```
|
||||
|
||||
`connect-url` inicia o servidor primeiro se nada estiver rodando nessa porta. Adicione `--api-only` para um servidor headless, `--lan` para escutar na LAN ao iniciar, `--ui-password` para proteger o acesso pelo navegador e `--name` para nomear a conexão salva.
|
||||
`connect-url` inicia o servidor primeiro se nada estiver rodando nessa porta. Adicione `--api-only` para um servidor headless, `--lan` para escutar na LAN ao iniciar, `--ui-password` para proteger o acesso pelo navegador e `--name` para nomear a conexão salva. Adicione `--relay` para um link que também funciona fora da rede local: o dispositivo prefere a conexão direta quando alcançável e recorre ao [Private Relay](/pt-br/private-relay/) — a instância liga o relay sozinha.
|
||||
|
||||
O link gerado contém um segredo de pareamento de uso único. Depois de importado, o dispositivo passa a ter o próprio token de cliente — separado da senha de UI do navegador — que sobrevive a reinícios do servidor até você revogá-lo no servidor emissor.
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ You can also create a link from a terminal on the remote machine:
|
||||
openchamber connect-url --port 3000 --server http://your-host:3000 --qr
|
||||
```
|
||||
|
||||
`connect-url` starts the server first if nothing is running on that port. Add `--api-only` for a headless server, `--lan` to bind to the LAN when starting, `--ui-password` to protect browser access, and `--name` to label the saved connection.
|
||||
`connect-url` starts the server first if nothing is running on that port. Add `--api-only` for a headless server, `--lan` to bind to the LAN when starting, `--ui-password` to protect browser access, and `--name` to label the saved connection. Add `--relay` for a link that also works away from the local network: the device prefers the direct connection when reachable and falls back to the [Private Relay](/private-relay/) — the instance brings the relay up on its own.
|
||||
|
||||
The generated link contains a single-use pairing secret. Once imported, the device holds its own client token — separate from the browser UI password — which survives server restarts until you revoke it on the issuing server.
|
||||
|
||||
|
||||
@@ -40,13 +40,25 @@ description: Зв'яжіть телефон, десктоп чи інший бр
|
||||
|
||||
## Підключення з командного рядка
|
||||
|
||||
Якщо сервер працює headless (без відкритого UI), створіть посилання для підключення з термінала на тій машині:
|
||||
Якщо сервер працює headless (без відкритого UI), створіть посилання для підключення з термінала на тій машині.
|
||||
|
||||
Для пристрою в тій самій мережі:
|
||||
|
||||
```bash
|
||||
openchamber connect-url --port 3000 --qr
|
||||
```
|
||||
|
||||
Надруковані посилання та QR-код працюють точнісінько як ті, що з діалогу налаштувань.
|
||||
Для пристрою, який має підключатися **звідусіль** — еквівалент вибору **Будь-де** в діалозі:
|
||||
|
||||
```bash
|
||||
openchamber connect-url --relay --qr
|
||||
```
|
||||
|
||||
Посилання з `--relay` містить обидва маршрути, як і діалог: пристрій підключається напряму через вашу локальну мережу, коли може дістатися сервера, і переходить на [Private Relay](/uk/private-relay/), коли ви не вдома. Relay запускається сам: запущений інстанс підхоплює посилання протягом хвилини, зупинений — при наступному запуску.
|
||||
|
||||
> Прямий маршрут працює лише тоді, коли сервер справді слухає вашу мережу. За замовчуванням OpenChamber слухає тільки саму машину — запустіть його з `--lan`, щоб він був доступний через Wi-Fi. Команда попереджає (`[LAN_UNREACHABLE]`), коли прямим маршрутом посилання не зможуть скористатися інші пристрої; посилання з `--relay` тоді все одно працює, просто завжди через relay.
|
||||
|
||||
Надруковані посилання та QR-код працюють точнісінько як ті, що з діалогу налаштувань — одноразові, зі строком дії, з можливістю відкликання.
|
||||
|
||||
## Пов'язане
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ OpenChamber проходить через кроки — перевірку з'
|
||||
openchamber connect-url --port 3000 --server http://your-host:3000 --qr
|
||||
```
|
||||
|
||||
`connect-url` спочатку запускає сервер, якщо на цьому порту нічого не працює. Додайте `--api-only` для headless-сервера, `--lan` для LAN bind під час старту, `--ui-password` для захисту browser access і `--name` для назви збереженого підключення.
|
||||
`connect-url` спочатку запускає сервер, якщо на цьому порту нічого не працює. Додайте `--api-only` для headless-сервера, `--lan` для LAN bind під час старту, `--ui-password` для захисту browser access і `--name` для назви збереженого підключення. Додайте `--relay`, щоб посилання працювало й поза локальною мережею: пристрій віддає перевагу прямому підключенню, коли сервер доступний, і переходить на [Private Relay](/uk/private-relay/) — інстанс піднімає relay сам.
|
||||
|
||||
Згенероване посилання містить одноразовий секрет зв'язування. Після імпорту пристрій отримує власний client token — окремий від пароля browser UI, — який зберігається після рестартів сервера, доки ви не відкличете його на сервері, що його видав.
|
||||
|
||||
|
||||
@@ -40,13 +40,25 @@ description: 通过一次性二维码,把你的手机、桌面应用或另一
|
||||
|
||||
## 从命令行连接
|
||||
|
||||
如果服务器以 headless 方式运行(没有打开 UI),可以在那台机器的终端里创建连接链接:
|
||||
如果服务器以 headless 方式运行(没有打开 UI),可以在那台机器的终端里创建连接链接。
|
||||
|
||||
针对同一网络中的设备:
|
||||
|
||||
```bash
|
||||
openchamber connect-url --port 3000 --qr
|
||||
```
|
||||
|
||||
打印出的链接和二维码与设置对话框里生成的完全一样。
|
||||
针对需要从**任何地方**连接的设备 — 相当于在对话框中选择 **任何地方**:
|
||||
|
||||
```bash
|
||||
openchamber connect-url --relay --qr
|
||||
```
|
||||
|
||||
`--relay` 链接与对话框一样同时携带两条路由:当设备能访问服务器时,通过你的本地网络直接连接;外出时则回退到 [Private Relay](/zh-cn/private-relay/)。中继会自行启动:正在运行的实例会在一分钟内接管该链接,已停止的实例则会在下次启动时接管。
|
||||
|
||||
> 直连路由只有在服务器确实监听你的网络时才有效。默认情况下 OpenChamber 只监听本机 — 用 `--lan` 启动它,才能通过 Wi-Fi 访问。当链接的直连路由无法被其他设备使用时,命令会发出警告(`[LAN_UNREACHABLE]`);此时 `--relay` 链接仍然可用,只是始终通过中继连接。
|
||||
|
||||
打印出的链接和二维码与设置对话框里生成的完全一样 — 一次性使用、会过期、可撤销。
|
||||
|
||||
## 相关内容
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ OpenChamber 会引导你完成各个步骤 — 检查连接、设置远程、启
|
||||
openchamber connect-url --port 3000 --server http://your-host:3000 --qr
|
||||
```
|
||||
|
||||
如果该端口上没有服务器,`connect-url` 会先启动服务器。使用 `--api-only` 可启动 headless 服务器,`--lan` 可在启动时绑定到 LAN,`--ui-password` 可保护浏览器访问,`--name` 可为保存的连接命名。
|
||||
如果该端口上没有服务器,`connect-url` 会先启动服务器。使用 `--api-only` 可启动 headless 服务器,`--lan` 可在启动时绑定到 LAN,`--ui-password` 可保护浏览器访问,`--name` 可为保存的连接命名。加上 `--relay` 可生成一条在本地网络之外也能使用的链接:设备在可达时优先直连,否则回退到 [Private Relay](/zh-cn/private-relay/) — 实例会自行启动中继。
|
||||
|
||||
生成的链接包含一个一次性配对密钥。导入后,设备会持有自己的 client token — 独立于浏览器 UI 密码 — 它会在服务器重启后继续有效,直到你在签发它的服务器上撤销它。
|
||||
|
||||
|
||||
@@ -387,7 +387,7 @@ OPTIONS:
|
||||
--hostname Alias for --host outside tunnel commands
|
||||
--lan Bind to 0.0.0.0 for LAN access
|
||||
--server <url> Public/server URL for connect-url links
|
||||
--relay connect-url: generate an end-to-end-encrypted relay pairing link
|
||||
--relay connect-url: also include the end-to-end-encrypted relay transport
|
||||
--ui-password Protect browser UI with single password
|
||||
--api-only Start API routes only, without serving browser UI assets
|
||||
--foreground Run server in foreground (use with systemd/process managers)
|
||||
@@ -465,10 +465,11 @@ OPTIONS:
|
||||
--lan Bind to 0.0.0.0 for LAN access when starting
|
||||
--server <url> Public URL saved into the connection link
|
||||
--server-url <url> Alias for --server
|
||||
--relay Generate an end-to-end-encrypted relay pairing link
|
||||
(no server URL needed; requires the relay enabled on
|
||||
this instance). Set OPENCHAMBER_RELAY_URL to use a
|
||||
self-hosted relay.
|
||||
--relay Also include the end-to-end-encrypted relay transport
|
||||
so the link works away from the local network. The
|
||||
device prefers the direct connection when reachable;
|
||||
the instance brings the relay up on its own. Set
|
||||
OPENCHAMBER_RELAY_URL to use a self-hosted relay.
|
||||
--name <label> Label saved with the remote client token
|
||||
--ui-password <value> Protect browser access when UI routes are enabled
|
||||
--api-only Start in headless/API-only mode when starting
|
||||
|
||||
@@ -137,50 +137,6 @@ function buildPairingPayload({ pairing, label, candidates }) {
|
||||
};
|
||||
}
|
||||
|
||||
// Relay-only pairing link: the sole candidate is the relay transport, for
|
||||
// sharing with a device that is not on the host's network. Needs no reachable
|
||||
// server URL, but the host must be running with the relay enabled to serve the
|
||||
// redeem over the tunnel.
|
||||
async function generateRelayConnectUrl(options) {
|
||||
const label = options.name || os.hostname();
|
||||
const relay = await buildRelayPairingCandidate();
|
||||
const pairingRuntime = createCliPairingRuntime();
|
||||
const { pairing } = await pairingRuntime.createPairingSession({ label });
|
||||
const connectUrl = encodePairingConnectUrl(buildPairingPayload({ pairing, label, candidates: [relay.candidate] }));
|
||||
|
||||
if (isJsonMode(options)) {
|
||||
printJson({
|
||||
mode: 'relay',
|
||||
relayUrl: relay.relayUrl,
|
||||
serverId: relay.serverId,
|
||||
relayEnabled: relay.enabled,
|
||||
pairingId: pairing.id,
|
||||
fingerprint: pairing.fingerprint,
|
||||
expiresAt: pairing.expiresAt,
|
||||
connectUrl,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (isQuietMode(options)) {
|
||||
process.stdout.write(`${connectUrl}\n`);
|
||||
return;
|
||||
}
|
||||
|
||||
clackIntro('OpenChamber relay pairing link');
|
||||
logStatus('success', connectUrl);
|
||||
clackLog.info(`Relay: ${relay.relayUrl}`);
|
||||
if (pairing.fingerprint) clackLog.info(`Fingerprint: ${pairing.fingerprint}`);
|
||||
if (!relay.enabled) {
|
||||
logStatus('info', '[RELAY_ENABLE]', 'Enable the relay on this instance so this link can connect (Settings -> Remote Instances).');
|
||||
}
|
||||
clackLog.info('Scan or paste this link into another OpenChamber client. It is single-use and expires.');
|
||||
if (options.qr === true) {
|
||||
await displayTunnelQrCode(connectUrl);
|
||||
}
|
||||
clackOutro('relay pairing link generated');
|
||||
}
|
||||
|
||||
async function resolveConnectUrlServerUrl(options) {
|
||||
let hostOverride = options.host;
|
||||
if (typeof hostOverride !== 'string' && !process.env.OPENCHAMBER_HOST) {
|
||||
@@ -226,6 +182,15 @@ function isWildcardBindHost(host) {
|
||||
return host === '0.0.0.0' || host === '::' || host === '[::]';
|
||||
}
|
||||
|
||||
function isLoopbackServerUrl(serverUrl) {
|
||||
try {
|
||||
const hostname = new URL(serverUrl).hostname.replace(/^\[|\]$/g, '');
|
||||
return hostname === '127.0.0.1' || hostname === 'localhost' || hostname === '::1';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeServerUrlForConnection(value) {
|
||||
const trimmed = typeof value === 'string' ? value.trim() : '';
|
||||
if (!trimmed) return null;
|
||||
@@ -266,13 +231,6 @@ function createConnectUrlCommand({ serveCommand }) {
|
||||
throw new TunnelCliError('Invalid --server URL. Use an http:// or https:// URL.', EXIT_CODE.USAGE_ERROR);
|
||||
}
|
||||
|
||||
// Relay pairing needs neither a reachable server URL nor a running server:
|
||||
// the link is built from the instance's local relay identity + a fresh client
|
||||
// token. The client reads the relay endpoint from the offer.
|
||||
if (options.relay) {
|
||||
return await generateRelayConnectUrl(options);
|
||||
}
|
||||
|
||||
const running = await discoverRunningInstances();
|
||||
const serverState = running.some((entry) => entry.port === options.port)
|
||||
? { port: options.port, autoStarted: false }
|
||||
@@ -298,14 +256,20 @@ function createConnectUrlCommand({ serveCommand }) {
|
||||
const label = options.name || os.hostname();
|
||||
|
||||
// Direct candidate for the reachable server URL, plus the relay transport as
|
||||
// a fallback candidate when the host relay is enabled — one link that works
|
||||
// both on the LAN and off-network.
|
||||
// a fallback candidate — one link that works both on the LAN and off-network.
|
||||
// Candidate priorities make the client prefer the direct route and try the
|
||||
// relay last, mirroring the UI's "Anywhere" pairing. `--relay` opts in even
|
||||
// when the host relay is not up yet (the demand-driven lifecycle starts it);
|
||||
// otherwise the relay rides along only when it is already enabled.
|
||||
const candidates = [{ type: serverUrl.startsWith('https://') ? 'tunnel' : 'lan', url: serverUrl, priority: 10 }];
|
||||
const relay = await buildRelayPairingCandidate();
|
||||
if (relay.enabled) candidates.push(relay.candidate);
|
||||
if (options.relay || relay.enabled) candidates.push(relay.candidate);
|
||||
|
||||
const pairingRuntime = createCliPairingRuntime();
|
||||
const { pairing } = await pairingRuntime.createPairingSession({ label });
|
||||
// Mark relay-carrying sessions like the server route does, so the host's
|
||||
// demand-driven relay lifecycle keeps the relay up while the link is pending.
|
||||
const usesRelay = candidates.some((candidate) => candidate.type === 'relay');
|
||||
const { pairing } = await pairingRuntime.createPairingSession({ label, usesRelay });
|
||||
const connectUrl = encodePairingConnectUrl(buildPairingPayload({ pairing, label, candidates }));
|
||||
|
||||
if (isJsonMode(options)) {
|
||||
@@ -332,9 +296,12 @@ function createConnectUrlCommand({ serveCommand }) {
|
||||
}
|
||||
logStatus('success', connectUrl);
|
||||
clackLog.info(`Server URL: ${serverUrl}`);
|
||||
if (relay.enabled) {
|
||||
if (options.relay || relay.enabled) {
|
||||
clackLog.info(`Relay fallback: ${relay.relayUrl}`);
|
||||
}
|
||||
if (options.relay && !relay.enabled) {
|
||||
logStatus('info', '[RELAY_STARTING]', 'Relay is not up yet. A running instance starts it within a minute; a stopped instance starts it on next launch.');
|
||||
}
|
||||
if (pairing.fingerprint) {
|
||||
clackLog.info(`Fingerprint: ${pairing.fingerprint}`);
|
||||
}
|
||||
@@ -342,6 +309,15 @@ function createConnectUrlCommand({ serveCommand }) {
|
||||
clackLog.info('Detected a LAN address because OpenChamber is bound to all interfaces. Use --server to override it.');
|
||||
} else if (resolvedServerUrl.source === 'loopback-fallback') {
|
||||
clackLog.warn('OpenChamber is bound to all interfaces, but no LAN address was detected. Use --server to provide a reachable URL.');
|
||||
} else if (isLoopbackServerUrl(serverUrl)) {
|
||||
// The direct candidate points at this machine only — other devices cannot
|
||||
// use it. Say so instead of letting a "LAN" link silently not work (or a
|
||||
// --relay link silently go relay-only).
|
||||
if (options.relay) {
|
||||
logStatus('warn', '[LAN_UNREACHABLE]', 'OpenChamber only listens on this machine, so devices will always connect through the relay. Restart with --lan to allow direct home-network connections.');
|
||||
} else {
|
||||
logStatus('warn', '[LAN_UNREACHABLE]', 'OpenChamber only listens on this machine, so other devices cannot use this link. Restart with --lan, or use --server to provide a reachable URL.');
|
||||
}
|
||||
}
|
||||
clackLog.info('Scan or paste this link into another OpenChamber client. It is single-use and expires.');
|
||||
if (options.qr === true) {
|
||||
|
||||
@@ -1508,6 +1508,15 @@ async function main(options = {}) {
|
||||
// device/session exists, stop it (and clear a stale enabled flag) otherwise.
|
||||
void relayService.reconcile();
|
||||
|
||||
// Relay demand can change outside our routes: `openchamber connect-url
|
||||
// --relay` writes a pending relay session straight to the on-disk store, and
|
||||
// pending sessions expire without any request hitting us. Poll reconcile so a
|
||||
// headless instance picks the relay up (or drops it) within a minute.
|
||||
const relayReconcileTimer = setInterval(() => {
|
||||
void relayService.reconcile();
|
||||
}, 60_000);
|
||||
relayReconcileTimer.unref?.();
|
||||
|
||||
return {
|
||||
expressApp: app,
|
||||
httpServer: server,
|
||||
@@ -1538,6 +1547,7 @@ async function main(options = {}) {
|
||||
},
|
||||
stop: (shutdownOptions = {}) => {
|
||||
realtimeProxyRuntime.stop();
|
||||
clearInterval(relayReconcileTimer);
|
||||
try {
|
||||
relayService.stop();
|
||||
} catch {
|
||||
|
||||
Reference in New Issue
Block a user