This site
Between you and this page, and between your email and my inbox: one Swift process at my home, hosted on a Superloop NBN connection. Every layer, below.
The host
One machine, in Melbourne.
One computer at home runs all of it: web, mail, DNS, certificates and the question box’s language model.
- CPU
- AMD Ryzen 5 5600X6 cores, 12 threads
- Memory
- 16 GB
- GPU
- NVIDIA RTX 309024 GB, for the question box
- System
- Ubuntu 26.04 LTSLinux 7.0
- Connection
- Superloop NBNAS38195
- Software
- OriginKitSwift 6.4, 91,000 lines, 1,747 tests
Addresses
IPv4 and IPv6, with reverse DNS.
Superloop routes IPv6 here, so IPv6 connections reach the process directly. IPv4 is one address behind the gateway. Every name has A and AAAA; the server refuses a zone otherwise.
- IPv6
- 2401:d002:3a0c:1500:2::1reverse: mail.jmurphyau.com
- IPv4
- 36.255.114.31NAT at the gateway
- Reverse DNS
- served herethe IPv6 zone, delegated to this machine
The firewall
The gateway, then the host.
The gateway forwards only served ports. On the host, nftables drops everything else inbound; SSH only from the LAN. Outbound, the server may reach DNS, TCP 25, 443 and 993, and nothing else: never loopback, private ranges or the LAN.
- Inbound TCP
- 25 · 53 · 80 · 443 · 465 · 993served addresses only
- Inbound UDP
- 53 · 443DNS and QUIC
- Outbound
- DNS · 25 · 443 · 993nothing else
- SSH
- LAN only
Sockets
From systemd, handed on after a peek.
systemd binds every port and passes the sockets in; OriginKit never binds a port or holds a capability. One binary, two roles: supervisor and worker, each its own Unix user. Over IPv4 the supervisor peeks at a connection’s first bytes and hands the socket to the worker with SCM_RIGHTS. Over IPv6 it goes straight to the worker.
- TLS ports
- ClientHello SNI
- Port 80
- Host header
- Port 53
- DNS question
- UDP 443
- QUIC Initialdecrypted with the public RFC 9001 keys
- Port 25
- STARTTLS ClientHelloafter SMTP up to RCPT TO
No privileges
Nothing as root, nothing it doesn’t need.
The worker runs as ok-jmurphyau with no capabilities, a seccomp filter, W^X memory, a read-only filesystem and no devices. It can write only its own directory.
Two slots: a new build starts in the idle one and takes new connections; the old one drains and exits. Measured: 18 swaps under load at 17,200 requests a second, no failed requests.
- Capabilities
- noneCapBnd = 0, NoNewPrivs
- System calls
- @system-serviceminus @privileged and @resources
- Memory
- 66 MBworker RSS
- Filesystem
- read-onlyexcept its own directory, mode 0700
- Containers
- nonesystemd units
TLS
1.2 minimum, post-quantum key exchange.
OpenSSL 3.5, server preference. ECDHE only; AES-GCM or ChaCha20-Poly1305; signatures SHA-256 or stronger; no renegotiation, no compression. Modern browsers get post-quantum X25519MLKEM768. One ECDSA P-256 certificate per name, chosen by SNI.
- Versions
- TLS 1.3 · TLS 1.2
- Key exchange
- X25519MLKEM768post-quantum hybrid
- TLS 1.3 suites
- AES-256-GCM · ChaCha20-Poly1305 · AES-128-GCM
- TLS 1.2 suites
- ECDHE-ECDSA · ECDHE-RSAsame three ciphers
- Certificates
- ECDSA P-256one per name
HTTP
HTTP/1.1 and HTTP/3, both in Swift.
HTTP/1.1 is OriginKit’s own. HTTP/3 runs on Apple’s swift-network-evolution QUIC engine, with OriginKit’s listener, framing and QPACK; each request goes to the same handler. Port 80 answers 308 to HTTPS. Load-tested on the host: 27,600 requests a second for the home page, no failures.
- Versions
- HTTP/1.1 · HTTP/3
- QUIC
- swift-network-evolutionApple’s engine, 0.4.0
- Cache
- 64 MB, W-TinyLFUETag, 304
- Compression
- gzipbodies ≥ 1 KiB
- Load test
- 27,600 req/sp50 1.1 ms · p99 3.0 ms · 32 clients, 3 × 8 s, on the host
- This page
- HTTPS
DNS
Authoritative, from the same process.
The .com registry delegates jmurphyau.com to ns1 and ns2.jmurphyau.com: both this process. The IPv6 reverse zone is answered from the same machine. ANY gets the RFC 8482 answer. Zone transfers and NOTIFY are built in; DNSSEC is not, yet.
- Zones
- jmurphyau.com · the IPv6 reverse
- Records
- A · AAAA · NS · CNAME · PTR · MX · SRV · SOA · TXT · CAA
- Rate limit
- 20/s, burst 40UDP, per /24 or /56
- CAA
- letsencrypt.org; no wildcards
- Reload
- live, inotify
Certificates
Let’s Encrypt, for names and IP addresses.
OriginKit’s own ACME client. Names use dns-01, answered by its own DNS. IP addresses use http-01 on Let’s Encrypt’s six-day profile; that certificate goes to clients that send no SNI. Before each order it checks that a public resolver sees its SOA serial and only its addresses.
The domain has its own client CA, name-constrained to its email addresses, and passkey sign-in on OriginKit’s own WebAuthn.
- Authority
- Let’s EncryptRFC 8555, own client
- Names
- dns-01one certificate each
- Addresses
- http-01, RFC 87386-day, IPv4 and IPv6
- Renewal
- at ⅔ of lifeevery ~4 days for IPs
- Client CA
- ownname-constrained, to 2036
SMTP in, SMTP out, IMAP to read it.
Mail to james@jmurphyau.com arrives at the same process on port 25. It checks SPF, DKIM and DMARC, and stores each message as one .eml file; no database. I read it over IMAP with a client certificate. Outgoing mail is DKIM-signed and retried for five days.
- Ports
- 25 STARTTLS · 465 · 993
- DKIM
- RSA 2048rsa-sha256, relaxed/relaxed
- SPF
- -allthis server’s addresses only
- DMARC
- p=quarantinestrict alignment
- Login
- client certificateSASL EXTERNAL, or app password
The question box
A language model on the same machine.
Ask runs Qwen3-8B on the RTX 3090: 1,600 lines of Swift, no package dependencies, CUDA opened with dlopen. My notes are prefilled once into the KV cache; no retrieval. The service has no network; the web worker reaches it over a Unix socket. Questions are rate-limited and not logged.
- Model
- Qwen3-8Bbf16, 15.6 GB of weights
- Speed
- 39.8 tokens/s
- Context
- 12,230 tokensmy notes, prefilled once
- Network
- nonea Unix socket from the web worker
The pages
Plain files, written with AI.
Static files: HTML, one stylesheet, a few small JavaScript modules. No framework, build step, web fonts, cookies or trackers. Claude Code wrote them, with me directing. A deploy is a file rename; nothing restarts.