Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 19 additions & 3 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

"github.com/coder/boundary/config"
"github.com/coder/boundary/log"
"github.com/coder/boundary/nsjail_manager"
"github.com/coder/boundary/run"
"github.com/coder/serpent"
)

Expand Down Expand Up @@ -119,9 +119,25 @@ func BaseCommand() *serpent.Command {
Value: &cliConfig.ConfigureDNSForLocalStubResolver,
YAML: "configure_dns_for_local_stub_resolver",
},
{
Flag: "jail-type",
Env: "BOUNDARY_JAIL_TYPE",
Description: "Jail type to use for network isolation. Options: nsjail (default), landjail.",
Default: "nsjail",
Value: &cliConfig.JailType,
YAML: "jail_type",
},
},
Handler: func(inv *serpent.Invocation) error {
appConfig := config.NewAppConfigFromCliConfig(cliConfig)
appConfig, err := config.NewAppConfigFromCliConfig(cliConfig, inv.Args)
if err != nil {
return fmt.Errorf("failed to parse cli config file: %v", err)
}

// Get command arguments
if len(appConfig.TargetCMD) == 0 {
return fmt.Errorf("no command specified")
}

logger, err := log.SetupLogging(appConfig)
if err != nil {
Expand All @@ -134,7 +150,7 @@ func BaseCommand() *serpent.Command {
}
logger.Debug("Application config", "config", appConfigInJSON)

return nsjail_manager.Run(inv.Context(), logger, appConfig, inv.Args)
return run.Run(inv.Context(), logger, appConfig)
},
}
}
35 changes: 33 additions & 2 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
package config

import (
"fmt"

"github.com/coder/serpent"
)

// JailType represents the type of jail to use for network isolation
type JailType string

const (
NSJailType JailType = "nsjail"
LandjailType JailType = "landjail"
)

func NewJailTypeFromString(str string) (JailType, error) {
switch str {
case "nsjail":
return NSJailType, nil
case "landjail":
return LandjailType, nil
default:
return NSJailType, fmt.Errorf("invalid JailType: %s", str)
}
}

type CliConfig struct {
Config serpent.YAMLConfigPath `yaml:"-"`
AllowListStrings serpent.StringArray `yaml:"allowlist"` // From config file
Expand All @@ -14,6 +35,7 @@ type CliConfig struct {
PprofEnabled serpent.Bool `yaml:"pprof_enabled"`
PprofPort serpent.Int64 `yaml:"pprof_port"`
ConfigureDNSForLocalStubResolver serpent.Bool `yaml:"configure_dns_for_local_stub_resolver"`
JailType serpent.String `yaml:"jail_type"`
}

type AppConfig struct {
Expand All @@ -24,16 +46,23 @@ type AppConfig struct {
PprofEnabled bool
PprofPort int64
ConfigureDNSForLocalStubResolver bool
JailType JailType
TargetCMD []string
}

func NewAppConfigFromCliConfig(cfg CliConfig) AppConfig {
func NewAppConfigFromCliConfig(cfg CliConfig, targetCMD []string) (AppConfig, error) {
// Merge allowlist from config file with allow from CLI flags
allowListStrings := cfg.AllowListStrings.Value()
allowStrings := cfg.AllowStrings.Value()

// Combine allowlist (config file) with allow (CLI flags)
allAllowStrings := append(allowListStrings, allowStrings...)

jailType, err := NewJailTypeFromString(cfg.JailType.Value())
if err != nil {
return AppConfig{}, err
}

return AppConfig{
AllowRules: allAllowStrings,
LogLevel: cfg.LogLevel.Value(),
Expand All @@ -42,5 +71,7 @@ func NewAppConfigFromCliConfig(cfg CliConfig) AppConfig {
PprofEnabled: cfg.PprofEnabled.Value(),
PprofPort: cfg.PprofPort.Value(),
ConfigureDNSForLocalStubResolver: cfg.ConfigureDNSForLocalStubResolver.Value(),
}
JailType: jailType,
TargetCMD: targetCMD,
}, nil
}
29 changes: 28 additions & 1 deletion e2e_tests/boundary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"github.com/stretchr/testify/require"
)

// BoundaryTest is a high-level test framework for boundary e2e tests
// BoundaryTest is a high-level test framework for boundary e2e tests using nsjail
type BoundaryTest struct {
t *testing.T
projectRoot string
Expand Down Expand Up @@ -100,6 +100,7 @@
// Build command args
args := []string{
"--log-level", bt.logLevel,
"--jail-type", "nsjail",
}
for _, domain := range bt.allowedDomains {
args = append(args, "--allow", domain)
Expand Down Expand Up @@ -202,6 +203,32 @@
return output
}

// ExpectDenyContains makes an HTTP/HTTPS request and expects it to be denied, checking that response contains the given text
func (bt *BoundaryTest) ExpectDenyContains(url string, containsText string) {
bt.t.Helper()
output := bt.makeRequest(url)
require.Contains(bt.t, string(output), containsText, "Response does not contain expected denial text")
}

func (bt *BoundaryTest) getNsCurlCmd(url string) *exec.Cmd {

Check failure on line 213 in e2e_tests/boundary_test.go

View workflow job for this annotation

GitHub Actions / Lint

func (*BoundaryTest).getNsCurlCmd is unused (unused)
pid := fmt.Sprintf("%v", bt.pid)
_, _, _, _, configDir := util.GetUserInfo()
certPath := fmt.Sprintf("%v/ca-cert.pem", configDir)

args := []string{"nsenter", "-t", pid, "-n", "--",
"env", fmt.Sprintf("SSL_CERT_FILE=%v", certPath), "curl", "-sS", url}
curlCmd := exec.Command("sudo", args...)

return curlCmd
}

func (bt *BoundaryTest) getHostCurlCmd(url string) *exec.Cmd {

Check failure on line 225 in e2e_tests/boundary_test.go

View workflow job for this annotation

GitHub Actions / Lint

func (*BoundaryTest).getHostCurlCmd is unused (unused)
args := []string{"-sS", url}
curlCmd := exec.Command("curl", args...)

return curlCmd
}

// getTargetProcessPID gets the PID of the boundary target process.
// Target process is associated with a network namespace, so you can exec into it, using this PID.
// pgrep -f boundary-test -n is doing two things:
Expand Down
Loading
Loading