sirius-press: let the published port be bound to localhost
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.
This commit is contained in:
parent
373394b534
commit
582cc81ffe
3 changed files with 53 additions and 1 deletions
|
|
@ -21,6 +21,12 @@ SITE_URL=
|
|||
# owns 80 and you are running a reverse proxy in front.
|
||||
HTTP_PORT=80
|
||||
|
||||
# Which address that port is published on. Leave it alone for a stack that
|
||||
# faces the internet directly. Set it to 127.0.0.1 when a reverse proxy on
|
||||
# this machine terminates TLS — the proxy can still reach it, nobody else
|
||||
# can, and the admin stops being available over plain HTTP to the world.
|
||||
#HTTP_BIND=127.0.0.1
|
||||
|
||||
WP_DEBUG=false
|
||||
|
||||
# --- the publishing key ------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -74,7 +74,13 @@ services:
|
|||
depends_on:
|
||||
- app
|
||||
ports:
|
||||
- "${HTTP_PORT:-80}:80"
|
||||
# HTTP_BIND exists for the case where something else terminates TLS in
|
||||
# front of this stack. Set it to 127.0.0.1 and the port stops being
|
||||
# reachable from outside the machine, which matters more here than on a
|
||||
# normal site: wp-admin is the whole account, and a session cookie
|
||||
# crossing the internet in clear text hands it over. Default is
|
||||
# unchanged, so a stack with nothing in front still works.
|
||||
- "${HTTP_BIND:-0.0.0.0}:${HTTP_PORT:-80}:80"
|
||||
volumes:
|
||||
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
|
||||
# nginx serves static files directly and only proxies PHP, so it needs
|
||||
|
|
|
|||
|
|
@ -36,6 +36,46 @@ 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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue