72 lines
2.6 KiB
Markdown
72 lines
2.6 KiB
Markdown
# SSH/SFTP Integration
|
|
|
|
Audience: operators and maintainers configuring SSH/SFTP sources or destinations.
|
|
|
|
The SSH backend uses native SSH and SFTP libraries. It does not call `ssh`, `scp`, or `rsync`.
|
|
|
|
## Dependencies
|
|
|
|
Runtime SSH support uses:
|
|
|
|
- `golang.org/x/crypto/ssh`
|
|
- `golang.org/x/crypto/ssh/agent`
|
|
- `golang.org/x/crypto/ssh/knownhosts`
|
|
- `github.com/pkg/sftp`
|
|
|
|
Exact versions are pinned in `go.mod`.
|
|
|
|
## Config Contract
|
|
|
|
Required fields:
|
|
|
|
- `backend: ssh`
|
|
- `host`
|
|
- `path`
|
|
|
|
Optional fields:
|
|
|
|
- `user`: defaults to the current OS user when available.
|
|
- `port`: defaults to `22`.
|
|
- `ssh_key_file`: private key path.
|
|
- `known_hosts`: OpenSSH known-hosts file path.
|
|
- `host_key_policy`: `strict`, `accept-new`, or `off`; defaults to `accept-new`.
|
|
|
|
## Authentication
|
|
|
|
Authentication methods are attempted in this order:
|
|
|
|
1. SSH agent identities when `SSH_AUTH_SOCK` is set.
|
|
2. The private key configured by `ssh_key_file`.
|
|
|
|
Password authentication is not configured in YAML. If neither an agent nor key file is available, opening the backend fails.
|
|
|
|
## Host Key Policy
|
|
|
|
- `strict`: requires a matching known host key.
|
|
- `accept-new`: accepts and persists an unknown host key, but rejects changed known keys.
|
|
- `off`: disables host key checking.
|
|
|
|
When `known_hosts` is omitted and checking is enabled, the adapter uses the current user's default OpenSSH `known_hosts` path when available. During dry runs, accepted unknown host keys are not persisted.
|
|
|
|
## Storage Behavior
|
|
|
|
The configured `path` is the backend root. All source discovery, destination paths, reads, writes, state files, and deletes operate on logical paths below that root.
|
|
|
|
The adapter rejects symlink ancestors for reads and writes. Reads require regular files. Writes create parent directories and prefer atomic temp-file-plus-rename writes when requested. Walk output is sorted through the shared storage walker.
|
|
|
|
Managed cleanup and normal replacement delete only managed output paths plus `.distributor.json`. Same-source merge publication retains omitted managed paths and may overwrite existing managed paths. Takeover replacement does not retain omitted outputs through merge reconciliation. Forced replacement deletes the bounded destination bundle path.
|
|
|
|
## Boundaries
|
|
|
|
The SSH backend does not configure passwords, jump hosts, shell commands, `rsync`, host-key bypass warnings beyond command output, or broad recursive deletion outside the destination bundle path.
|
|
|
|
## Tests
|
|
|
|
Before changing this integration, inspect and run:
|
|
|
|
```sh
|
|
go test ./internal/adapters/ssh
|
|
```
|
|
|
|
Live SSH tests are opt-in and gated by environment variables in the adapter test package.
|