mirror of
https://github.com/pomerium/pomerium.git
synced 2025-08-06 10:21:05 +02:00
rough changes for ssh to work with latest envoy-custom from main
This commit is contained in:
parent
4e6aa84ca4
commit
b5e70f7a6a
6 changed files with 40 additions and 46 deletions
|
@ -469,7 +469,7 @@ func (a *Authorize) ManageStream(
|
||||||
|
|
||||||
func (a *Authorize) getSSHRouteForHostname(hostname string) *config.Policy {
|
func (a *Authorize) getSSHRouteForHostname(hostname string) *config.Policy {
|
||||||
opts := a.currentConfig.Load().Options
|
opts := a.currentConfig.Load().Options
|
||||||
from := "ssh://" + strings.TrimSuffix(strings.Join([]string{hostname, opts.SSHHostname}, "."), ".")
|
from := "ssh://" + hostname
|
||||||
for r := range opts.GetAllPolicies() {
|
for r := range opts.GetAllPolicies() {
|
||||||
if r.From == from {
|
if r.From == from {
|
||||||
return r
|
return r
|
||||||
|
@ -1221,18 +1221,18 @@ func (a *Authorize) NewPortalCommand(
|
||||||
var routes []string
|
var routes []string
|
||||||
for r := range cfg.Options.GetAllPolicies() {
|
for r := range cfg.Options.GetAllPolicies() {
|
||||||
if strings.HasPrefix(r.From, "ssh://") {
|
if strings.HasPrefix(r.From, "ssh://") {
|
||||||
routes = append(routes, fmt.Sprintf("%s@%s", state.Username, strings.TrimSuffix(strings.TrimPrefix(r.From, "ssh://"), "."+cfg.Options.SSHHostname)))
|
routes = append(routes, fmt.Sprintf("%s@%s", state.Username, strings.TrimPrefix(r.From, "ssh://")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
items := []list.Item{}
|
items := []list.Item{}
|
||||||
for _, route := range routes {
|
for _, route := range routes {
|
||||||
items = append(items, item(route))
|
items = append(items, item(route))
|
||||||
}
|
}
|
||||||
a.activeStreams.Range(func(id uint64, _ *StreamState) {
|
// a.activeStreams.Range(func(id uint64, _ *StreamState) {
|
||||||
if id != state.StreamID {
|
// if id != state.StreamID {
|
||||||
items = append(items, item(fmt.Sprintf("[demo] mirror session: %v", id)))
|
// items = append(items, item(fmt.Sprintf("[demo] mirror session: %v", id)))
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
|
|
||||||
l := list.New(items, itemDelegate{}, int(ptyInfo.WidthColumns-2), int(ptyInfo.HeightRows-2))
|
l := list.New(items, itemDelegate{}, int(ptyInfo.WidthColumns-2), int(ptyInfo.HeightRows-2))
|
||||||
l.Title = "Connect to which server?"
|
l.Title = "Connect to which server?"
|
||||||
|
|
|
@ -5,24 +5,20 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
xds_core_v3 "github.com/cncf/xds/go/xds/core/v3"
|
xds_core_v3 "github.com/cncf/xds/go/xds/core/v3"
|
||||||
xds_matcher_v3 "github.com/cncf/xds/go/xds/type/matcher/v3"
|
xds_matcher_v3 "github.com/cncf/xds/go/xds/type/matcher/v3"
|
||||||
envoy_config_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
|
envoy_config_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
|
||||||
envoy_config_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
|
envoy_config_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
|
||||||
extensions_compressor_zstd_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/compression/zstd/compressor/v3"
|
|
||||||
envoy_generic_proxy_action_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/action/v3"
|
envoy_generic_proxy_action_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/action/v3"
|
||||||
envoy_generic_proxy_matcher_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/matcher/v3"
|
envoy_generic_proxy_matcher_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/matcher/v3"
|
||||||
envoy_generic_router_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/router/v3"
|
envoy_generic_router_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/router/v3"
|
||||||
envoy_generic_proxy_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/v3"
|
envoy_generic_proxy_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/v3"
|
||||||
matcherv3 "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3"
|
matcherv3 "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3"
|
||||||
extensions_ssh "github.com/pomerium/envoy-custom/api/extensions/filters/network/ssh"
|
extensions_ssh "github.com/pomerium/envoy-custom/api/extensions/filters/network/ssh"
|
||||||
extensions_ssh_session_recording "github.com/pomerium/envoy-custom/api/extensions/filters/network/ssh/filters/session_recording"
|
|
||||||
"github.com/pomerium/pomerium/config"
|
"github.com/pomerium/pomerium/config"
|
||||||
"google.golang.org/protobuf/types/known/durationpb"
|
"google.golang.org/protobuf/types/known/durationpb"
|
||||||
"google.golang.org/protobuf/types/known/wrapperspb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b *Builder) buildSSHListener(ctx context.Context, cfg *config.Config) (*envoy_config_listener_v3.Listener, error) {
|
func (b *Builder) buildSSHListener(ctx context.Context, cfg *config.Config) (*envoy_config_listener_v3.Listener, error) {
|
||||||
|
@ -65,29 +61,29 @@ func (b *Builder) buildSSHListener(ctx context.Context, cfg *config.Config) (*en
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
Filters: []*envoy_config_core_v3.TypedExtensionConfig{
|
Filters: []*envoy_config_core_v3.TypedExtensionConfig{
|
||||||
{
|
// {
|
||||||
Name: "envoy.filters.generic.ssh.session_recording",
|
// Name: "envoy.filters.generic.ssh.session_recording",
|
||||||
TypedConfig: marshalAny(&extensions_ssh_session_recording.Config{
|
// TypedConfig: marshalAny(&extensions_ssh_session_recording.Config{
|
||||||
StorageDir: "/tmp/recordings",
|
// StorageDir: "/tmp/recordings",
|
||||||
GrpcService: authorizeService,
|
// GrpcService: authorizeService,
|
||||||
CompressorLibrary: &envoy_config_core_v3.TypedExtensionConfig{
|
// CompressorLibrary: &envoy_config_core_v3.TypedExtensionConfig{
|
||||||
Name: "envoy.compression.zstd.compressor",
|
// Name: "envoy.compression.zstd.compressor",
|
||||||
TypedConfig: marshalAny(&extensions_compressor_zstd_v3.Zstd{
|
// TypedConfig: marshalAny(&extensions_compressor_zstd_v3.Zstd{
|
||||||
CompressionLevel: wrapperspb.UInt32(19),
|
// CompressionLevel: wrapperspb.UInt32(19),
|
||||||
EnableChecksum: false,
|
// EnableChecksum: false,
|
||||||
Strategy: extensions_compressor_zstd_v3.Zstd_BTULTRA2,
|
// Strategy: extensions_compressor_zstd_v3.Zstd_BTULTRA2,
|
||||||
ChunkSize: wrapperspb.UInt32(8192),
|
// ChunkSize: wrapperspb.UInt32(8192),
|
||||||
}),
|
// }),
|
||||||
},
|
// },
|
||||||
// FileManagerConfig: &async_filesv3.AsyncFileManagerConfig{
|
// // FileManagerConfig: &async_filesv3.AsyncFileManagerConfig{
|
||||||
// ManagerType: &async_filesv3.AsyncFileManagerConfig_ThreadPool_{
|
// // ManagerType: &async_filesv3.AsyncFileManagerConfig_ThreadPool_{
|
||||||
// ThreadPool: &async_filesv3.AsyncFileManagerConfig_ThreadPool{
|
// // ThreadPool: &async_filesv3.AsyncFileManagerConfig_ThreadPool{
|
||||||
// ThreadCount: 2,
|
// // ThreadCount: 2,
|
||||||
// },
|
// // },
|
||||||
// },
|
// // },
|
||||||
// },
|
// // },
|
||||||
}),
|
// }),
|
||||||
},
|
// },
|
||||||
// {
|
// {
|
||||||
// Name: "envoy.filters.generic.ssh.session_multiplexing",
|
// Name: "envoy.filters.generic.ssh.session_multiplexing",
|
||||||
// TypedConfig: marshalAny(&extensions_ssh_session_multiplexing.Config{}),
|
// TypedConfig: marshalAny(&extensions_ssh_session_multiplexing.Config{}),
|
||||||
|
@ -123,10 +119,6 @@ func (b *Builder) buildRouteConfig(_ context.Context, cfg *config.Config) (*envo
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fromHost := from.Hostname()
|
fromHost := from.Hostname()
|
||||||
if cfg.Options.SSHHostname != "" {
|
|
||||||
suffix := "." + cfg.Options.SSHHostname
|
|
||||||
fromHost = strings.TrimSuffix(fromHost, suffix)
|
|
||||||
}
|
|
||||||
if len(route.To) > 1 {
|
if len(route.To) > 1 {
|
||||||
return nil, fmt.Errorf("only one 'to' entry allowed for ssh routes")
|
return nil, fmt.Errorf("only one 'to' entry allowed for ssh routes")
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,7 +246,6 @@ type Options struct {
|
||||||
GRPCClientTimeout time.Duration `mapstructure:"grpc_client_timeout" yaml:"grpc_client_timeout,omitempty"`
|
GRPCClientTimeout time.Duration `mapstructure:"grpc_client_timeout" yaml:"grpc_client_timeout,omitempty"`
|
||||||
|
|
||||||
SSHAddr string `mapstructure:"ssh_address" yaml:"ssh_address,omitempty"`
|
SSHAddr string `mapstructure:"ssh_address" yaml:"ssh_address,omitempty"`
|
||||||
SSHHostname string `mapstructure:"ssh_hostname" yaml:"ssh_hostname,omitempty"`
|
|
||||||
SSHHostKeys []string `mapstructure:"ssh_host_keys" yaml:"ssh_host_keys,omitempty"`
|
SSHHostKeys []string `mapstructure:"ssh_host_keys" yaml:"ssh_host_keys,omitempty"`
|
||||||
SSHUserCAKey string `mapstructure:"ssh_user_ca_key" yaml:"ssh_user_ca_key,omitempty"`
|
SSHUserCAKey string `mapstructure:"ssh_user_ca_key" yaml:"ssh_user_ca_key,omitempty"`
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/ed25519"
|
"crypto/ed25519"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -20,6 +21,7 @@ import (
|
||||||
"github.com/pomerium/pomerium/internal/testenv/scenarios"
|
"github.com/pomerium/pomerium/internal/testenv/scenarios"
|
||||||
"github.com/pomerium/pomerium/internal/testenv/snippets"
|
"github.com/pomerium/pomerium/internal/testenv/snippets"
|
||||||
"github.com/pomerium/pomerium/internal/testenv/upstreams"
|
"github.com/pomerium/pomerium/internal/testenv/upstreams"
|
||||||
|
"github.com/pomerium/pomerium/internal/testenv/values"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSSH(t *testing.T) {
|
func TestSSH(t *testing.T) {
|
||||||
|
@ -65,7 +67,9 @@ func TestSSH(t *testing.T) {
|
||||||
)
|
)
|
||||||
up.SetServerConnCallback(echoShell{t}.handleConnection)
|
up.SetServerConnCallback(echoShell{t}.handleConnection)
|
||||||
r := up.Route().
|
r := up.Route().
|
||||||
From(env.SubdomainURLWithScheme("example", "ssh")).
|
From(values.Bind(env.Ports().ProxySSH, func(port int) string {
|
||||||
|
return fmt.Sprintf("ssh://example:%d", port)
|
||||||
|
})).
|
||||||
Policy(func(p *config.Policy) { p.AllowAnyAuthenticatedUser = true })
|
Policy(func(p *config.Policy) { p.AllowAnyAuthenticatedUser = true })
|
||||||
env.AddUpstream(up)
|
env.AddUpstream(up)
|
||||||
env.Start()
|
env.Start()
|
||||||
|
@ -121,7 +125,9 @@ func TestSSH_JumpHostMode(t *testing.T) {
|
||||||
)
|
)
|
||||||
up.SetServerConnCallback(echoShell{t}.handleConnection)
|
up.SetServerConnCallback(echoShell{t}.handleConnection)
|
||||||
r := up.Route().
|
r := up.Route().
|
||||||
From(env.SubdomainURLWithScheme("example", "ssh")).
|
From(values.Bind(env.Ports().ProxySSH, func(port int) string {
|
||||||
|
return fmt.Sprintf("ssh://example:%d", port)
|
||||||
|
})).
|
||||||
Policy(func(p *config.Policy) { p.AllowAnyAuthenticatedUser = true })
|
Policy(func(p *config.Policy) { p.AllowAnyAuthenticatedUser = true })
|
||||||
env.AddUpstream(up)
|
env.AddUpstream(up)
|
||||||
env.Start()
|
env.Start()
|
||||||
|
|
|
@ -635,7 +635,6 @@ func (e *environment) Start() {
|
||||||
cfg.Options.GRPCAddr = fmt.Sprintf("%s:%d", e.host, e.ports.ProxyGRPC.Value())
|
cfg.Options.GRPCAddr = fmt.Sprintf("%s:%d", e.host, e.ports.ProxyGRPC.Value())
|
||||||
cfg.Options.SSHAddr = fmt.Sprintf("%s:%d", e.host, e.ports.ProxySSH.Value())
|
cfg.Options.SSHAddr = fmt.Sprintf("%s:%d", e.host, e.ports.ProxySSH.Value())
|
||||||
cfg.Options.EnvoyAdminAddress = fmt.Sprintf("%s:%d", e.host, e.ports.EnvoyAdmin.Value())
|
cfg.Options.EnvoyAdminAddress = fmt.Sprintf("%s:%d", e.host, e.ports.EnvoyAdmin.Value())
|
||||||
cfg.Options.SSHHostname = localDomainName
|
|
||||||
cfg.Options.MetricsAddr = fmt.Sprintf("%s:%d", e.host, e.ports.ProxyMetrics.Value())
|
cfg.Options.MetricsAddr = fmt.Sprintf("%s:%d", e.host, e.ports.ProxyMetrics.Value())
|
||||||
cfg.Options.CAFile = filepath.Join(e.tempDir, "certs", "ca.pem")
|
cfg.Options.CAFile = filepath.Join(e.tempDir, "certs", "ca.pem")
|
||||||
cfg.Options.CertFile = filepath.Join(e.tempDir, "certs", "trusted.pem")
|
cfg.Options.CertFile = filepath.Join(e.tempDir, "certs", "trusted.pem")
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/internal/testenv"
|
"github.com/pomerium/pomerium/internal/testenv"
|
||||||
"github.com/pomerium/pomerium/internal/testenv/values"
|
"github.com/pomerium/pomerium/internal/testenv/values"
|
||||||
|
@ -109,7 +108,7 @@ type sshUpstream struct {
|
||||||
serverPort values.MutableValue[int]
|
serverPort values.MutableValue[int]
|
||||||
|
|
||||||
// XXX: does it make sense to cache clients?
|
// XXX: does it make sense to cache clients?
|
||||||
//clientCache sync.Map // map[testenv.Route]*ssh.Client
|
// clientCache sync.Map // map[testenv.Route]*ssh.Client
|
||||||
|
|
||||||
serverConnCallback ServerConnCallback
|
serverConnCallback ServerConnCallback
|
||||||
}
|
}
|
||||||
|
@ -202,8 +201,7 @@ func (h *sshUpstream) handleConnection(ctx context.Context, conn net.Conn) {
|
||||||
|
|
||||||
// Dial implements SSHUpstream.
|
// Dial implements SSHUpstream.
|
||||||
func (h *sshUpstream) Dial(r testenv.Route, config *ssh.ClientConfig) (*ssh.Client, error) {
|
func (h *sshUpstream) Dial(r testenv.Route, config *ssh.ClientConfig) (*ssh.Client, error) {
|
||||||
return ssh.Dial("tcp", strings.TrimPrefix(r.URL().Value(), "ssh://"), config)
|
return ssh.Dial("tcp", h.Env().Config().Options.SSHAddr, config)
|
||||||
//return ssh.Dial("tcp", h.Env().Config().Options.SSHAddr, config)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DirectDial implements SSHUpstream.
|
// DirectDial implements SSHUpstream.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue