Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
0790ca9
Add --unprivileged flag for rootless operation using user namespaces …
blink-so[bot] Sep 12, 2025
a2dfe31
Fix cross-compilation: Add stub for NewUserNamespaceLinux on non-Linu…
blink-so[bot] Sep 12, 2025
12e6842
Simplify implementation: Remove enhanced APIs, update existing APIs d…
blink-so[bot] Sep 12, 2025
1f6e276
Revert to manual user namespace approach (better than rootlesskit for…
blink-so[bot] Sep 12, 2025
2a3c04f
Replace unshare command with SysProcAttr namespace creation
blink-so[bot] Sep 12, 2025
e05321d
Update tool validation for SysProcAttr approach
blink-so[bot] Sep 12, 2025
9d50a59
Fix config directory issue: Add better root user detection and error …
blink-so[bot] Sep 12, 2025
d43a7cd
Add comprehensive troubleshooting guide and usage clarification
blink-so[bot] Sep 12, 2025
19cf5e8
Add container-friendly config directory handling
blink-so[bot] Sep 12, 2025
d24106d
Fix user detection in Coder workspace environments
blink-so[bot] Sep 12, 2025
6feee6d
Fix networking: Use localhost redirection instead of veth pairs
blink-so[bot] Sep 12, 2025
e7f4aa4
Add simple user namespace approach that avoids nsenter issues
blink-so[bot] Sep 12, 2025
e9a5d7a
Fix in place: Replace complex nsenter approach with direct SysProcAttr
blink-so[bot] Sep 12, 2025
5e5c9a2
Fix UID/GID mapping: Handle manually in script instead of Go SysProcAttr
blink-so[bot] Sep 12, 2025
cab27c5
Simplify to use unshare command directly for reliable namespace creation
blink-so[bot] Sep 12, 2025
dd0409f
Add DNS configuration and improve iptables rules for user namespace
blink-so[bot] Sep 12, 2025
20e597e
Switch to proxy environment variables instead of iptables
blink-so[bot] Sep 12, 2025
90f68b1
Implement rootlesskit-inspired proxy-based approach
blink-so[bot] Sep 12, 2025
dfba605
Fix proxy environment for transparent HTTPS proxy
blink-so[bot] Sep 12, 2025
a74731a
Implement rootlesskit user space networking with iptables
blink-so[bot] Sep 12, 2025
277c506
Add proper networking setup with veth pair and DNS
blink-so[bot] Sep 12, 2025
96a229d
Implement true unprivileged networking with slirp4netns
blink-so[bot] Sep 12, 2025
272df2f
Require slirp4netns for --unprivileged mode
blink-so[bot] Sep 12, 2025
0b47bd6
Fix slirp4netns integration with proper PID coordination
blink-so[bot] Sep 12, 2025
6bdcebf
Fix proxy connectivity from slirp4netns namespace
blink-so[bot] Sep 12, 2025
160927a
Implement simple proxy forwarding with netcat
blink-so[bot] Sep 12, 2025
1acbc57
Fix proxy forwarding with socat and improved netcat compatibility
blink-so[bot] Sep 12, 2025
a13939e
Fix format string arguments mismatch
blink-so[bot] Sep 12, 2025
3b6e470
Improve proxy forwarding with connectivity testing and reliable fallb…
blink-so[bot] Sep 12, 2025
2341b29
Clean slate: Remove all complex networking code to start fresh
blink-so[bot] Sep 12, 2025
0198fa3
Implement clean slirp4netns network jail with iptables traffic forwar…
blink-so[bot] Sep 12, 2025
588a400
Fix slirp4netns PID handling and add iptables fallback to proxy envir…
blink-so[bot] Sep 12, 2025
13dbcb5
Fix proxy environment to use slirp4netns gateway IP (10.0.2.2)
blink-so[bot] Sep 12, 2025
dfcc006
Simplify unprivileged mode to use proxy environment variables
blink-so[bot] Sep 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 69 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,43 @@ jail \
jail -- curl https://example.com
```

### Unprivileged Mode (NEW!)

jail now supports running without elevated privileges using the `--unprivileged` flag:

```bash
# No sudo required!
jail --unprivileged --allow "github.com" -- curl https://github.com

# Works with complex applications
jail --unprivileged --allow "*.npmjs.org" -- npm install

# Same rule engine and proxy functionality as privileged mode
jail --unprivileged --allow "api.example.com" -- ./my-app
```

**⚠️ Important: Run as regular user, NOT with sudo**
```bash
# ✅ CORRECT - Run as regular user
jail --unprivileged --allow "github.com" -- curl https://github.com

# ❌ WRONG - Don't use sudo with --unprivileged
sudo jail --unprivileged --allow "github.com" -- curl https://github.com

# ✅ For privileged mode, use sudo WITHOUT --unprivileged
sudo jail --allow "github.com" -- curl https://github.com
```

**Requirements for Unprivileged Mode:**
- Linux (kernel 2.6+)
- Applications that respect proxy environment variables (HTTP_PROXY, HTTPS_PROXY)

**Benefits:**
- ✅ **No sudo required** - Runs as regular user
- ✅ **No external dependencies** - Uses built-in proxy environment variables
- ✅ **Container-friendly** - Works in restricted environments
- ✅ **Same rule engine** - Identical allow/block logic as privileged mode

## Allow Rules

jail uses simple wildcard patterns for URL matching.
Expand Down Expand Up @@ -121,10 +158,37 @@ For more help: https://github.com/coder/jail
## Platform Support

| Platform | Implementation | Sudo Required |
|----------|----------------|---------------|
| Linux | Network namespaces + iptables | Yes |
| macOS | Process groups + PF rules | Yes |
| Windows | Not supported | - |
|----------|----------------|--------------|
| Linux | Network namespaces + iptables | Yes |
| **Linux (Unprivileged)** | **Proxy environment variables** | **No** |
| macOS | Process groups + PF rules | Yes |
| Windows | Not supported | - |

## Troubleshooting Unprivileged Mode

### "permission denied" for `/root/.config`
```bash
Error: failed to create certificate manager: failed to create config directory at /root/.config/coder_jail: mkdir /root/.config: permission denied
```
**Solution**: Don't use `sudo` with `--unprivileged`. Run as regular user:
```bash
# ❌ Wrong
sudo jail --unprivileged --allow "github.com" -- curl https://github.com

# ✅ Correct
jail --unprivileged --allow "github.com" -- curl https://github.com
```

### Applications not respecting proxy settings
```bash
# Some applications may ignore proxy environment variables
# Check your application's documentation for proxy configuration
```
**Solution**: Use privileged mode for applications that don't respect proxy environment variables:
```bash
# For apps that ignore HTTP_PROXY/HTTPS_PROXY
sudo jail --allow "github.com" -- your-app
```

## Installation

Expand Down Expand Up @@ -174,6 +238,7 @@ OPTIONS:
--allow <SPEC> Allow rule (repeatable)
Format: "pattern" or "METHOD[,METHOD] pattern"
--log-level <LEVEL> Set log level (error, warn, info, debug)
--unprivileged Use unprivileged mode (no sudo required, Linux only)
--no-tls-intercept Disable HTTPS interception
-h, --help Print help
```
Expand Down
93 changes: 67 additions & 26 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"os/signal"
"os/user"
"path/filepath"
"runtime"
"strconv"
"strings"
"syscall"
Expand All @@ -24,6 +25,7 @@ import (
type Config struct {
AllowStrings []string
LogLevel string
Unprivileged bool // Enable unprivileged mode (user namespace + iptables)
}

// NewCommand creates and returns the root serpent command
Expand All @@ -37,14 +39,22 @@ func NewCommand() *serpent.Command {
intercepting all HTTP/HTTPS traffic through a transparent proxy that enforces
user-defined rules.

Modes:
Default (privileged): Uses network namespaces + iptables (requires sudo)
Unprivileged: Uses proxy environment variables (no sudo required)

Examples:
# Allow only requests to github.com
jail --allow "github.com" -- curl https://github.com
# Privileged mode (original behavior)
sudo jail --allow "github.com" -- curl https://github.com

# Unprivileged mode (NEW!)
jail --unprivileged --allow "github.com" -- curl https://github.com

# Monitor all requests to specific domains (allow only those)
jail --allow "github.com/api/issues/*" --allow "GET,HEAD github.com" -- npm install
# Monitor all requests to specific domains
jail --unprivileged --allow "github.com/api/issues/*" --allow "GET,HEAD github.com" -- npm install

# Block everything by default (implicit)`,
# Block everything by default (implicit)
jail --unprivileged --allow "api.example.com" -- ./my-app`,
Options: serpent.OptionSet{
{
Name: "allow",
Expand All @@ -61,6 +71,13 @@ Examples:
Default: "warn",
Value: serpent.StringOf(&config.LogLevel),
},
{
Name: "unprivileged",
Flag: "unprivileged",
Env: "JAIL_UNPRIVILEGED",
Description: "Use unprivileged mode (proxy environment variables, no sudo required, Linux only).",
Value: serpent.BoolOf(&config.Unprivileged),
},
},
Handler: func(inv *serpent.Invocation) error {
return Run(inv.Context(), config, inv.Args)
Expand All @@ -75,6 +92,20 @@ func Run(ctx context.Context, config Config, args []string) error {
logger := setupLogging(config.LogLevel)
userInfo := getUserInfo()

// Validate unprivileged mode if requested
if config.Unprivileged {
// Warn if running as root but don't block it (some container environments need this)
if os.Geteuid() == 0 {
logger.Warn("Running unprivileged mode as root - this may cause permission issues with config files")
}
if err := validateUnprivilegedMode(logger); err != nil {
return fmt.Errorf("unprivileged mode validation failed: %v", err)
}
logger.Info("Using unprivileged mode (proxy environment variables, no sudo required)")
} else {
logger.Info("Using privileged mode (network namespace + iptables, requires sudo)")
}

// Get command arguments
if len(args) == 0 {
return fmt.Errorf("no command specified")
Expand Down Expand Up @@ -110,10 +141,11 @@ func Run(ctx context.Context, config Config, args []string) error {

// Create jail instance
jailInstance, err := jail.New(ctx, jail.Config{
RuleEngine: ruleEngine,
Auditor: auditor,
CertManager: certManager,
Logger: logger,
RuleEngine: ruleEngine,
Auditor: auditor,
CertManager: certManager,
Logger: logger,
Unprivileged: config.Unprivileged,
})
if err != nil {
return fmt.Errorf("failed to create jail instance: %v", err)
Expand Down Expand Up @@ -158,30 +190,29 @@ func Run(ctx context.Context, config Config, args []string) error {
return nil
}

// getUserInfo returns information about the current user, handling sudo scenarios
func getUserInfo() namespace.UserInfo {
// get the user info of the original user even if we are running under sudo
sudoUser := os.Getenv("SUDO_USER")

// If running under sudo, get original user information
if sudoUser != "" {
// Only consider SUDO_USER if we're actually running with elevated privileges
// In environments like Coder workspaces, SUDO_USER may be set to 'root'
// but we're not actually running under sudo
if sudoUser := os.Getenv("SUDO_USER"); sudoUser != "" && os.Geteuid() == 0 && sudoUser != "root" {
// We're actually running under sudo with a non-root original user
user, err := user.Lookup(sudoUser)
if err != nil {
// Fallback to current user if lookup fails
return getCurrentUserInfo()
return getCurrentUserInfo() // Fallback to current user
}

// Parse SUDO_UID and SUDO_GID
uid := 0
gid := 0
uid, _ := strconv.Atoi(os.Getenv("SUDO_UID"))
gid, _ := strconv.Atoi(os.Getenv("SUDO_GID"))

if sudoUID := os.Getenv("SUDO_UID"); sudoUID != "" {
if parsedUID, err := strconv.Atoi(sudoUID); err == nil {
// If we couldn't get UID/GID from env, parse from user info
if uid == 0 {
if parsedUID, err := strconv.Atoi(user.Uid); err == nil {
uid = parsedUID
}
}

if sudoGID := os.Getenv("SUDO_GID"); sudoGID != "" {
if parsedGID, err := strconv.Atoi(sudoGID); err == nil {
if gid == 0 {
if parsedGID, err := strconv.Atoi(user.Gid); err == nil {
gid = parsedGID
}
}
Expand All @@ -197,7 +228,7 @@ func getUserInfo() namespace.UserInfo {
}
}

// Not running under sudo, use current user
// Not actually running under sudo, use current user
return getCurrentUserInfo()
}

Expand Down Expand Up @@ -225,7 +256,6 @@ func setupLogging(logLevel string) *slog.Logger {
return slog.New(handler)
}

// getCurrentUserInfo gets information for the current user
func getCurrentUserInfo() namespace.UserInfo {
currentUser, err := user.Current()
if err != nil {
Expand Down Expand Up @@ -255,3 +285,14 @@ func getConfigDir(homeDir string) string {
}
return filepath.Join(homeDir, ".config", "coder_jail")
}

// validateUnprivilegedMode checks if the system supports unprivileged mode
func validateUnprivilegedMode(logger *slog.Logger) error {
// Check if we're on Linux
if runtime.GOOS != "linux" {
return fmt.Errorf("unprivileged mode only supports Linux, got: %s", runtime.GOOS)
}

logger.Debug("Unprivileged mode validation passed")
return nil
}
13 changes: 10 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,31 @@ require (
cdr.dev/slog v1.6.2-0.20240126064726-20367d4aede6 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/moby/sys/mountinfo v0.6.2 // indirect
github.com/muesli/termenv v0.15.2 // indirect
github.com/pion/transport/v2 v2.0.0 // indirect
github.com/pion/udp v0.1.4 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/rootless-containers/rootlesskit v1.1.1 // indirect
github.com/sirupsen/logrus v1.9.2 // indirect
github.com/spf13/pflag v1.0.5 // indirect
go.opentelemetry.io/otel v1.19.0 // indirect
go.opentelemetry.io/otel/trace v1.19.0 // indirect
golang.org/x/crypto v0.19.0 // indirect
golang.org/x/crypto v0.36.0 // indirect
golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect
golang.org/x/sys v0.17.0 // indirect
golang.org/x/term v0.17.0 // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/sys v0.32.0 // indirect
golang.org/x/term v0.30.0 // indirect
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
36 changes: 24 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,14 @@ github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
Expand All @@ -48,6 +52,8 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78=
github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
Expand All @@ -67,11 +73,16 @@ github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/rootless-containers/rootlesskit v1.1.1 h1:F5psKWoWY9/VjZ3ifVcaosjvFZJOagX85U22M0/EQZE=
github.com/rootless-containers/rootlesskit v1.1.1/go.mod h1:UD5GoA3dqKCJrnvnhVgQQnweMF2qZnf9KLw8EewcMZI=
github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y=
github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
Expand All @@ -88,40 +99,41 @@ go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1
go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE=
golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
Expand Down
Binary file added jail
Binary file not shown.
Loading