Dan Fuhry [Sat, 22 Nov 2025 03:01:18 +0000 (22:01 -0500)]
[ephs] split server into servicer and low-level client
Make the ephs servicer act as a front-end to the ephs low-level client library, which handles all direct interaction with etcd.
- Move all ephs etcd interaction from `ephs/servicer` to `ephs/ephsll`
- Add ephs.Path type to make ephs path transformations simpler
- Refactor grpc's `WithStaticAddress` option to support DNS names
Dan Fuhry [Fri, 21 Nov 2025 00:34:00 +0000 (19:34 -0500)]
[ephs] `edit` command, client library and server improvements
- fixed server failing to build since 020d9e6d because s3.go referenced the removed `genericOption` type
- add custom error type for not-found errors so they are easier to distinguish
- validate S3 credentials on server startup
- add `edit` command to ephs commandline client to allow editing text files directly in ephs
Dan Fuhry [Wed, 19 Nov 2025 21:48:52 +0000 (16:48 -0500)]
[mint] add new service: mint
Add a mint service which can issue certificates for other service identities based on configured rules. This allows, for example, a service to use its own identity to request a temporary `etcd-client` certificate.
The mint service applies the following restrictions:
1. Only service account identities may be requested.
2. Clients are not allowed to request a certificate for their own identity.
3. Issued certificates will always use the same SPIFFE domain as the original requester's certificate.
4. Certificates issued by the mint service expire at the same time as the client certificate used to make the connection to the mint service.
5. The rules for which services are allowed to request which identities are defined in a YAML file stored in ephs at (by default) `/ephs/local/services/mint/rules.yaml`.
Dan Fuhry [Wed, 19 Nov 2025 21:46:12 +0000 (16:46 -0500)]
[grpc/client] make serverId a string
Prevent gRPC clients from trying to load the server's identity by calling `mtls.NewRemoteServiceIdentity` (which only returns a stub identity) and changing the `NewGrpcClient` function signature to accept a string instead of an Identity.
Dan Fuhry [Wed, 19 Nov 2025 21:36:13 +0000 (16:36 -0500)]
Genericize "option" interface
"Option" variadic pattern has been used in lots of things lately - grpc client and server, ephs, etc. Although the implementation is trivial, the repetition was becoming obnoxious.
Other trivial fixes:
- Fixed sd watcher wait group never calling Done if etcd client context is canceled
- Fixed etcd_factory type declaration
Dan Fuhry [Wed, 19 Nov 2025 14:30:24 +0000 (09:30 -0500)]
[grpc] adopt Option pattern, add DNS SRV support
- Allow gRPC server and client factories to accept variadic Options
- Add `ClientOption`: `WithDNSSRV`, which uses DNS SRV queries instead of SD
- Add `ServerOption`: `WithTransport` (overrides `-grpc.transport` flag)
- Force ephs server to use QUIC transport as QUIC is hardcoded into the client library
Dan Fuhry [Wed, 19 Nov 2025 14:14:51 +0000 (09:14 -0500)]
[mtls] add common identity parser
Add a new function in `mtls`, `ParseIdentity`, which standardizes the following prefixes for identities:
- "user." for human users
- "ssl://" for publicly trusted certs
- the exact string "anonymous" for anonymous access
- all other strings are parsed as service identities
The etcd client is configured to follow this convention.
Dan Fuhry [Fri, 14 Nov 2025 16:52:07 +0000 (11:52 -0500)]
[grpc] support loading ACLs from ephs
Supporting changes:
- Rearranged grpc into internal/{client,server,common} packages to deal with circular dep between ephs and grpc
- Rename `mtls.parseName` -> `mtls.ParseRemoteIdentity` and make the returned struct and its properties public
- In ephs server ACLs, try to parse principal; if successful, set `name`, `class` and `domain` substitutions in the key
- Fixed severely incorrect invocation of acl.Check in ephs server (not a security issue, legitimate requests were blocked but no illegitimate requests were allowed)
- Add `utils/context` package - wrapper for `context` with shared `Interruptible` context that cancels on SIGTERM and SIGINT
Dan Fuhry [Thu, 6 Nov 2025 11:49:53 +0000 (06:49 -0500)]
[http] live reload, SNI proxying, bugfixes
- Initial backend live reload support, to be enabled in binary with merge of ephs/config_watcher
- Fix SNI listener closure upon single connection TLS handshake error
- added readme, because this is seriously getting too complicated for me to configure from memory
- refactored connection acceptance with a new `net.Listener` implementation that supports SNI, with virtual listeners that can be used with `http.Server`
- foundations laid for bare-TCP SNI proxying too, but implementation not started yet
- added `healthcheck` action
- added a mutable request context at the logging middleware level, to bubble up request data to the logger
- propagate SAML authorization state to global request context
- SAML action now skips if request was previously authorized
- got multiple listeners + multiple vhosts per listener working
To detect changes to the contents of /mnt/file using inotify instead of polling file contents, we need to detect when /mnt/..data is overwritten.
This requires complex symlink detection and resolution for not only the file but any of the directories in its path, and tracking of final absolute path and inode number to detect when the file was swapped with a different one.
This commit adds that support to fsnotify, along with lots of documentation and tests.
Dan Fuhry [Thu, 15 May 2025 14:39:24 +0000 (10:39 -0400)]
refactor MetricBusService to an interface
D-Bus metricbus server is being deprecated and being replaced with an https server that registers itself in sd and publishes its own stats.
This is the first step in the refactor, converting `MetricBusService` to an interface and updating all references accordingly. Full implementation will come later.
Dan Fuhry [Tue, 8 Apr 2025 21:59:26 +0000 (17:59 -0400)]
[http/saml] cookie bugfixes
- strip auth cookies before forwarding to origin
- when no session, send 401 instead of redirect for CORS and websocket requests
- delete unused relaystate cookies
Dan Fuhry [Sat, 29 Mar 2025 03:38:07 +0000 (23:38 -0400)]
Fine let's just make it a full HTTP proxy
Refactor samlproxy into a general purpose proxy with pluggable actions. Add S3 bucket serving backend. Route actions can fulfill the request or modify it and call next(), basically the same idea as coredns but for http.
Dan Fuhry [Sat, 22 Mar 2025 01:26:52 +0000 (21:26 -0400)]
machines bugfixes
- handle interface:deleted and host:deleted events
- coredns plugin: only call tryInit if we fail to load the saved state from disk
- coredns plugin: make all hostname lookups case insensitive
- coredns plugin: fix <interface>.<host>.<domain> lookups
- coredns plugin: bump init ticker interval to 10 seconds
- coredns plugin: tighten lock window when updating registry from API
- coredns plugin: increase verbosity level of some really noisy log messages
- tweak mqtt startup
- fix `allow/deny unknown-clients` being added to dhcp subnets with only one range
- add captive portal service in openbsd, fix maclist template
Dan Fuhry [Fri, 25 Oct 2024 15:46:00 +0000 (11:46 -0400)]
[mtls] Support service identity from cert-manager-csi-driver-spiffe
K8s support, commit 3 of 3.
Check the default mount location of `cert-manager-csi-driver-spiffe` for service certificate discovery. Support default and certbot file naming schemes.
Dan Fuhry [Fri, 25 Oct 2024 15:43:29 +0000 (11:43 -0400)]
[sd] add SRVHost option
Kubernetes support, commit 2 of 3: publish `pod-name.service.<SDDomain>` as the name in the SRV record when Kubernetes is detected. Preserve legacy behavior by defaulting to `AdvertiseHost` if configured, or our FQDN if not.
Dan Fuhry [Fri, 25 Oct 2024 15:34:43 +0000 (11:34 -0400)]
hostname: support /etc/hosts, /etc/resolv.conf; add container detection
Needed for Kubernetes compatibility.
Kubernetes doesn't publish DNS records for pods. So the runtime can no longer assume that A/AAAA records exist for the host.
As a first step we need to be able to detect the hostname and kubernetes domain name. K8s is pretty good about populating `/etc/hosts` and `/etc/resolv.conf`, so we parse those when k8s is detected.
Dan Fuhry [Fri, 13 Sep 2024 00:38:32 +0000 (20:38 -0400)]
utils/daemon: add new package
Add new "daemon" package to handle detaching on Linux and Unix systems.
Supports writing pid files, socket pair based startup messaging, and
systemd notification on Linux.
Dan Fuhry [Fri, 13 Sep 2024 00:17:37 +0000 (20:17 -0400)]
utils/hostname: handle special case of domain name = "(none)" on linux
Linux systems can return interesting values when the domain name is
unset, like "(none)" or an empty string. To handle these, hostname.go is
forked with special Hostname(), DomainName() and RegionName()
implementations for Linux and the original implementations for other
OSes.
Dan Fuhry [Fri, 26 Jul 2024 16:37:07 +0000 (12:37 -0400)]
dns_cache: bypass systemd-resolved
On Linux systems, the stub resolv.conf points at systemd-resolved which uses the hostsfile. We don't want this - we need the system's addresses as described by the network's DNS server.