
# SFTP

The SFTP integration allows Plakar Control Plane to back up and restore files on
any remote machine reachable over SSH. Plakar connects to the remote machine
over SSH and reads or writes files directly under the configured root path using
SFTP.

## Running SFTP tasks on an edge

The SFTP integration connects through the OpenSSH `ssh` client, and loads
private keys with `ssh-add` into the SSH agent of the edge. The official edge
image includes the OpenSSH client. When the task runs on a binary edge or on a
[custom edge image](../../edges/installation/custom-image), install the OpenSSH
client on it, for example with the `openssh-client` package on Debian and
Ubuntu. See [SSH client](../../edges/requirements#ssh-client).

## Inventory Management

Currently no [managed inventory](../../inventories#managed-inventories) has the
capability of discovering SFTP resources. You need to set up a
[self-managed inventory](../../inventories/self-managed) before adding an SFTP
resource.

### Adding SFTP as a resource

When using a self-managed inventory, you must register your resources manually
or import them from a CSV file.

To add an SFTP machine as a resource, use **Services** as the `class` and
**Sftp** as the `subclass`. For the endpoint, use the IP address or hostname of
the target machine. See [resources documentation](../../resources) for more
information on how to set up resources on a self-managed inventory.

#### Backup flow

<!-- prettier-ignore-start -->
{{< mermaid >}}
flowchart TD
  subgraph Remote["Remote Machine"]
    Files["Filesystem<br/>Root path"]
  end

  subgraph Plakar["Plakar Control Plane"]
    Source["SFTP<br/>Source app"]
    Backup["Backup process<br/>Encrypt & deduplicate"]
  end

  Store["Kloset Store"]

  Source -->|"SSH/SFTP connection"| Files
  Files -->|"read files"| Backup
  Backup --> Store
{{< /mermaid >}}
<!-- prettier-ignore-end -->

#### Restore flow

<!-- prettier-ignore-start -->
{{< mermaid >}}
flowchart TD
  Store["Kloset Store"]

  subgraph Plakar["Plakar Control Plane"]
    Destination["SFTP<br/>Destination app"]
    Restore["Restore process"]
  end

  subgraph Remote["Remote Machine"]
    Files["Filesystem<br/>Root path"]
  end

  Store --> Restore
  Destination --> Restore
  Restore -->|"SSH/SFTP connection"| Files
{{< /mermaid >}}
<!-- prettier-ignore-end -->

#### Store flow

<!-- prettier-ignore-start -->
{{< mermaid >}}
flowchart TD
  Source["Source data"]

  subgraph Plakar["Plakar Control Plane"]
    Backup["Backup process<br/>Encrypt & deduplicate"]
    StoreApp["SFTP<br/>Store app"]
  end

  subgraph Remote["Remote Machine"]
    Kloset["Kloset Store<br/>Root path"]
  end

  Source --> Backup
  Backup --> StoreApp
  StoreApp -->|"SSH/SFTP connection"| Kloset
{{< /mermaid >}}
<!-- prettier-ignore-end -->

## Shared configuration

The following settings are available when configuring a source, store, or
destination app.

- **Host Key**: The SSH host public key entry of the remote machine, used to
  verify its identity before connecting, for example
  `example.com ssh-rsa AAAAB3NzaC1yc2E...`. You can get the entry by running
  `ssh-keyscan <host>` from a trusted network, and check its fingerprint against
  the remote machine before using it.
- **Port**: The TCP/UDP port number the SSH service is listening on. Defaults to
  `22`.
- **Root**: The absolute filesystem path to use as the root for backup
  operations. Defaults to `/`.
- **Ssh Private Key**: SSH private key material (PEM/OpenSSH) to load into
  `ssh-agent` via `ssh-add` (not supported on Windows). Generate a dedicated SSH
  keypair for PCP and add the public key to the remote machine's authorized keys
  before configuring this field, then copy the private key in full, including
  the header and footer lines, into this field:

  ```txt
  -----BEGIN OPENSSH PRIVATE KEY-----
  ...
  -----END OPENSSH PRIVATE KEY-----
  ```

- **Username**: The SFTP username to authenticate as on the remote machine. This
  field cannot be used if the hostname already includes a `user@host` format.

## Store configuration

The following extra settings are available when configuring a store app.

- **Kloset Passphrase**: The passphrase Plakar Control Plane uses to encrypt the
  store. This passphrase is required to access the store and must be kept safe.

## Store requirements

Writing to a Kloset store requires the remote machine to support the
`posix-rename@openssh.com` SFTP extension, which OpenSSH provides. Plakar checks
for it on the first write to the store and fails with an error if it is missing.

Reading from a store does not need the extension. A store on an OpenSSH server
running in read-only mode (`sftp-server -R`), which does not advertise it, can
be used as the source of a sync or browsed in the UI.

## Destination configuration

The following extra settings are available when configuring a destination app.

- **Set Owner**: Sets the owner and group of restored files to match the
  original snapshot. Requires the SSH user configured for PCP to have superuser
  permissions on the remote machine.
- **Skip Permissions**: Skips restoring permission bits, including the setuid,
  setgid and sticky bits, on restored files and directories. Disabled by
  default.

## Restore behaviour

Restored files and directories receive their final permissions when they are
created, so restored content is never readable by more users than the snapshot
allows, even while the restore is running. Directories keep owner read, write
and execute permissions until the restore finishes, so that a read-only
directory can still be populated, and then receive their final mode.

Symbolic links are restored only if their target resolves inside the
destination's root path. Relative targets are resolved from the link's location,
and absolute targets are compared as paths on the remote machine. A link whose
target falls outside the root path, such as `../../etc/passwd` or
`/usr/bin/python3` restored under `/srv/restore`, is reported as failed and is
not created.

## Permissions

The SSH user configured for PCP must have read access to the paths being backed
up. For destination use, write access is also required. A store needs write
access to receive backups, but can be read from with read access only. See
[Store requirements](#store-requirements). It is recommended to create a
dedicated user and keypair for Plakar Control Plane rather than reusing personal
credentials.

