Add support for local outbound connections in sandbox configuration
This commit is contained in:
@@ -71,6 +71,7 @@ Create `~/.fence.json` to configure allowed domains and filesystem access:
|
||||
| `allowUnixSockets` | List of allowed Unix socket paths (macOS) |
|
||||
| `allowAllUnixSockets` | Allow all Unix sockets |
|
||||
| `allowLocalBinding` | Allow binding to local ports |
|
||||
| `allowLocalOutbound` | Allow outbound connections to localhost, e.g., local DBs (defaults to `allowLocalBinding` if not set) |
|
||||
| `httpProxyPort` | Fixed port for HTTP proxy (default: random available port) |
|
||||
| `socksProxyPort` | Fixed port for SOCKS5 proxy (default: random available port) |
|
||||
|
||||
@@ -138,6 +139,12 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Check if platform supports sandboxing (macOS/Linux)
|
||||
if !fence.IsSupported() {
|
||||
fmt.Println("Sandboxing not supported on this platform")
|
||||
return
|
||||
}
|
||||
|
||||
// Create config
|
||||
cfg := &fence.Config{
|
||||
Network: fence.NetworkConfig{
|
||||
|
||||
@@ -25,6 +25,7 @@ type NetworkConfig struct {
|
||||
AllowUnixSockets []string `json:"allowUnixSockets,omitempty"`
|
||||
AllowAllUnixSockets bool `json:"allowAllUnixSockets,omitempty"`
|
||||
AllowLocalBinding bool `json:"allowLocalBinding,omitempty"`
|
||||
AllowLocalOutbound *bool `json:"allowLocalOutbound,omitempty"` // If nil, defaults to AllowLocalBinding value
|
||||
HTTPProxyPort int `json:"httpProxyPort,omitempty"`
|
||||
SOCKSProxyPort int `json:"socksProxyPort,omitempty"`
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ type MacOSSandboxParams struct {
|
||||
AllowUnixSockets []string
|
||||
AllowAllUnixSockets bool
|
||||
AllowLocalBinding bool
|
||||
AllowLocalOutbound bool
|
||||
ReadDenyPaths []string
|
||||
WriteAllowPaths []string
|
||||
WriteDenyPaths []string
|
||||
@@ -419,10 +420,15 @@ func GenerateSandboxProfile(params MacOSSandboxParams) string {
|
||||
profile.WriteString("(allow network*)\n")
|
||||
} else {
|
||||
if params.AllowLocalBinding {
|
||||
// Allow binding and inbound connections on localhost (for servers)
|
||||
profile.WriteString(`(allow network-bind (local ip "localhost:*"))
|
||||
(allow network-inbound (local ip "localhost:*"))
|
||||
(allow network-outbound (local ip "localhost:*"))
|
||||
`)
|
||||
// Process can make outbound connections to localhost
|
||||
if params.AllowLocalOutbound {
|
||||
profile.WriteString(`(allow network-outbound (local ip "localhost:*"))
|
||||
`)
|
||||
}
|
||||
}
|
||||
|
||||
if params.AllowAllUnixSockets {
|
||||
@@ -492,6 +498,11 @@ func WrapCommandMacOS(cfg *config.Config, command string, httpPort, socksPort in
|
||||
// Enable local binding if ports are exposed or if explicitly configured
|
||||
allowLocalBinding := cfg.Network.AllowLocalBinding || len(exposedPorts) > 0
|
||||
|
||||
allowLocalOutbound := allowLocalBinding
|
||||
if cfg.Network.AllowLocalOutbound != nil {
|
||||
allowLocalOutbound = *cfg.Network.AllowLocalOutbound
|
||||
}
|
||||
|
||||
params := MacOSSandboxParams{
|
||||
Command: command,
|
||||
NeedsNetworkRestriction: needsNetwork || len(cfg.Network.AllowedDomains) == 0, // Block if no domains allowed
|
||||
@@ -500,6 +511,7 @@ func WrapCommandMacOS(cfg *config.Config, command string, httpPort, socksPort in
|
||||
AllowUnixSockets: cfg.Network.AllowUnixSockets,
|
||||
AllowAllUnixSockets: cfg.Network.AllowAllUnixSockets,
|
||||
AllowLocalBinding: allowLocalBinding,
|
||||
AllowLocalOutbound: allowLocalOutbound,
|
||||
ReadDenyPaths: cfg.Filesystem.DenyRead,
|
||||
WriteAllowPaths: allowPaths,
|
||||
WriteDenyPaths: cfg.Filesystem.DenyWrite,
|
||||
@@ -510,6 +522,9 @@ func WrapCommandMacOS(cfg *config.Config, command string, httpPort, socksPort in
|
||||
if debug && len(exposedPorts) > 0 {
|
||||
fmt.Fprintf(os.Stderr, "[fence:macos] Enabling local binding for exposed ports: %v\n", exposedPorts)
|
||||
}
|
||||
if debug && allowLocalBinding && !allowLocalOutbound {
|
||||
fmt.Fprintf(os.Stderr, "[fence:macos] Blocking localhost outbound (AllowLocalOutbound=false)\n")
|
||||
}
|
||||
|
||||
profile := GenerateSandboxProfile(params)
|
||||
|
||||
|
||||
@@ -3,9 +3,15 @@ package fence
|
||||
|
||||
import (
|
||||
"github.com/Use-Tusk/fence/internal/config"
|
||||
"github.com/Use-Tusk/fence/internal/platform"
|
||||
"github.com/Use-Tusk/fence/internal/sandbox"
|
||||
)
|
||||
|
||||
// IsSupported returns true if the current platform supports sandboxing (macOS/Linux).
|
||||
func IsSupported() bool {
|
||||
return platform.IsSupported()
|
||||
}
|
||||
|
||||
// Config is the configuration for fence.
|
||||
type Config = config.Config
|
||||
|
||||
|
||||
Reference in New Issue
Block a user