Add a local unix socket for root on the server
jarld also listens on /run/jarl/jarl.sock (socket in jarl.yaml). Requests on it from root or jarld's own user need no token and act as an administrator; the kernel's SO_PEERCRED says who is connecting, and anyone else must send a token. The jarl CLI uses the socket when no server is configured, or with -s local, so 'sudo jarl status' works on the server with nothing set up and a lost token or password never locks root out. Changes are audited under the system user's name via "socket". The systemd unit creates /run/jarl (0750). Socket paths over 107 bytes are refused with a clear message. The docs explain the socket and what happens when a token is revoked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f528c2aa9c
commit
cf49df0346
22 files changed
+570
-26
No files matched your search
@@ -22,14 +22,17 @@ type Config struct {
|
||||
Listen []string `yaml:"listen"`
|
||||
TLS TLS `yaml:"tls"`
|
||||
TrustedProxies []string `yaml:"trusted_proxies"`
|
||||
Database string `yaml:"database"`
|
||||
StagingDir string `yaml:"staging_dir"`
|
||||
Log Log `yaml:"log"`
|
||||
Session Session `yaml:"session"`
|
||||
BIND BIND `yaml:"bind"`
|
||||
Audit Audit `yaml:"audit"`
|
||||
Stats Stats `yaml:"stats"`
|
||||
ACME ACME `yaml:"acme"`
|
||||
// Socket is a local unix socket for the API, where root and jarld's
|
||||
// own user need no token ("" for none).
|
||||
Socket string `yaml:"socket"`
|
||||
Database string `yaml:"database"`
|
||||
StagingDir string `yaml:"staging_dir"`
|
||||
Log Log `yaml:"log"`
|
||||
Session Session `yaml:"session"`
|
||||
BIND BIND `yaml:"bind"`
|
||||
Audit Audit `yaml:"audit"`
|
||||
Stats Stats `yaml:"stats"`
|
||||
ACME ACME `yaml:"acme"`
|
||||
}
|
||||
|
||||
// ACME configures the ACME helpers.
|
||||
@@ -168,6 +171,7 @@ func ParseDuration(s string) (time.Duration, error) {
|
||||
func Default() *Config {
|
||||
return &Config{
|
||||
Listen: []string{"127.0.0.1:8053"},
|
||||
Socket: "/run/jarl/jarl.sock",
|
||||
Database: "/var/lib/jarl/jarl.db",
|
||||
StagingDir: "/var/lib/jarl/staging",
|
||||
Log: Log{Level: "info", Format: "text"},
|
||||
@@ -220,6 +224,12 @@ func (c *Config) check() error {
|
||||
if len(c.Listen) == 0 {
|
||||
return fmt.Errorf("listen: at least one address is needed")
|
||||
}
|
||||
if c.Socket != "" && !filepath.IsAbs(c.Socket) {
|
||||
return fmt.Errorf("socket must be an absolute path (or \"\" for none)")
|
||||
}
|
||||
if len(c.Socket) > 107 {
|
||||
return fmt.Errorf("socket: the path is %d bytes long; unix sockets allow at most 107", len(c.Socket))
|
||||
}
|
||||
if (c.TLS.CertFile == "") != (c.TLS.KeyFile == "") {
|
||||
return fmt.Errorf("tls: set both cert_file and key_file")
|
||||
}
|
||||
@@ -334,6 +344,12 @@ tls:
|
||||
cert_file: ""
|
||||
key_file: ""
|
||||
|
||||
# A local unix socket for the API and the jarl CLI. Requests on it from
|
||||
# root or jarld's own user need no token and have administrator rights
|
||||
# ('sudo jarl status' works with nothing configured); anyone else must send
|
||||
# a token. systemd creates /run/jarl. "" turns the socket off.
|
||||
socket: /run/jarl/jarl.sock
|
||||
|
||||
# Reverse proxies whose X-Forwarded-For / X-Forwarded-Proto headers are
|
||||
# trusted (addresses or prefixes).
|
||||
trusted_proxies: []
|
||||
|
||||
Reference in new issue
Block a user