Skip to content

cognilabz/remote-browser

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Remote Browser

Access internal websites from anywhere without a VPN, without editing DNS, and without hand-building port forwards for every service.

Remote Browser gives you a dedicated Chrome/Chromium app that behaves like it is sitting inside your remote Linux network. Open the app on macOS or a Linux desktop, type an internal URL, and the request is resolved and fetched through the remote machine that already has network access.

It is built for the annoying real-world gap between "I can reach this service from the remote machine" and "I need to inspect it in a normal browser on my laptop".

Why This Exists

Modern teams hide the important stuff behind private DNS, split networks, private routes, remote development hosts, staging clusters, intranet portals, admin UIs, local dashboards, and environments that your laptop browser cannot see directly.

The usual workarounds are slow and fragile:

  • Start a VPN, hope DNS routes correctly, and leak all browsing into the VPN.
  • Forward one port, then another, then another, until the login redirect breaks.
  • Copy service URLs into curl because the browser cannot resolve the hostname.
  • Reconfigure Chrome proxy settings globally and accidentally affect normal browsing.
  • Keep a terminal full of tunnel commands alive just to view one internal page.

Remote Browser replaces that mess with one focused tool:

  • a separate desktop browser app for internal sites,
  • a remote-side HTTP proxy where internal DNS actually works,
  • an authenticated Dev Tunnel bridge for the proxy port,
  • an isolated Chrome profile so cookies, extensions, history, and sessions stay separate from your daily browser,
  • scripts for macOS, Linux clients, and remote Linux hosts.

The Use Case

Use Remote Browser when a machine you can reach already has access to internal websites, but your local browser does not.

Good examples:

  • Open https://grafana.internal, https://argocd.company.local, or https://service.namespace.svc from your laptop.
  • Test staging web apps that only resolve inside a remote Linux host or a private network.
  • Access internal admin panels without routing your whole laptop through a VPN.
  • Browse many internal hosts without creating a new port forward for each one.
  • Keep internal sessions and certificates out of your normal Chrome profile.
  • Give developers a repeatable "open the internal browser" workflow instead of a tribal-knowledge tunnel recipe.

Remote Browser is not a security bypass. The remote Linux machine must already be allowed to reach the internal sites, and Dev Tunnels authentication still controls who can connect to the bridge.

How It Works

The key idea is simple: do DNS and HTTP(S) proxying on the remote side, then make only that proxy reachable to the client.

flowchart LR
  user["Developer"]
  app["Remote Browser app<br/>macOS .app or Linux client"]
  profile["Dedicated Chrome profile<br/>cookies, history, extensions"]
  localBridge["Local Dev Tunnel bridge<br/>127.0.0.1:18080"]
  tunnel["Authenticated Dev Tunnel<br/>single proxy port"]
  remoteHost["Remote Linux host<br/>inside private network"]
  tinyproxy["tinyproxy<br/>127.0.0.1:18080"]
  dns["Remote DNS resolver"]
  internal["Internal sites<br/>intranet, staging, dashboards, admin UIs"]

  user --> app
  app --> profile
  app -->|"Chrome proxy flag"| localBridge
  localBridge --> tunnel
  tunnel --> remoteHost
  remoteHost --> tinyproxy
  tinyproxy --> dns
  tinyproxy --> internal

  normal["Normal Chrome<br/>unchanged"]
  user -.-> normal
Loading

Request flow:

  1. You open Remote Browser.app on macOS or the Linux client.
  2. The launcher starts Chrome/Chromium with an isolated profile and proxy flags.
  3. The local client exposes http://127.0.0.1:18080 through Dev Tunnels.
  4. The remote Linux side runs tinyproxy on the same port.
  5. Internal hostnames are resolved by the remote machine, not by your laptop.
  6. The page renders locally while the network lookup happens remotely.

That is the whole product: local browser experience, remote network reach.

What You Get

  • One-click internal browsing on macOS through /Applications/Remote Browser.app.
  • Linux desktop client and optional AppImage.
  • Remote Linux setup for tinyproxy and tunnel hosting.
  • No global browser proxy changes.
  • No per-service port forwarding.
  • No dependency on the VS Code Ports panel once the bridge is configured.
  • Separate browser profile for internal sessions.
  • Logs and status commands that make failures diagnosable.
  • A single shared remote-browser.env for tunnel name, proxy port, browser path, start URL, and prestart hooks.

Quick Start

There are two sides:

  • Remote side: Linux machine that can resolve and reach internal sites.
  • Client side: macOS or Linux desktop where you want the browser window.

1. Install The Remote Linux Side

Run this inside the remote Linux checkout:

./remote-browser-setup.sh

Choose:

install remote Linux side

The setup installs the needed CLI tools, configures tinyproxy, prepares the tunnel helper, starts the remote proxy, and hosts the proxy port through Dev Tunnels.

Check it:

./scripts/remote-browser-proxy-remote-start.sh status
./scripts/remote-browser-remote-start.sh status
./scripts/remote-browser-remote-start.sh proxy-host-status

The first run may ask for a GitHub device-code login for the Dev Tunnels CLI. Later runs reuse that login.

2. Install The macOS App

Run this in the macOS checkout:

./remote-browser-setup.sh

Choose:

install/update macOS app

Direct non-interactive install:

./scripts/remote-browser-install.sh \
  --mac \
  --mac-app \
  --app-name "Remote Browser" \
  --app-force \
  --app-open

The app is installed here:

/Applications/Remote Browser.app

Open it like any other Mac app. Only Remote Browser appears in the Dock, and the app uses its own Chrome profile.

3. Or Install The Linux Client

Run this in the Linux desktop checkout:

./remote-browser-setup.sh

Choose:

install/update Linux client

Direct install:

./scripts/remote-browser-install.sh --linux-client

Build an AppImage:

./scripts/remote-browser-linux-appimage.sh --force

Run it:

./scripts/remote-browser-linux-client.sh

or:

./dist/remote-browser-x86_64.AppImage

Configuration

Create a local config if you need to override defaults:

cp config/remote-browser.env.example remote-browser.env

Use the same tunnel name on the remote side and every client.

Important values:

  • RB_TUNNEL_NAME - Dev Tunnel label/name shared by the remote host and clients.
  • RB_REMOTE_TUNNEL_LABEL - optional label override used for lookup.
  • RB_PROXY_PORT - proxy and bridge port, default 18080.
  • RB_CONNECT_TUNNEL_ID - fixed Dev Tunnel ID when label lookup is not enough.
  • RB_CHROME_APP - local Chrome app used as the macOS runtime source.
  • RB_CHROME_BIN - local Chrome/Chromium executable used on Linux.
  • RB_CHROME_PROFILE_DIR - dedicated Remote Browser Chrome profile.
  • RB_START_URL - default Linux startup URL, default about:blank.
  • RB_REMOTE_PRESTART_CMD - optional command run before app launch to start remote Linux services, for example through SSH.

Example prestart hook:

RB_REMOTE_PRESTART_CMD="ssh <user>@<host> '/path/to/repo/scripts/remote-browser-proxy-remote-start.sh start && /path/to/repo/scripts/remote-browser-remote-start.sh host-proxy'"

Validation

The most important proof is not "the tunnel exists". The proof is that the client has a local listener and can fetch an internal URL through it.

On the remote Linux side:

./scripts/remote-browser-proxy-remote-start.sh status
./scripts/remote-browser-proxy-remote-start.sh test
./scripts/remote-browser-remote-start.sh proxy-host-status

On the client side:

./scripts/remote-browser-devtunnel.sh status

On macOS, verify the local proxy listener:

lsof -nP -iTCP:18080 -sTCP:LISTEN

Verify a real internal site:

curl -k -x http://127.0.0.1:18080 -I -L \
  "https://internal-service.local/healthz"

Expected result: the request reaches the internal service and returns a real HTTP response, for example a redirect followed by 200 OK.

Daily Usage

Start from macOS:

open "/Applications/Remote Browser.app"

Start from Linux:

./scripts/remote-browser-linux-client.sh

Stop the macOS app:

./scripts/remote-browser-stop.command

Stop the client tunnel bridge:

./scripts/remote-browser-devtunnel.sh stop

Stop remote tinyproxy:

./scripts/remote-browser-proxy-remote-start.sh stop

Repository Layout

  • remote-browser-setup.sh - interactive installer with arrow-key menus.
  • scripts/remote-browser-install.sh - installs macOS, Linux client, or remote Linux dependencies.
  • scripts/remote-browser-macos-app.sh - builds /Applications/Remote Browser.app.
  • scripts/remote-browser-linux-client.sh - Linux client launcher using local Chrome/Chromium.
  • scripts/remote-browser-linux-appimage.sh - builds a Linux client AppImage.
  • scripts/remote-browser.command - macOS gateway check used by the app.
  • scripts/remote-browser-devtunnel.sh - client-side Dev Tunnels bridge for port 18080.
  • scripts/remote-browser-proxy-remote-start.sh - remote Linux tinyproxy manager.
  • scripts/remote-browser-remote-start.sh - remote Linux tunnel host helper.
  • scripts/remote-browser-stop.command - closes the Remote Browser app.
  • config/remote-browser.env.example - shared config template.
  • config/remote-browser-proxy-remote.tinyproxy.conf - remote Linux tinyproxy template.
  • assets/ - app icon assets.

Logs

macOS app launcher:

tail -f ~/Library/Logs/remote-browser/launcher.log

Client Dev Tunnel bridge:

tail -f ~/.local/state/remote-browser-devtunnel/connect.log

Remote Linux tunnel host:

./scripts/remote-browser-remote-start.sh logs

Remote Linux tinyproxy:

tail -f ~/.remote-browser-proxy/tinyproxy.log

Troubleshooting

If the browser opens but internal pages fail, check in this order:

  1. Remote proxy running:

    ./scripts/remote-browser-proxy-remote-start.sh status
  2. Remote tunnel host running:

    ./scripts/remote-browser-remote-start.sh proxy-host-status
  3. Client bridge running:

    ./scripts/remote-browser-devtunnel.sh status
  4. Local listener exists on the client:

    lsof -nP -iTCP:18080 -sTCP:LISTEN
  5. Internal URL works through the proxy:

    curl -k -x http://127.0.0.1:18080 -I -L "https://internal-service.local"

Common failure meanings:

  • No listener on 127.0.0.1:18080: the client bridge is not connected.
  • Remote tunnel host offline: start remote-browser-remote-start.sh host-proxy on the remote Linux machine.
  • tinyproxy not listening: start remote-browser-proxy-remote-start.sh start on the remote Linux machine.
  • Dev Tunnel login required: run ./scripts/remote-browser-remote-start.sh login on the remote side or authenticate the client-side devtunnel CLI.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages