From 2a9ca0577ecdbee8b5a4bc8886c112dbc4260eab Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 25 Aug 2026 21:23:04 -0500 Subject: new-app: configure jail mail relay and persist the jail's network alias Two provisioning gaps in new-app: - The jail's dma.conf inherited the base image's shared SMARTHOST/ PORT/AUTHPATH, but never got a per-app MAILNAME - without one, dma can misroute mail for recipients on the jail's own apex domain as local delivery. EnableMail appends a MAILNAME of .skiff.local, which can't collide with any real domain an app sends to or from. - A classic jail's ip4.addr is only a bind restriction, not a route, until something aliases it onto a host interface. jail.conf.tmpl never set jail(8)'s own `interface` parameter, so nothing ever created that alias - confirmed on skiff-freebsd, where the address had twice been made to work via an ad hoc `ifconfig alias` that didn't survive a reboot. Setting `interface` lets jail(8) manage the alias itself, including on every boot. --- internal/jailmgr/jailmgr.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'internal/jailmgr/jailmgr.go') diff --git a/internal/jailmgr/jailmgr.go b/internal/jailmgr/jailmgr.go index b6a5d28..9ddf9b8 100644 --- a/internal/jailmgr/jailmgr.go +++ b/internal/jailmgr/jailmgr.go @@ -16,8 +16,8 @@ import ( // WriteConf renders jail.conf.d/.conf and the jail's own rc.d service // script + rc.conf enable line. Called once, from `skiff new-app`. -func WriteConf(cfg layout.Config, app, ip string) error { - conf, err := tmpl.JailConf(tmpl.JailConfData{Name: app, JailRoot: cfg.JailRoot(app), IP: ip}) +func WriteConf(cfg layout.Config, app, ip, iface string) error { + conf, err := tmpl.JailConf(tmpl.JailConfData{Name: app, JailRoot: cfg.JailRoot(app), IP: ip, Iface: iface}) if err != nil { return err } @@ -49,6 +49,21 @@ func WriteConf(cfg layout.Config, app, ip string) error { return nil } +// EnableMail appends a MAILNAME line to the jail's dma.conf, inherited from +// the base image's SMARTHOST/PORT/AUTHPATH/SECURETRANSFER/STARTTLS. Called +// once, from `skiff new-app`. +func EnableMail(cfg layout.Config, app string) error { + f, err := os.OpenFile(cfg.DMAConfPath(app), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + return fmt.Errorf("open jail dma.conf: %w", err) + } + defer f.Close() + if _, err := fmt.Fprintf(f, "\nMAILNAME %s.skiff.local\n", app); err != nil { + return fmt.Errorf("set MAILNAME in jail dma.conf: %w", err) + } + return nil +} + func Start(ctx context.Context, out io.Writer, app string) error { return sh.Run(ctx, out, "", "service", "jail", "start", app) } -- cgit v1.3