Skip to content

Commit

Permalink
[v10] Make source IP-pinning and proxy peering enterprise features (#…
Browse files Browse the repository at this point in the history
…14153)

* Make source IP-pinning an enterprise feature
* Make proxy peering an enterprise only feature (#14155)
  • Loading branch information
zmb3 authored Jul 7, 2022
1 parent 6396413 commit 9e3912e
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 5 deletions.
2 changes: 1 addition & 1 deletion docs/pages/includes/role-spec.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ spec:
# if unspecified. If one or more of the user's roles has disabled
# the clipboard, then it will be disabled.
desktop_clipboard: true
# When enabled, the source IP that was used to log in is embedded in the SSH
# enterprise-only: when enabled, the source IP that was used to log in is embedded in the SSH
# certificate, preventing a compromised certificate from being used on other
# devices. The default is false.
pin_source_ip: true
Expand Down
3 changes: 3 additions & 0 deletions integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import (
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/events"
"github.com/gravitational/teleport/lib/events/filesessions"
"github.com/gravitational/teleport/lib/modules"
"github.com/gravitational/teleport/lib/pam"
"github.com/gravitational/teleport/lib/reversetunnel"
"github.com/gravitational/teleport/lib/service"
Expand Down Expand Up @@ -213,6 +214,8 @@ func TestIntegrations(t *testing.T) {

// testDifferentPinnedIP tests connection is rejected when source IP doesn't match the pinned one
func testDifferentPinnedIP(t *testing.T, suite *integrationTestSuite) {
modules.SetTestModules(t, &modules.TestModules{TestBuildType: modules.BuildEnterprise})

tr := utils.NewTracer(utils.ThisFunction()).Start()
defer tr.Stop()

Expand Down
6 changes: 6 additions & 0 deletions integration/proxy_tunnel_strategy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/gravitational/teleport/lib/auth"
"github.com/gravitational/teleport/lib/auth/testauthority"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/modules"
"github.com/gravitational/teleport/lib/service"
"github.com/gravitational/teleport/lib/srv/db/common"
"github.com/gravitational/teleport/lib/srv/db/postgres"
Expand Down Expand Up @@ -120,6 +121,11 @@ func TestProxyTunnelStrategyAgentMesh(t *testing.T) {

// TestProxyTunnelStrategyProxyPeering tests the proxy-peer tunnel strategy
func TestProxyTunnelStrategyProxyPeering(t *testing.T) {
modules.SetTestModules(t, &modules.TestModules{
TestBuildType: modules.BuildEnterprise,
TestFeatures: modules.Features{DB: true},
})

p := newProxyTunnelStrategy(t, "proxy-tunnel-proxy-peer",
&types.TunnelStrategyV1{
Strategy: &types.TunnelStrategyV1_ProxyPeering{
Expand Down
9 changes: 9 additions & 0 deletions lib/auth/auth_with_roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -3232,6 +3232,15 @@ func (a *ServerWithRoles) SetClusterNetworkingConfig(ctx context.Context, newNet
}
}

tst, err := newNetConfig.GetTunnelStrategyType()
if err != nil {
return trace.Wrap(err)
}
if tst == types.ProxyPeering &&
modules.GetModules().BuildType() != modules.BuildEnterprise {
return trace.AccessDenied("proxy peering is an enterprise-only feature")
}

return a.authServer.SetClusterNetworkingConfig(ctx, newNetConfig)
}

Expand Down
6 changes: 5 additions & 1 deletion lib/auth/native/native.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/types/wrappers"
apiutils "github.com/gravitational/teleport/api/utils"
"github.com/gravitational/teleport/lib/modules"
"github.com/gravitational/teleport/lib/services"
"github.com/gravitational/teleport/lib/utils"

Expand Down Expand Up @@ -228,7 +229,7 @@ func (k *Keygen) GenerateUserCert(c services.UserCertParams) ([]byte, error) {
const sourceAddress = "source-address"

// GenerateUserCertWithoutValidation generates a user certificate with the
// passed in parameters without validating them. For use in tests only.
// passed in parameters without validating them.
func (k *Keygen) GenerateUserCertWithoutValidation(c services.UserCertParams) ([]byte, error) {
pubKey, _, _, _, err := ssh.ParseAuthorizedKey(c.PublicUserKey)
if err != nil {
Expand Down Expand Up @@ -284,6 +285,9 @@ func (k *Keygen) GenerateUserCertWithoutValidation(c services.UserCertParams) ([
}

if c.SourceIP != "" {
if modules.GetModules().BuildType() != modules.BuildEnterprise {
return nil, trace.AccessDenied("source IP pinning is only supported in Teleport Enterprise")
}
if cert.CriticalOptions == nil {
cert.CriticalOptions = make(map[string]string)
}
Expand Down
5 changes: 5 additions & 0 deletions lib/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -3025,6 +3025,11 @@ func (process *TeleportProcess) setupProxyListeners(networkingConfig types.Clust
tunnelStrategy = types.AgentMesh
}

if tunnelStrategy == types.ProxyPeering &&
modules.GetModules().BuildType() != modules.BuildEnterprise {
return nil, trace.AccessDenied("proxy peering is an enterprise-only feature")
}

if !cfg.Proxy.DisableReverseTunnel && tunnelStrategy == types.ProxyPeering {
addr, err := peerAddr(&process.Config.Proxy.PeerAddr)
if err != nil {
Expand Down
7 changes: 4 additions & 3 deletions rfd/0066-ip-based-validation.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
authors: Przemko Robakowski([email protected])
state: draft
state: implemented (Teleport 10.0.0)
---

# RFD 66 - IP-based validation
Expand All @@ -12,8 +12,9 @@ state: draft

## What

Additional validation based on client IP for creating and using certificates. Certificate can be used only with the same
client IP as the one used to generate it.
IP-based validation is an enterprise-only feature that embeds the source IP
in SSH certificates. When enabled, SSH certificates can only be used to connect
to resources from the same source IP that was issued the certificate.

## Why

Expand Down

0 comments on commit 9e3912e

Please sign in to comment.