feat: switch macOS daemon from user-based to group-based pf routing

Sandboxed commands previously ran as `sudo -u _greywall`, breaking user
identity (home dir, SSH keys, git config). Now uses `sudo -u #<uid> -g
_greywall` so the process keeps the real user's identity while pf
matches
on EGID for traffic routing.

Key changes:
- pf rules use `group <GID>` instead of `user _greywall`
- GID resolved dynamically at daemon startup (not hardcoded, since macOS
  system groups like com.apple.access_ssh may claim preferred IDs)
- Sudoers rule installed at /etc/sudoers.d/greywall (validated with
visudo)
- Invoking user added to _greywall group via dscl (not dseditgroup,
which
  clobbers group attributes)
- tun2socks device discovery scans both stdout and stderr (fixes 10s
  timeout caused by STACK message going to stdout)
- Always-on daemon logging for session create/destroy events
This commit is contained in:
2026-02-25 19:20:01 -06:00
parent 4ea4592d75
commit cfe29d2c0b
15 changed files with 3866 additions and 18 deletions

View File

@@ -0,0 +1,38 @@
//go:build !darwin
package daemon
import "fmt"
// TunManager is a stub for non-macOS platforms.
type TunManager struct{}
// NewTunManager returns an error on non-macOS platforms.
func NewTunManager(tun2socksPath string, proxyURL string, debug bool) *TunManager {
return &TunManager{}
}
// Start returns an error on non-macOS platforms.
func (t *TunManager) Start() error {
return fmt.Errorf("tun manager is only available on macOS")
}
// Stop returns an error on non-macOS platforms.
func (t *TunManager) Stop() error {
return fmt.Errorf("tun manager is only available on macOS")
}
// TunDevice returns an empty string on non-macOS platforms.
func (t *TunManager) TunDevice() string {
return ""
}
// LoadPFRules returns an error on non-macOS platforms.
func (t *TunManager) LoadPFRules(sandboxUser string) error {
return fmt.Errorf("pf rules are only available on macOS")
}
// UnloadPFRules returns an error on non-macOS platforms.
func (t *TunManager) UnloadPFRules() error {
return fmt.Errorf("pf rules are only available on macOS")
}