> ## Documentation Index
> Fetch the complete documentation index at: https://nexohub.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# What faces the internet

> Which routes are public, what the secret protects, and where TLS belongs.

On a fresh install nothing here faces the internet. The pack goes to Nexo's Hermes host
and players fetch it from there, so NexoHub's own port only ever carries your backends
talking to the proxy and can stay behind your firewall.

This page is about what changes when you set `packs.host: proxy` and serve the pack from
the proxy yourself. Then the port has to be open, because that is where players download
from, and your backends' traffic goes through that same open port by default.

## The two kinds of route

| Route | Who calls it | Secret |
| - | - | - |
| `/hub/v1/pack/<hash>.zip` | a player's Minecraft client | no |
| `/hub/v1/health` | you, and `/nexohub doctor` | no |
| everything else | your backends | yes |

The pack download cannot be protected by the secret, because a Minecraft client is only
handed a link. The pack is not a secret, so that costs you nothing.

`/hub/v1/health` returns the word `nexohub` and nothing else. `/nexohub doctor` uses it
to check whether the address you handed players actually reaches your proxy, which is the
one thing you cannot test from inside your own network.

Everything else needs the secret, and a request without it is refused and logged with the
address it came from:

```
[nexohub] Rejected GET /hub/v1/bundle/pvp/current from 203.0.113.9, X-Hub-Secret header missing or wrong.
```

## The secret

NexoHub generates a 40 character secret on first start, writes it into `config.yml` and
prints it once. Every backend gets the same one.

Treat it like a password. Every backend holds it, so anyone who gets onto one of your
backends can read and write anything on the hub. That is why `/nexohub adopt` needs more
than the secret: it only works in the five minute window you open by running the command,
so a backend cannot overwrite your whole network's files on its own.

Changing it means changing it on the proxy and on every backend, then `/nexohub reload`.

## Splitting the ports

Under `host: proxy` your backends talk to the proxy on the same port players download
from. That works, but it means those routes are reachable from the internet too. (Under
the default delegated hosting there is nothing to split: no port here is open to players
in the first place, and `/nexohub doctor` says so rather than suggesting this.)

Give them a port of their own:

```yaml theme={null}
http:
  bind: 0.0.0.0
  port: 8085              # players
  public_address: "http://your.proxy.address:8085"

  api_address: 8086       # backends
```

Then point each backend at that listener instead:

```yaml theme={null}
# backend: plugins/NexoHubBridge/config.yml
hub:
  address: "http://your.proxy.internal:8086"
```

`public_address` still describes the public port, because that is what goes into the
resource pack link.

<Note>
  A bare port means loopback, so only backends on the proxy's own machine can reach it.
  If yours are elsewhere, write an address they can reach: `api_address: "10.0.0.1:8086"`,
  and let your firewall do the rest.

  Players can still download the pack on either port, so nothing breaks for them.
</Note>

`/nexohub doctor` tells you which of the two you are running:

```
  note the authenticated API shares the public port 8085; set http.api_address to separate them
```

```
  ok   the authenticated API is on 127.0.0.1:8086, off the public port
```

It is a `note` and not a `bad`. Sharing the port is the default and it is a fine choice
for a small network, but you should know that is what you have.

## TLS

NexoHub speaks plain HTTP and has no certificate settings.

That means the secret travels in the clear every time a backend talks to the proxy. If
they are on the same machine or the same private network, that traffic never goes
anywhere and it does not matter. If they are on different machines across the internet,
put a reverse proxy in front.

nginx, Caddy or Cloudflare is worth having anyway:

* it adds TLS, so the pack download and your backends' traffic stop being plaintext
* it keeps your proxy's address out of the resource pack link, because `public_address`
  points at the reverse proxy instead
* it can rate limit the download, which NexoHub does not do

<Warning>
  Cloudflare only proxies certain ports: 8080, 8443, 2052, 2053, 2082, 2083, 2086, 2087,
  2095, 2096 and 8880. The default 8085 is not one of them, so change `http.port` if you
  go that route. See [hosting](/guides/hosting).
</Warning>

If you would rather not hand out your proxy's address at all, leave hosting delegated to
an external host, which is what a fresh install does. Then no player ever resolves it and
`public_address` stops mattering. The hub still listens, so the port still wants closing
to everything but your backends. See [hosting](/guides/hosting).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.