Pomelo uses stunnel in client mode to reach services on the current application server (gravlax) over mutually-authenticated TLS. Three tunnels are active. Authentication uses the private PKI — see ssl/pki for cert details and file locations.
| Name | Pomelo port | Remote | Purpose |
|---|---|---|---|
| socks5h | localhost:1080 | gravlax:11080 | SOCKS5 proxy (microsocks on gravlax) |
| notes | localhost:8021 | gravlax:18021 | Notes API (gdata-server on gravlax) |
| notes-mcp | localhost:8023 | gravlax:18023 | Notes MCP (gdata-mcp-server on gravlax) |
| imap | localhost:143 | cv.critchley.biz:993 | IMAP (public cert, separate CA) |
Config: /etc/stunnel/stunnel.conf on pomelo. checkHost = John Critchley verifies the server CN on all three gravlax tunnels.
Edit /etc/stunnel/stunnel.conf and change connect = gravlax:... to the new host in all three gravlax sections, then systemctl restart stunnel4. The new server must have been provisioned with setup_server.yml --tags stunnel.
Located at ~/py/s5pin.py. Aliased as s5pin. Listens on a local port and proxies each connection through the SOCKS5 server to a fixed remote host:port. Async, handles multiple simultaneous connections. Supports IPv4, IPv6, and domain name targets.
# Expose a remote service on gravlax's network as localhost:5432
s5pin --listen-port 5432 \
--remote-host db.internal \
--remote-port 5432 \
--socks-host localhost \
--socks-port 1080
Defaults: listen on 127.0.0.1:8008, SOCKS at localhost:1080, remote localhost:80.
s5pin can expose non-public REST services on gravlax's network as local ports, making them reachable by the envoy API call mechanism. See API Registration.
Idea raised 2026-09-17, not adopted, recorded for later: move authorization out of the tunnel and into the SOCKS layer — per-identity rules in danted.conf deciding who may reach which destination, rather than the current all-or-nothing "holding a valid client certificate grants everything". Possibly driven from a centralised config that can be updated in one place instead of edited per host. John's position for now: "this is all future ideas; we keep stunnel as is doing the authorization in effect."
Why both mechanisms exist, for when the next service needs exposing. Per-service stunnel sections (as the notes stack uses: 18021, 18023, 18121, 18123, 18221, 18223, plus pg on 15432) grant exactly one destination each, but every new backend costs a port and a config change on the server and on every client. The SOCKS tunnel plus s5pin grants one door to everything, so a new backend needs no tunnel config at all — at the cost of coarser authority, since the certificate that opens it opens all of it. Native TLS in each service was considered and rejected: it would mean implementing certificate handling and client verification separately in every service, whereas stunnel does it once, uniformly, in a well-understood implementation. That uniformity is the point, and is why the answer is not "pick one" — use a dedicated section where a service deserves its own narrow grant, and the SOCKS path where convenience matters more.