A stack with TLS in front of it was still publishing nginx on 0.0.0.0, so the admin stayed reachable over plain HTTP on a raw port while the proxy served the same site over HTTPS beside it. On this project's own instance that meant wp-login.php answering 200 to the open internet. There is no password to steal — the account is a key — but the session cookie is the account, and a cookie read off the wire is a logged-in administrator. HTTP_BIND defaults to 0.0.0.0, so a stack with nothing in front behaves exactly as before. The records doc now also explains the pinned self-signed certificate route, which is how a BCNR name gets HTTPS without a certificate authority — and why an editor needs it at all: the publishing key is derived in the page, and crypto.subtle does not exist outside a secure context.
144 lines
5.2 KiB
Markdown
144 lines
5.2 KiB
Markdown
# Pointing your name at your site
|
|
|
|
A BCNR name carries a small set of records on-chain. Two of them say "the site
|
|
for this name is served from here":
|
|
|
|
| Record | Holds | Use it when |
|
|
|---|---|---|
|
|
| `ip` | An IPv4 or IPv6 address | You have a server with a fixed address — the normal case for a VPS |
|
|
| `p` | A hostname | Something else already resolves to your server: a DNS name, a tunnel endpoint, a load balancer |
|
|
|
|
Either one makes a BCNR resolver — Theseus, Ariadne, or the public gateway —
|
|
send visitors to your Sirius Press instance.
|
|
|
|
---
|
|
|
|
## Setting the record
|
|
|
|
From the Sirius portal at [sirius.x](https://sirius.x): open your name, go to
|
|
the DNS tab, add the record, and sign. The change costs nothing and takes
|
|
effect as soon as the manifest is published, because records live in a
|
|
wallet-signed manifest rather than in a chain transaction.
|
|
|
|
You can also set them from the registrar CLI if you run one.
|
|
|
|
---
|
|
|
|
## Which one to use
|
|
|
|
**`ip`, if you can.** It is one fewer system between a reader and your site,
|
|
and it does not depend on anyone's DNS continuing to answer — which is most of
|
|
the point of having a BCNR name in the first place.
|
|
|
|
**`p`, if your address moves**, or if you are behind a tunnel, or if you want
|
|
a CDN in front. The tradeoff is real: a `p` record points at a name in somebody
|
|
else's namespace, and whoever controls that namespace can redirect your
|
|
visitors. If you are using BCNR to get out from under ICANN, pointing your name
|
|
back into it is worth doing deliberately rather than by default.
|
|
|
|
### Put TLS in front of it, with `ip` + `tls`
|
|
|
|
An `ip` record on its own is served over plain HTTP, and for a site with an
|
|
editor that is not good enough. Two reasons, and the second is the one people
|
|
miss:
|
|
|
|
1. **The session cookie is the account.** There is no password to steal here,
|
|
but a cookie read off the wire is a logged-in admin, and a BCNR name does
|
|
not stop a network between you and the server.
|
|
2. **Manual publishing does not work without it.** The key that signs an
|
|
upload is derived in the page, and `crypto.subtle` does not exist outside a
|
|
secure context. Over plain HTTP the Publishing screen can queue work and
|
|
never sign it.
|
|
|
|
You do not need a certificate authority. Put a reverse proxy in front with a
|
|
**self-signed certificate**, and record its fingerprint on chain:
|
|
|
|
```bash
|
|
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes \
|
|
-keyout server.key -out server.crt -days 3650 \
|
|
-subj "/CN=yourname.x" -addext "subjectAltName=DNS:yourname.x,DNS:*.yourname.x"
|
|
|
|
# the value for the `tls` record
|
|
openssl x509 -in server.crt -noout -fingerprint -sha256 \
|
|
| sed 's/.*=//; s/://g' | tr 'A-Z' 'a-z'
|
|
```
|
|
|
|
Set `ip` to the server's address and `tls` to that fingerprint. Theseus and
|
|
Ariadne both refuse any certificate whose DER SHA-256 does not match — which
|
|
is a narrower claim than a CA makes, and it expires on your schedule rather
|
|
than someone else's. Rotating the certificate is one record update.
|
|
|
|
Then stop publishing the container's port to the world, since the proxy is now
|
|
the only thing that should reach it:
|
|
|
|
```ini
|
|
# .env
|
|
HTTP_BIND=127.0.0.1
|
|
```
|
|
|
|
---
|
|
|
|
## Telling WordPress its own address
|
|
|
|
WordPress builds absolute URLs from a value it stores, and it has to match what
|
|
visitors actually type or you get redirect loops.
|
|
|
|
In Docker, set `SITE_URL` in `docker/.env` and restart:
|
|
|
|
```
|
|
SITE_URL=https://example.bch
|
|
```
|
|
|
|
Elsewhere, set it in `wp-config.php`:
|
|
|
|
```php
|
|
define( 'WP_HOME', 'https://example.bch' );
|
|
define( 'WP_SITEURL', 'https://example.bch' );
|
|
```
|
|
|
|
Do this once your name resolves, not before — WordPress will happily guess from
|
|
the request until then, which is what you want during setup.
|
|
|
|
---
|
|
|
|
## The static mirror is separate
|
|
|
|
Setting `ip` or `p` points readers at your **live WordPress**. It has nothing
|
|
to do with the static export.
|
|
|
|
The export goes to your name's storage on Sia, at `bns/<name>/`, and resolvers
|
|
reach it through the name's `s3` record. That means a name can have both:
|
|
|
|
- an `ip` record, so visitors get the live site with its comments and search
|
|
- a populated bucket, so that when the server is down, or slow, or gone, the
|
|
last published copy still answers
|
|
|
|
Which one a given resolver prefers is its business, and different resolvers
|
|
choose differently. The useful way to think about it: the live site is where
|
|
your site is, and the static mirror is what survives if it stops being there.
|
|
|
|
If you want *only* the static copy served — no PHP exposed to the public at all
|
|
— leave `ip` and `p` unset and let the `s3` record do the work. Your WordPress
|
|
then runs somewhere private, as an authoring tool, and publishes outward. For
|
|
a site that is mostly reading rather than interaction, this is the strongest
|
|
arrangement available, and it is what `silentmode.st` itself does.
|
|
|
|
---
|
|
|
|
## Checking it
|
|
|
|
```bash
|
|
curl -s https://navigate.st/api/dns/example.bch | python3 -m json.tool
|
|
```
|
|
|
|
shows the verified records a resolver sees, and
|
|
|
|
```bash
|
|
curl -s https://navigate.st/api/site/example.bch | python3 -m json.tool
|
|
```
|
|
|
|
lists what is actually in the name's bucket — which is the quickest way to
|
|
confirm an export arrived.
|
|
|
|
The **Sirius Press → Publishing** screen shows the same thing from inside
|
|
wp-admin, along with whatever the queue is still working through.
|