fix: add --block-direct-connections to wsproxies (#12182)

This commit is contained in:
Colin Adler
2024-03-07 23:45:59 -06:00
committed by GitHub
parent 66154f937e
commit 6b0b87eb27
6 changed files with 80 additions and 3 deletions

View File

@ -880,7 +880,8 @@ when required by your organization's security policy.`,
Env: "CODER_BLOCK_DIRECT", Env: "CODER_BLOCK_DIRECT",
Value: &c.DERP.Config.BlockDirect, Value: &c.DERP.Config.BlockDirect,
Group: &deploymentGroupNetworkingDERP, Group: &deploymentGroupNetworkingDERP,
YAML: "blockDirect", YAML: "blockDirect", Annotations: clibase.Annotations{}.
Mark(annotationExternalProxies, "true"),
}, },
{ {
Name: "DERP Force WebSockets", Name: "DERP Force WebSockets",

View File

@ -262,6 +262,7 @@ func (r *RootCmd) proxyServer() *clibase.Cmd {
AllowAllCors: cfg.Dangerous.AllowAllCors.Value(), AllowAllCors: cfg.Dangerous.AllowAllCors.Value(),
DERPEnabled: cfg.DERP.Server.Enable.Value(), DERPEnabled: cfg.DERP.Server.Enable.Value(),
DERPOnly: derpOnly.Value(), DERPOnly: derpOnly.Value(),
BlockDirect: cfg.DERP.Config.BlockDirect.Value(),
DERPServerRelayAddress: cfg.DERP.Server.RelayURL.String(), DERPServerRelayAddress: cfg.DERP.Server.RelayURL.String(),
}) })
if err != nil { if err != nil {

View File

@ -20,7 +20,7 @@ import (
"github.com/coder/coder/v2/testutil" "github.com/coder/coder/v2/testutil"
) )
func Test_Headers(t *testing.T) { func Test_ProxyServer_Headers(t *testing.T) {
t.Parallel() t.Parallel()
const ( const (

View File

@ -34,6 +34,7 @@ type ProxyOptions struct {
DisablePathApps bool DisablePathApps bool
DerpDisabled bool DerpDisabled bool
DerpOnly bool DerpOnly bool
BlockDirect bool
// ProxyURL is optional // ProxyURL is optional
ProxyURL *url.URL ProxyURL *url.URL
@ -158,6 +159,7 @@ func NewWorkspaceProxyReplica(t *testing.T, coderdAPI *coderd.API, owner *coders
DERPOnly: options.DerpOnly, DERPOnly: options.DerpOnly,
DERPServerRelayAddress: serverURL.String(), DERPServerRelayAddress: serverURL.String(),
StatsCollectorOptions: statsCollectorOptions, StatsCollectorOptions: statsCollectorOptions,
BlockDirect: options.BlockDirect,
}) })
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {

View File

@ -75,6 +75,9 @@ type Options struct {
// DERPOnly determines whether this proxy only provides DERP and does not // DERPOnly determines whether this proxy only provides DERP and does not
// provide access to workspace apps/terminal. // provide access to workspace apps/terminal.
DERPOnly bool DERPOnly bool
// BlockDirect controls the servertailnet of the proxy, forcing it from
// negotiating direct connections.
BlockDirect bool
ProxySessionToken string ProxySessionToken string
// AllowAllCors will set all CORs headers to '*'. // AllowAllCors will set all CORs headers to '*'.
@ -251,7 +254,7 @@ func New(ctx context.Context, opts *Options) (*Server, error) {
}, },
regResp.DERPForceWebSockets, regResp.DERPForceWebSockets,
s.DialCoordinator, s.DialCoordinator,
false, // TODO: this will be covered in a subsequent pr. opts.BlockDirect,
s.TracerProvider, s.TracerProvider,
) )
if err != nil { if err != nil {

View File

@ -615,6 +615,76 @@ func TestWorkspaceProxyWorkspaceApps(t *testing.T) {
}) })
} }
func TestWorkspaceProxyWorkspaceApps_BlockDirect(t *testing.T) {
t.Parallel()
apptest.Run(t, false, func(t *testing.T, opts *apptest.DeploymentOptions) *apptest.Deployment {
deploymentValues := coderdtest.DeploymentValues(t)
deploymentValues.DisablePathApps = clibase.Bool(opts.DisablePathApps)
deploymentValues.Dangerous.AllowPathAppSharing = clibase.Bool(opts.DangerousAllowPathAppSharing)
deploymentValues.Dangerous.AllowPathAppSiteOwnerAccess = clibase.Bool(opts.DangerousAllowPathAppSiteOwnerAccess)
deploymentValues.Experiments = []string{
"*",
}
proxyStatsCollectorFlushCh := make(chan chan<- struct{}, 1)
flushStats := func() {
proxyStatsCollectorFlushDone := make(chan struct{}, 1)
proxyStatsCollectorFlushCh <- proxyStatsCollectorFlushDone
<-proxyStatsCollectorFlushDone
}
if opts.PrimaryAppHost == "" {
opts.PrimaryAppHost = "*.primary.test.coder.com"
}
client, closer, api, user := coderdenttest.NewWithAPI(t, &coderdenttest.Options{
Options: &coderdtest.Options{
DeploymentValues: deploymentValues,
AppHostname: opts.PrimaryAppHost,
IncludeProvisionerDaemon: true,
RealIPConfig: &httpmw.RealIPConfig{
TrustedOrigins: []*net.IPNet{{
IP: net.ParseIP("127.0.0.1"),
Mask: net.CIDRMask(8, 32),
}},
TrustedHeaders: []string{
"CF-Connecting-IP",
},
},
WorkspaceAppsStatsCollectorOptions: opts.StatsCollectorOptions,
},
LicenseOptions: &coderdenttest.LicenseOptions{
Features: license.Features{
codersdk.FeatureWorkspaceProxy: 1,
},
},
})
t.Cleanup(func() {
_ = closer.Close()
})
// Create the external proxy
if opts.DisableSubdomainApps {
opts.AppHost = ""
}
proxyAPI := coderdenttest.NewWorkspaceProxyReplica(t, api, client, &coderdenttest.ProxyOptions{
Name: "best-proxy",
AppHostname: opts.AppHost,
DisablePathApps: opts.DisablePathApps,
FlushStats: proxyStatsCollectorFlushCh,
BlockDirect: true,
})
return &apptest.Deployment{
Options: opts,
SDKClient: client,
FirstUser: user,
PathAppBaseURL: proxyAPI.Options.AccessURL,
FlushStats: flushStats,
}
})
}
// createDERPClient creates a DERP client and spawns a goroutine that reads from // createDERPClient creates a DERP client and spawns a goroutine that reads from
// the client and sends the received packets to a channel. // the client and sends the received packets to a channel.
// //