Documentation
¶
Overview ¶
package deploy provides functionality for connecting to remote hosts via SSH and managing their authorized_keys files. This file contains the Unix-specific implementation for locating the SSH agent.
Package deploy provides functionality for decommissioning accounts by removing their authorized_keys files before deleting from the database.
package deploy provides functionality for connecting to remote hosts via SSH and managing their authorized_keys files. This file contains the logic for generating the content of an authorized_keys file from database records.
package deploy provides functionality for connecting to remote hosts via SSH and managing their authorized_keys files. This file contains the logic for importing public keys from a remote host's authorized_keys file into the Keymaster database.
Package deploy provides functionality for connecting to remote hosts via SSH and managing their authorized_keys files. This file contains the core SSH and SFTP client logic for connecting, authenticating, and transferring files.
It includes configurable timeout support and enhanced error classification to provide better user feedback when connections fail.
Index ¶
- Constants
- Variables
- func AuditAccountSerial(account model.Account) error
- func AuditAccountStrict(account model.Account) error
- func CanonicalizeHostPort(input string) string
- func ClassifyConnectionError(host string, err error) error
- func GenerateKeysContent(accountID int) (string, error)
- func GenerateKeysContentForSerial(accountID int, serial int) (string, error)
- func GenerateSelectiveKeysContent(accountID int, serial int, excludeKeyIDs []int, removeSystemKey bool) (string, error)
- func GetRemoteHostKey(host string) (ssh.PublicKey, error)
- func GetRemoteHostKeyWithTimeout(host string, timeout time.Duration) (ssh.PublicKey, error)
- func ImportRemoteKeys(account model.Account) (importedKeys []model.PublicKey, skippedCount int, warning string, err error)
- func IsAuthenticationError(err error) bool
- func IsConnectionRefusedError(err error) bool
- func IsConnectionTimeoutError(err error) bool
- func IsHostKeyError(err error) bool
- func JoinHostPort(host, port, defaultPort string) string
- func ParseHostPort(addr string) (host string, port string, err error)
- func RunDeploymentForAccount(account model.Account, isTUI bool) error
- func StripIPv6Brackets(host string) string
- type ConnectionConfig
- type DecommissionOptions
- type DecommissionResult
- type Deployer
- func NewBootstrapDeployer(host, user, privateKey string) (*Deployer, error)
- func NewBootstrapDeployerWithExpectedKey(host, user, privateKey, expectedHostKey string) (*Deployer, error)
- func NewDeployer(host, user, privateKey string, passphrase []byte) (*Deployer, error)
- func NewDeployerWithConfig(host, user, privateKey string, passphrase []byte, config *ConnectionConfig, ...) (*Deployer, error)
Constants ¶
const ( // DefaultConnectionTimeout is the default timeout for establishing SSH connections DefaultConnectionTimeout = 10 * time.Second // DefaultCommandTimeout is the default timeout for executing commands DefaultCommandTimeout = 30 * time.Second // DefaultHostKeyTimeout is the default timeout for host key retrieval DefaultHostKeyTimeout = 5 * time.Second // DefaultSFTPTimeout is the default timeout for SFTP operations DefaultSFTPTimeout = 60 * time.Second )
Default timeout values for SSH operations
const SystemKeyRestrictions = `command="internal-sftp",no-port-forwarding,no-x11-forwarding,no-agent-forwarding,no-pty`
SystemKeyRestrictions defines the SSH options applied to the Keymaster system key. These restrictions limit the key to only allow SFTP access for file management, enhancing security by preventing shell access, port forwarding, etc.
Variables ¶
var ErrHostKeySuccessfullyRetrieved = errors.New("keymaster: successfully retrieved host key")
ErrHostKeySuccessfullyRetrieved is a sentinel error used to gracefully stop the SSH handshake in GetRemoteHostKey once the host key has been captured.
var ErrPassphraseRequired = errors.New("passphrase required for encrypted system key")
ErrPassphraseRequired is a sentinel error returned when an encrypted key is encountered but no passphrase was provided, signaling that the caller should prompt for one.
Functions ¶
func AuditAccountSerial ¶ added in v1.4.0
AuditAccountSerial performs a lightweight audit by checking only the Keymaster header serial number on the remote host against the account's last deployed serial recorded in the database.
func AuditAccountStrict ¶ added in v1.4.0
AuditAccountStrict performs a strict audit by comparing the full normalized remote authorized_keys file with the expected desired state.
func CanonicalizeHostPort ¶ added in v1.4.0
CanonicalizeHostPort returns host:port form using default 22 if missing.
func ClassifyConnectionError ¶ added in v1.4.0
ClassifyConnectionError provides a more descriptive error message based on the error type
func GenerateKeysContent ¶
GenerateKeysContent constructs the authorized_keys file content for a given account. It defaults to using the currently active system key.
func GenerateKeysContentForSerial ¶ added in v1.4.0
GenerateKeysContentForSerial constructs the authorized_keys file content for a given account using a specific system key serial.
func GenerateSelectiveKeysContent ¶ added in v1.4.0
func GenerateSelectiveKeysContent(accountID int, serial int, excludeKeyIDs []int, removeSystemKey bool) (string, error)
GenerateSelectiveKeysContent constructs authorized_keys content excluding specific keys. The system key is always included unless removeSystemKey is true.
func GetRemoteHostKey ¶
GetRemoteHostKey connects to a host just to retrieve its public key.
func GetRemoteHostKeyWithTimeout ¶ added in v1.4.0
GetRemoteHostKeyWithTimeout connects to a host with a custom timeout to retrieve its public key.
func ImportRemoteKeys ¶
func ImportRemoteKeys(account model.Account) (importedKeys []model.PublicKey, skippedCount int, warning string, err error)
ImportRemoteKeys connects to a host, reads its authorized_keys, imports new keys into the database, and returns the newly imported keys.
func IsAuthenticationError ¶ added in v1.4.0
IsAuthenticationError checks if the error is due to authentication failure
func IsConnectionRefusedError ¶ added in v1.4.0
IsConnectionRefusedError checks if the error is due to connection being refused
func IsConnectionTimeoutError ¶ added in v1.4.0
IsConnectionTimeoutError checks if the error is due to a connection timeout
func IsHostKeyError ¶ added in v1.4.0
IsHostKeyError checks if the error is due to host key verification failure
func JoinHostPort ¶ added in v1.4.0
JoinHostPort joins host and port into a canonical host:port. - If port is empty, defaultPort is used. - IPv6 hosts will be bracketed.
func ParseHostPort ¶ added in v1.4.0
ParseHostPort splits an address into host and port. Behavior: - Accepts host, host:port, [ipv6], [ipv6]:port, ipv6, ipv6:port - Returns port "" if not specified - Returns host without IPv6 brackets
func RunDeploymentForAccount ¶ added in v1.4.0
RunDeploymentForAccount handles the deployment logic for a single account. It determines the correct system key to use for connection (either the active key for bootstrapping or the account's last known key), generates the authorized_keys content, deploys it, and updates the account's key serial in the database upon success. The isTUI flag controls which i18n keys are used.
func StripIPv6Brackets ¶ added in v1.4.0
CanonicalizeHostPort returns a normalized host:port string. - If no port is provided, :22 is assumed. - IPv6 literals will be bracketed as needed (e.g., [2001:db8::1]:22). - If input is of the form user@host, the user part is discarded. StripIPv6Brackets removes surrounding [ ] from an IPv6 literal if present.
Types ¶
type ConnectionConfig ¶ added in v1.4.0
type ConnectionConfig struct {
ConnectionTimeout time.Duration
CommandTimeout time.Duration
SFTPTimeout time.Duration
}
ConnectionConfig holds timeout configuration for SSH connections
func DefaultConnectionConfig ¶ added in v1.4.0
func DefaultConnectionConfig() *ConnectionConfig
DefaultConnectionConfig returns a ConnectionConfig with default timeout values
type DecommissionOptions ¶ added in v1.4.0
type DecommissionOptions struct {
// SkipRemoteCleanup bypasses SSH connection and authorized_keys removal
SkipRemoteCleanup bool
// KeepFile removes only Keymaster-managed content, leaves other keys intact
KeepFile bool
// Force continues decommission even if remote cleanup fails
Force bool
// DryRun shows what would be done without making changes
DryRun bool
// SelectiveKeys specifies which keys to remove (by ID). If empty, removes all Keymaster-managed keys
SelectiveKeys []int
// RemoveSystemKeyOnly removes only the system key, preserving all user keys
RemoveSystemKeyOnly bool
}
DecommissionOptions configures how accounts are decommissioned
type DecommissionResult ¶ added in v1.4.0
type DecommissionResult struct {
AccountID int
AccountString string
RemoteCleanupDone bool
RemoteCleanupError error
DatabaseDeleteDone bool
DatabaseDeleteError error
BackupPath string
Skipped bool
SkipReason string
}
DecommissionResult contains the outcome of a decommission operation
func BulkDecommissionAccounts ¶ added in v1.4.0
func BulkDecommissionAccounts(accounts []model.Account, systemKey string, options DecommissionOptions) []DecommissionResult
BulkDecommissionAccounts decommissions multiple accounts with progress reporting
func DecommissionAccount ¶ added in v1.4.0
func DecommissionAccount(account model.Account, systemKey string, options DecommissionOptions) DecommissionResult
DecommissionAccount removes SSH access for an account and deletes it from the database. It first attempts to clean up the remote authorized_keys file, then removes the account from the database. The operation can be configured with DecommissionOptions.
func (DecommissionResult) String ¶ added in v1.4.0
func (r DecommissionResult) String() string
String returns a human-readable summary of the decommission result
type Deployer ¶
type Deployer struct {
// contains filtered or unexported fields
}
Deployer handles the connection and deployment to a remote host.
func NewBootstrapDeployer ¶ added in v1.4.0
NewBootstrapDeployer creates a new SSH connection for bootstrap operations. It accepts any host key and saves it to the database for future connections.
func NewBootstrapDeployerWithExpectedKey ¶ added in v1.4.0
func NewBootstrapDeployerWithExpectedKey(host, user, privateKey, expectedHostKey string) (*Deployer, error)
NewBootstrapDeployerWithExpectedKey creates a new SSH connection for bootstrap operations that only accepts the specific expected host key. This is used when the host key has been manually verified by the user.
func NewDeployer ¶
NewDeployer creates a new SSH connection and returns a Deployer. For bootstrap connections, use NewBootstrapDeployer instead.
func NewDeployerWithConfig ¶ added in v1.4.0
func NewDeployerWithConfig(host, user, privateKey string, passphrase []byte, config *ConnectionConfig, isBootstrap bool) (*Deployer, error)
NewDeployerWithConfig creates a new SSH connection with custom timeout configuration.
func (*Deployer) Close ¶
func (d *Deployer) Close()
Close closes the underlying SSH and SFTP clients.
func (*Deployer) DeployAuthorizedKeys ¶
DeployAuthorizedKeys uploads the new authorized_keys content and moves it into place. This function uses a pure-SFTP method to be compatible with restricted keys (e.g., command="internal-sftp"). It uses a backup-and-rename strategy for compatibility with SFTP servers that don't support atomic overwrites (e.g., on Windows).
func (*Deployer) GetAuthorizedKeys ¶
GetAuthorizedKeys reads and returns the content of the remote authorized_keys file.