Add accept_any_key option to accept any SSH key and pass fingerprint

New YAML config option: accept_any_key: true
- Accepts any public key without verification against authorized_keys
- Still passes the client's key fingerprint in the upstream username
- Format: fp:FINGERPRINT.originaluser
- Useful for proxying to apps that identify users by SSH key fingerprint
This commit is contained in:
Russell Ballestrini 2025-12-21 09:05:05 -05:00
parent 065a7c359e
commit 56577b727e
3 changed files with 21 additions and 1 deletions

View file

@ -52,6 +52,15 @@ type SkelPipeFromPublicKey interface {
TrustedUserCAKeys(conn libplugin.ConnMetadata) ([]byte, error)
}
// SkelPipeFromPublicKeyAcceptAny is an optional interface that allows accepting any public key
// without verification. When AcceptAnyKey() returns true, the key is accepted without checking
// against authorized_keys. The client's key fingerprint is still passed to the upstream.
type SkelPipeFromPublicKeyAcceptAny interface {
SkelPipeFromPublicKey
AcceptAnyKey() bool
}
type SkelPipeTo interface {
Host(conn libplugin.ConnMetadata) string
User(conn libplugin.ConnMetadata) string
@ -210,6 +219,12 @@ func (p *SkelPlugin) PublicKeyCallback(conn libplugin.ConnMetadata, publicKey []
return false, nil
}
// Check if this pipe accepts any key without verification
if acceptAny, ok := from.(SkelPipeFromPublicKeyAcceptAny); ok && acceptAny.AcceptAnyKey() {
log.Debugf("accepting any public key for user %s (accept_any_key: true)", conn.User())
return true, nil
}
verified := false
if isCert {

View file

@ -172,6 +172,10 @@ func (s *skelpipePublicKeyWrapper) TrustedUserCAKeys(conn libplugin.ConnMetadata
})
}
func (s *skelpipePublicKeyWrapper) AcceptAnyKey() bool {
return s.from.AcceptAnyKey
}
func (s *skelpipeToPrivateKeyWrapper) PrivateKey(conn libplugin.ConnMetadata) ([]byte, []byte, error) {
p, err := s.config.loadFileOrDecode(s.to.PrivateKey, s.to.PrivateKeyData, map[string]string{
"DOWNSTREAM_USER": conn.User(),

View file

@ -21,10 +21,11 @@ type yamlPipeFrom struct {
AuthorizedKeysData listOrString `yaml:"authorized_keys_data,omitempty"`
TrustedUserCAKeys listOrString `yaml:"trusted_user_ca_keys,omitempty"`
TrustedUserCAKeysData listOrString `yaml:"trusted_user_ca_keys_data,omitempty"`
AcceptAnyKey bool `yaml:"accept_any_key,omitempty"`
}
func (f yamlPipeFrom) SupportPublicKey() bool {
return f.AuthorizedKeys.Any() || f.AuthorizedKeysData.Any() || f.TrustedUserCAKeys.Any() || f.TrustedUserCAKeysData.Any()
return f.AcceptAnyKey || f.AuthorizedKeys.Any() || f.AuthorizedKeysData.Any() || f.TrustedUserCAKeys.Any() || f.TrustedUserCAKeysData.Any()
}
type yamlPipeTo struct {