# shark-expose `shark expose 3000`: put a local port on the internet through your own [Hammerhead](https://git.veillax.com/Veillax/hammerhead) and [Blacktip](https://git.veillax.com/Veillax/blacktip), the way ngrok does, with nothing to clean up afterwards. ``` $ shark expose 3000 --password s3cret shark http://demo-4f2a.dev.example.com -> 127.0.0.1:3000 Visitors must sign in. Press Ctrl+C to stop. ``` One command asks Hammerhead for a short-lived site and a public name or port, brings up the WireGuard tunnel from your machine (it embeds the [Bamboo](https://git.veillax.com/Veillax/bamboo) agent, so there is nothing else to install or run), prints the address, and keeps it alive. On Ctrl+C it deletes everything it created. If shark is killed or loses the network, Hammerhead removes the exposure itself once its TTL runs out (5 minutes unless you say otherwise). ## Install ``` go env -w GOPRIVATE=git.veillax.com go install git.veillax.com/Veillax/shark-expose/cmd/shark@latest ``` ## Sign in Make an API key under **Access** in the Hammerhead dashboard, then: ``` shark login --hammerhead https://hammerhead.example.com --token hhk_... ``` This checks the key and saves it to your user config folder (`shark/config.json`, readable by you only; `SHARK_CONFIG` picks another file). `SHARK_HAMMERHEAD` and `SHARK_TOKEN` override it, which suits CI. An API key belongs to one organization and can manage its settings, so treat it like a password. Exposures are made in that organization. ## Use ``` shark expose 3000 website on . shark expose https 3000 the same over HTTPS (Blacktip gets the certificate) shark expose 3000 --name demo demo-. shark expose 3000 --hostname me.dev.example.com shark expose 192.168.1.20:8080 something else on your network shark expose tcp 25565 raw TCP on a free public port (20000-29999) shark expose tcp 22 --port 20022 ...on the port you pick shark ls what is exposed in your organization right now ``` | Flag | | |---|---| | `--password P`, `--pin N`, `--sso` | Put a login in front of a website: a shared password (6+ characters), a PIN (4-12 digits), or a Hammerhead account. Can be combined; `SHARK_PASSWORD` avoids putting the password on the command line. | | `--ttl 10m` | How long Hammerhead keeps it if shark goes quiet (30s to 24h). shark renews every third of that while it runs. | | `--name`, `--hostname`, `--port`, `--edge` | Choose the label, the full public name, the public port, or the edge. | | `--verbose` | Show the tunnel agent's log. | For websites Hammerhead needs a domain to put the name under (**Domains** in the dashboard), with a wildcard DNS record pointing at the edge. TCP needs no domain: it uses the edge's address and a free port in 20000-29999, which has to be open in the edge's firewall. Login protection is for websites only. ## How it works 1. `POST /api/orgs/-/expose` makes an *ephemeral* site and mapping tagged `ephemeral` and returns the public address and the site's token. 2. shark runs Bamboo in-process with that token. It dials out to the edge, so your machine needs no inbound ports. 3. When the edge reports the port listening, shark prints the address. 4. `POST .../renew` every TTL/3. A 404 means Hammerhead dropped it, and shark exits with an error; renewals failing for longer than the TTL end it too. 5. `DELETE` on exit. The site, port, login secrets and tunnel address all go with it. The API is documented in Hammerhead's README ("Ephemeral exposures"). It currently lives on Hammerhead's `feature/ephemeral-expose` branch. ## Development ``` go test ./... # unit tests, with a fake Hammerhead cd e2e && go test ./... # shark against a real Hammerhead + Blacktip + Bamboo in one process ``` `e2e` is its own module so the CLI does not depend on Hammerhead. Its `go.mod` has a `replace` pointing at `../../hammerhead-expose`, a checkout of the Hammerhead branch above; change it once that is merged and released.